返回博客

给 Agent 搭一个好脚手架:工具链设计的四个维度

用 LLM 驱动的 Agent 做自动化任务,最容易踩的坑不是提示词写得不够好,而是工具链本身就是一团乱麻——工具太多、语义重叠、报错信息含糊、上下文一次性塞满……模型再聪明,也没办法在一堆劣质工具上可靠地完成任务。

我把这类问题统称为「脚手架质量问题」。好的脚手架让 Agent 路径收敛、错误可恢复;坏的脚手架让 Agent 在模糊中打转,靠运气完成任务。

动作空间:少即是多

第一个要控制的是工具数量和语义边界。

工具太多的直觉来自好心:「给它更多能力,它就能做更多事。」但实际上,工具间的语义重叠是 Agent 规划失败的首要原因——模型不知道该选哪个,或者两个都调用,造成副作用叠加。

我的经验是:先问「这个工具能不能用已有工具组合替代」,不能才加新工具。每个工具要有清晰的、不可替代的职责边界;输入 schema 要窄,不要设计「什么都传进来然后在函数内部分支」的宽接口;输出形状要确定,不要根据运行时条件返回不同结构。

工具粒度要按风险分层:

  • 高风险操作(数据库迁移、部署、权限变更)用微粒度工具,每步都能单独审计和回滚
  • 常规读写搜索用中粒度工具,一次往返完成一个完整意图
  • 只有当往返延迟是主要成本时才考虑宏工具

观测设计:让模型看懂发生了什么

Agent 每次调用工具后,读到的是「观测」。观测质量直接决定下一步规划的质量。

我见过最糟糕的工具响应:返回裸数据,没有状态标志,没有任何对「下一步该做什么」的提示。模型只能靠猜测——而猜错的代价是整个任务链断掉。

每个工具响应应该包含四个字段:

{
  "status": "success | warning | error",
  "summary": "一句话描述结果",
  "next_actions": ["可以做什么", "或者不需要做什么"],
  "artifacts": ["生成的文件路径或资源 ID"]
}

next_actions 是最容易被忽视的一项。它不是给人看的说明书,而是给模型的规划提示。写清楚「你可以继续执行步骤 X」或「任务已完成,不需要继续」,能显著减少模型的无效尝试。

观测即规划信号

工具响应不是数据dump,是模型的下一轮输入。next_actions 写得越清晰,模型越不需要靠推理「猜」下一步——任务完成率直接提升。

错误恢复合约:每个错误路径都要可退出

Agent 任务失败最难处理的不是报错本身,而是「不知道该不该重试、能不能重试、重试多少次」。

每个工具的错误响应都应该包含三件事:

  1. 根因提示:为什么失败了(不是只说「500 Internal Error」)
  2. 安全重试指令:这个错误是幂等的吗?重试需要什么前置条件?
  3. 显式停止条件:什么情况下应该停下来等人工介入,不要继续尝试

没有停止条件的错误处理,会让 Agent 陷入无限重试循环——在一个无法自愈的错误上反复调用,直到 token 耗尽或把系统搞坏。

上下文预算:稀缺资源要主动管理

上下文窗口是有限的,但工程师往往不把它当稀缺资源管理——系统 Prompt 越写越长,把所有文档都塞进去,希望模型「知道得越多越好」。

实际上,不相关的信息不只是浪费,还会干扰模型的注意力,降低规划准确率。

几个有效的做法:

  • 系统 Prompt 只放不变的核心约束,会变化的内容外置成文件,按需加载
  • 长文档用路径引用,不内联——让工具去读,而不是一开始就贴进上下文
  • 在任务阶段边界做压缩,不要等 token 快满了才清理;阶段结束后把中间状态摘要成几句话,丢掉原始交互记录

上下文管理的哲学是:给模型的信息要刚好够用,不要「以防万一」地塞满

一句话心法

Agent 的完成率上限由工具链质量决定,而不是模型能力——先把脚手架搭好,再谈提示词优化。