把图像增强能力交给 Agent:LibLLIE Skill 的设计复盘
LibLLIE 是一个统一的低照度图像增强工具包。它既有传统算法和深度学习模型,也覆盖训练、推理、图像读写与质量评估。接口越完整,Agent 面临的选择反而越多:该读哪部分文档、哪些参数不能猜、什么时候可以执行、什么时候必须停下来问人?
我为它写 libllie-cli Skill 时,真正要解决的不是“让 Agent 知道更多命令”,而是让 Agent 在足够少的上下文里做出正确动作。
先把 Skill 当作路由器
整个 Skill 没有把模型、算法、指标和配置文档全部复制到一个文件里,而是分成三层:
用户意图
└─ SKILL.md:识别任务、检查前置条件、决定是否继续
├─ references/inference.md → 按需索引 CLI 文档
├─ references/training.md → 训练 API 文档 + 脚本模板
└─ references/validation.md → 指标规则 + 验证脚本模板SKILL.md 只保留所有任务都需要的规则,再把推理、训练、验证分别路由到对应 reference。reference 也不是第二份完整手册,而是指向项目文档的索引。
这个结构的价值是渐进式披露:一次普通图片增强,不需要把训练配置、数据集布局和十几种指标全部塞进上下文;只有选定模型后,才继续读取对应模型文档。
不允许 Agent “合理猜测”
图像增强任务里,很多错误看起来都很合理:拿模型名直接推理、替用户编一个 checkpoint 路径、默认一个数据集目录,或者在没有参考图时计算 PSNR。
因此我在入口层明确列出没有默认值的参数:
- 推理必须有
target和source;深度学习推理要有真实存在的.pt或.pthcheckpoint。 - 训练至少需要配置文件,或者能够确定
model与root_dir的覆盖参数。 - 验证必须有增强图目录;PSNR、SSIM、LPIPS 等全参考指标还必须有参考图目录。
这里的设计重点不是“多问问题”,而是只询问文档没有默认值、工具也无法自行确认的事实。能从配置中读到的值先读配置,能由 LibLLIE 校验的数据集布局交给 LibLLIE 校验。
环境注册与 Skill 本体解耦
Skill 不扫描机器上的 Conda、uv 或虚拟环境,也不在运行时猜 Python。安装阶段会把两个值写入独立环境文件:
LIBLLIE_ROOT=/path/to/LibLLIE
LIBLLIE_PYTHON=/path/to/python运行时只读取这份契约:LIBLLIE_ROOT 用于定位文档、reference 和模板,LIBLLIE_PYTHON 用于执行命令。
这有两个好处。第一,Agent 的行为可复现,不会因为终端当前激活了另一个环境而漂移;第二,重新链接 Skill 时可以保留用户已有配置,不必每次重新探测环境。
昂贵动作默认停在执行之前
训练和批量评估可能占用 GPU、下载权重或运行很久。因此 Skill 对“写脚本”和“执行脚本”做了明确切分:
- 用户要求训练或验证时,先从模板生成脚本。
- 把用户路径和配置填到脚本顶部的常量区。
- 默认不执行;只有用户明确要求运行时,才调用注册的 Python。
这是 Agent 工具设计里很重要的一条边界:产出一个可审查的执行计划,不等于获得执行昂贵任务的授权。
模板比代码片段更可靠
训练模板不是只有一行 llie.train(...)。它同时兼容 YAML 配置和内联配置,并把数据集、输出目录与断点路径集中在文件顶部。验证模板则在调用 llie.evaluate(...) 前完成三类检查:
if not EN_IMG_DIR.is_dir():
raise FileNotFoundError(...)
if REF_IMG_DIR is None and any(
metric.upper() in FULL_REFERENCE_METRICS for metric in METRICS
):
raise ValueError("Full-reference metrics require REF_IMG_DIR.")它还会先导入自定义指标模块,让注册机制在评估开始前生效。Agent 不需要每次临时拼一份结构不同的脚本,用户也能快速看懂需要修改的位置。
把领域知识写成恢复路径
只告诉 Agent “checkpoint 不存在”还不够。Skill 继续规定了失败后的下一步:可以生成训练脚本得到 best.pt 或 last.pt,也可以去模型文档链接的官方仓库下载权重;同时提醒上游原始 state dict 不一定能被 LibLLIE 直接加载。
类似的恢复路径还包括:
- 缺数据集时说明从官方分发下载、解压并把本地路径作为
root_dir。 - 感知损失首次运行可能下载 VGG19 权重,离线环境需要放行网络或关闭对应依赖。
- 批量推理保留文件名,让增强图和参考图可以按 stem 配对。
这些规则把“报错”变成了下一步行动,也减少了 Agent 自行搜索后走偏的概率。
工作区归用户,Skill 目录只读
生成的训练脚本、验证脚本和输出都放在用户当前工作区,而不是 $LIBLLIE_ROOT。Skill 目录只负责提供能力说明、引用索引和模板。
这条规则看似普通,却能避免自动化工具污染依赖仓库,也让生成物天然进入用户自己的版本控制与目录结构。
仍然存在的取舍
这套设计并非没有成本:
- reference 依赖仓库文档路径,文档重组时需要同步维护链接。
- 全参考指标集合写在模板中,LibLLIE 新增指标后可能发生漂移。
- 外部环境文件提高了确定性,但首次安装比“自动找一个 Python”多了一步。
- 模板降低了生成差异,也意味着特殊训练流程需要在模板之外继续扩展。
这些取舍是有意的。对涉及 GPU、数据集和模型权重的任务,我更愿意接受少量显式配置,也不希望 Agent 在错误环境里顺利跑完一条错误命令。
最后
一个好 Skill 不应该只是更长的提示词。它需要知道何时加载知识、何时复用模板、何时执行工具,也需要知道何时停下来。
LibLLIE Skill 最值得保留的设计,不是某一条命令,而是这套层次:短入口负责决策,reference 负责导航,项目文档负责事实,模板负责落地,安全门负责约束行动。