Agent 的门槛不在模型能力,而在工程约束:循环要能停下来、失败要能退回去、写操作要有人兜底、账单要能被解释。这四点没想清楚,Agent 只会变成一个随机花钱的脚本。
工具调用是一个循环
- ① 你带上工具清单发请求工具清单里有名字、用途说明、参数 schema。清单本身也占输入 token。
- ② 模型不回答,而是返回「要调哪个工具、参数是什么」这一步通常不算输出长文本,但会计输出 token。
- ③ 你的代码真正执行工具模型永远不会自己执行任何东西——查库、发请求、改文件都是你的程序在做。
- ④ 把执行结果回传,模型继续结果会进入历史,下一轮全部重发。循环直到模型给出最终答复或触发你的上限。
{
"name": "get_order_status",
"description": "查询订单当前状态。仅用于用户提供了订单号、且问题与物流或退款有关时。",
"input_schema": {
"type": "object",
"properties": {
"order_id": { "type": "string", "description": "订单号,形如 A12345678" },
"include_logistics": { "type": "boolean", "default": false }
},
"required": ["order_id"]
}
}工具定义写不好,模型就会乱调
- description 要写「什么时候用」,不只是「是什么」:模型靠这句话决定要不要调、调哪个;
- 参数少而明确:能给枚举就别给自由字符串,能必填就别可选;
- 工具数量控制在十来个:清单越长,选错的概率越高,输入 token 也越贵;
- 错误也返回结构化结果:失败原因写清楚,模型才有机会换参数重试,而不是一直重复同一个调用。
循环控制:五条硬约束
| 约束 | 建议值 | 不设的后果 |
|---|---|---|
| 最大步数 | 6~12 步 | 无限循环,账单失控 |
| 总超时 | 60~120 秒 | 用户等待不可控,请求被网关掐断 |
| 重复调用检测 | 相同工具 + 相同参数出现 2 次即停 | 模型卡在同一个失败调用上烧钱 |
| 单次输出上限 | 按任务设定 | 某一步生成长文,把预算吃光 |
| 失败预算 | 连续失败 3 次即退出并回报 | 把上游故障放大成成本事故 |
成本:比普通对话高一个量级
每一轮循环都要把「原始问题 + 全部工具结果 + 之前的调用记录」重新发一遍,输入量随步数快速增长。这也是为什么缓存对 Agent 场景特别关键:前缀稳定时重复部分只收约一折,不稳定时每一步都是全价。
- 把「系统提示词 + 工具清单 + 固定示例」放最前且不要改,保证前缀可缓存;
- 工具返回值别原样回传:日志、HTML、几十 KB 的 JSON 先裁剪成关键字段;
- 给每一步记账:记录每轮的 usage,才能知道钱花在推理还是花在搬运数据。
权限与安全:写操作必须有人兜底
- ① 区分读与写读操作可自动执行;写、删、付款、发消息一律要显式确认或二次校验。
- ② 最小权限工具用只读账号、限定目录、限定域名;不要给 Agent 一个能改生产的数据库连接。
- ③ 沙箱执行能跑代码的 Agent 必须在隔离环境里跑,并限制网络与文件系统范围。
- ④ 全程留痕记录每一步的工具名、参数、返回值与耗时:出问题能复盘,也是给用户解释账单的依据。
什么任务值得做成 Agent
- 适合
- 步骤数固定、每步都能验证、失败可重试:查数据→汇总→出报告,改代码→跑测试→修错
- 不适合
- 开放式目标、无法验证结果、涉及不可逆操作:自主下单、自主对外发言、无审核的批量改库
- 先做工作流,再做 Agent
- 如果流程每一步都能写死,直接用固定工作流调模型,比让模型自己规划更便宜也更稳
常见问题
模型真的会执行操作吗?
不会。模型只输出「我想调用某个工具、参数是这些」,真正的执行发生在你的代码里。所以工具调用的安全性完全取决于你在执行前加了多少校验。
Agent 为什么比普通对话贵那么多?
每一轮循环都会把历史记录和工具结果重新发一遍,输入量随步数增长;再加上工具清单与返回数据本身也占 token。缓存是否生效,直接决定成本差几倍。
MCP 和直接写 function calling 有什么区别?
功能等价,区别在形态:直接写在代码里,工具与业务耦合;MCP 把工具做成独立服务,客户端可插拔复用。工具只有一两个时直接写更快,要跨客户端复用时才值得上 MCP。