一个常见误区是把 OpenAPI 文档直接丢给模型,然后期待它自己组合出正确调用。真实情况是:模型会按语义猜,而大多数内部 API 的命名并不是为语义调用设计的。
一、工具名应该表达意图
query_table 不是能力,find_overdue_homework 才是。工具名越接近用户语言,模型选错工具的概率越低。
// 模糊
run_query(sql)
// 清晰
list_pending_assignments(child_id, subject?)
get_assignment_detail(assignment_id)
create_practice_from_photo(child_id, image_url)
工具数量也要控制。不是越多越好:每多一个工具,选择空间和误用概率都会上升。优先合并同质操作,把复杂组合留在代码里。
二、参数是契约,不是建议
参数名要稳定、类型明确、枚举可穷举。不要让模型传自由格式的 JSON 字符串,也不要让“可选参数”实际上决定完全不同的行为。
- 日期统一用
YYYY-MM-DD,不要让模型猜时间戳; - 枚举值直接列出,不要接受近义词;
- 必填和可选明确区分,缺必填时返回可读错误;
- 高风险参数(删除、发送、支付)必须二次确认。
设计检查
把工具签名给一个不了解系统的人看。他能不能在不看文档的情况下,判断每个参数该填什么?如果不能,模型也不能。
三、错误要能指导下一步
工具返回不只是一个状态码。对 Agent 来说,错误信息是观察结果的一部分。好的错误会告诉它:是继续、换参数、请求用户,还是停止。
// 模型无法行动
{ "error": "400 Bad Request" }
// 模型可以行动
{
"error": "IMAGE_TOO_SMALL",
"message": "图片短边小于 800px,题目文字无法识别",
"next": "请用户重新上传清晰照片,或改用手动录入"
}
把可恢复错误和不可恢复错误分开。可恢复错误可以重试;不可恢复错误应该尽快收敛,避免无限循环。
四、幂等和副作用
Agent 会重试。工具如果不幂等,一次超时就可能创建两份作业、发两条消息。写操作要么带幂等键,要么在服务端做去重。
create_assignment({
child_id: 3,
questions: [...],
idempotency_key: "daily-2026-10-27-child-3"
})
同时区分“查询”和“执行”。读工具可以自由重试,写工具必须有明确的副作用边界,并在轨迹里记录。
五、权限放在代码里,不放在提示词里
“请不要删除用户数据”不是权限控制。真正的权限是服务端校验:这个 Agent 代表谁、能访问哪个家庭、能执行哪些动作。
- 工具执行前校验用户身份和资源归属;
- 高风险工具默认关闭,由人显式开启;
- 所有写操作留下审计记录;
- 不要把管理密钥放进模型可见的上下文。
一个工具定义模板
{
"name": "create_practice_from_photo",
"description": "从一张清晰的作业照片生成练习草稿,不直接布置。",
"when_to_use": "用户上传照片并要求整理成练习时",
"when_not_to_use": "图片模糊、包含人脸或与学习无关时",
"parameters": {
"child_id": "integer, required",
"image_url": "string, required, 已上传图片地址",
"subject": "math|chinese|english, optional"
},
"returns": "draft_id, question_count, warnings[]",
"side_effects": "创建草稿,不发布",
"requires_confirmation": false
}
最后一句很重要:工具不是越自动越好。把“生成草稿”和“正式布置”拆开,系统就多了一个人类检查点。
下一篇:Agent 的记忆 →02 / MEMORY