跳到主要内容

AI 智能体的工具契约

工具本质上是一个以函数形式呈现的权限边界。JSON Schema 校验只能证明参数符合格式,却无法证明操作是否经过授权、意图是否正确、重试是否安全,或者执行是否真正完成。

模型提出请求之后,谁执行工具?​

模型请求调用函数,真正执行函数的是应用代码。函数调用指南把这一过程描述为包含工具定义、调用、结果以及后续回答的多轮对话。以只读工具 search_notes 为例:

  1. 应用向模型提供名称、用途和参数 schema:参数是对象,只有必填字符串 query,长度为 1–200,不接受其他字段。实现只允许搜索已获授权的公开笔记索引。
  2. 模型返回工具调用消息,其中包含调用标识、工具名称和参数。应用要等消息完整,不能拿流式输出中的参数片段提前执行。
  3. 应用解析参数、检查 schema 和权限,再分派给允许列表中的函数。格式错误或权限不足时,返回错误,不运行搜索。
  4. 应用把搜索结果与原调用标识对应起来,连同对话状态回送。模型据此回答,或再请求一次允许的操作。

下面用 Responses 风格的字段展示简化消息,不是完整的 API 请求:

{"type":"function_call","call_id":"call_1","name":"search_notes","arguments":"{\"query\":\"KV cache\"}"}
{"type":"function_call_output","call_id":"call_1","output":"{\"status\":\"ok\",\"matches\":[]}"}

空结果表示这次搜索没有命中,不代表这个主题不存在。普通文本即使长得像这段 JSON,也不会因此获得调用权限。供应商适配器或本地解析器须先识别协议层的请求,harness 再决定是否执行。结果仍是不可信数据,不是新的指令;后续行动和停止条件由 Agent 循环管理。

契约的关键维度​

维度核心问题
选择逻辑何时应优先选择此工具而非其他?
输入规范哪些字段、边界值、枚举和路径规则是合法的?
权限边界哪个身份在执行?它有权读取或修改什么?
副作用操作是只读、可逆、对外可见还是具有破坏性?
并发控制读写之间状态发生变化时如何处理?
幂等性相同请求重试是否会导致重复执行?
结果判定如何证明操作完全成功、部分成功、被拒绝或状态未知?
人工审批哪些参数与副作用的组合需要人工介入?
可观测性保留哪些脱敏字段、ID、时间戳和产物?

契约实例​

name: replace_text
purpose: replace one exact block in one repository file
input:
path: repository-relative path, no traversal
old_text: non-empty and must match exactly once
new_text: string
preconditions:
- path is inside approved write scope
- working tree version equals observed version
effects: reversible local write
idempotency: not retryable after success without re-reading
result:
status: succeeded | conflict | no-match | multiple-matches | denied
changed_file: path or null
approval: required when path is outside task scope

这份契约让 Agent 循环能够区分具体的失败原因。通用的 error: edit failed 错误提示只会诱导盲目重试。

结果封装​

稳定的结果结构应将传输层状态与业务层结果分离:

{
"request_id": "req-123",
"status": "partial",
"completed": 8,
"failed": 2,
"retry_safe": false,
"artifact": "results/batch-123.json",
"errors": [{"code": "permission-denied", "item": "..."}]
}

不要将单个项目的成功等同于整个批次的成功。“结果未知”不同于“失败”,因为重复执行对外可见的操作可能会导致数据重复。

设计原则​

  1. 避免 Shell 插值。 尽可能直接传递程序名和参数数组。这能消除 Shell 解析环节,但参数本身仍可能危险:git、云 CLI 和包管理器中都有具备破坏性或代码执行能力的标志位。
  2. 验证解析后的路径。 在规范化并解析符号链接后检查仓库边界;仅拒绝字面量 ../ 是不够的。应将敏感路径排除在工具权限之外,而非依赖黑名单。
  3. 停止无效重试。 根据操作风险和幂等性设置熔断机制。读取操作可容忍多次重试;对外可见的写入操作在结果未知时不应重试。
  4. 返回结构化失败信息。 区分输入格式错误、权限拒绝、临时传输故障、业务逻辑拒绝、部分完成和结果未知。后续动作取决于这些差异。

注入与不可信结果​

网页、Issue、文档和工具元数据中可能包含旨在误导模型的文本。这些数据应保持其数据属性。安全的运行环境应标记不可信的来源,禁止工具输出自动执行权限,从面向模型的上下文中剥离敏感信息,并对提议的下一步操作重新应用策略。类型化响应能减少歧义,但不能净化语义。

小型模型的权衡​

较小的模型通常能更稳定地生成浅层 Schema,但移除 Schema 细节可能会丢弃关键的安全信息。应使用精确的提示词模板和量化配置来测量调用接受率和任务成功率。不要为了适应较弱模型而静默降低权限;应优先选择简单的单一用途工具、受限适配器或更强的模型。

探索关联打开关联网络