工具设计与函数调用
函数调用(Function Calling / Tool Use)是 LLM 与外部世界交互的标准协议:模型不直接执行代码,而是输出一个结构化的调用意图,由宿主程序执行后把结果回填。
协议机制
一次工具调用涉及三个角色:模型(决策方)、宿主(执行方)、工具(能力方)。
宿主 ──发送 [上下文 + 工具清单]──→ 模型
宿主 ←──返回 [tool_call: 名称 + JSON 参数]── 模型
宿主 ──执行工具──→ 工具
宿主 ──回填 [role: "tool" 的结果消息]──→ 模型
(循环,直到模型返回纯文本)
工具清单用 JSON Schema 声明,这是模型对工具的全部认知来源:
tools = [{
"type": "function",
"function": {
"name": "search_employee",
"description": (
"按姓名检索员工基础信息。返回字段:部门、岗位、入职日期。"
"同名多人时返回候选列表,此时应向用户澄清而不是猜测。"
),
"parameters": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "员工姓名,全名"},
"department": {
"type": "string",
"enum": ["教研部", "IT部", "市场部"],
"description": "可选,用于同名消歧",
},
},
"required": ["name"],
},
},
}]
描述工程
工具描述是写给模型看的 API 文档。高描述质量的要点:
- 说明"何时用"而不只是"是什么":"当问题涉及私有知识时调用" 比 "检索知识库" 信息量大得多;
- 说明返回结构:模型需要知道返回什么才能规划下一步;
- 说明边界与歧义处理:如上面的"同名多人返回候选列表",提前约定了消歧策略;
- 给出典型调用:复杂参数(如查询语法、日期格式)附一个示例值。
反面模式:动词含糊(process、handle)、一个工具塞十几个参数、用自由字符串表达枚举语义。
参数与返回值
参数:强类型、必填最小化、枚举约束。模型填自由字符串的出错率远高于受限字段。日期、ID 等格式在 description 中写死格式(如 YYYY-MM-DD)。
返回值:结构化优先(JSON),并控制体积——完整结果很大时返回摘要 + 一个"取全文"的后续工具(如 read_file(path, offset, limit))。大结果全量回填上下文是成本与注意力双输的设计。
{
"ok": true,
"found": 1,
"items": [{"name": "张伟", "department": "教研部"}],
"hint": "如需详细档案可调用 get_employee_profile"
}
错误设计:可行动优先
错误信息是给模型的修复指引。分级处理:
| 错误类型 | 返回方式 | 模型可采取的动作 |
|---|---|---|
| 参数错误 | 指出字段、期望格式、可选值 | 修正参数重试 |
| 资源不存在 | 列出相近候选 | 换目标或向用户澄清 |
| 权限不足 | 明确说明无权限 | 走人工 / 放弃该路径 |
| 服务故障 | 保留错误类别,建议稍候重试 | 重试一次后转告用户 |
{
"ok": false,
"error_type": "invalid_argument",
"message": "department 必须是以下之一:教研部/IT部/市场部,收到 '教务处'"
}
绝对不要做的:异常吞掉返回空字符串、把堆栈原文直接回填(噪声大且可能泄敏)、静默降级返回错误数据。
工具数量管理
单轮可见工具越多,选择正确率越低。经验阈值在十几个量级,超过后:
- 分组路由:入口先分类,每组挂载自己的工具子集;
- 工具检索:把工具描述本身向量化,按任务检索出候选工具再注入清单;
- 命名前缀:
db_query、db_schema、web_search,让同类工具在命名上成簇。
MCP:工具接入的开放协议
传统做法里每个应用为每个模型重新实现一遍工具接入。Model Context Protocol(MCP)将其标准化:工具提供方实现一次 MCP Server(暴露 tools / resources / prompts 能力),任何支持 MCP 的客户端(IDE、聊天应用、Agent 框架)即插即用。
Agent 宿主(MCP Client)──标准协议──→ MCP Server(文件系统)
├──→ MCP Server(数据库)
└──→ MCP Server(内部业务 API)
对自建系统的价值:工具层与应用层解耦,团队可以独立迭代"能力面";对生态的价值:一个社区维护的 MCP Server,所有接入方共享。MCP 不改变工具设计的基本功——描述质量、错误设计仍然是决定使用效果的第一因素。
安全边界
- 最小权限:每个工具只授予完成其职能所需的最小权限,凭据由宿主持有,模型永远只见到参数;
- 参数白名单校验:模型输出的参数必须过服务端校验(路径穿越、SQL 注入、越权 ID),不能信任模型输出的合法性;
- 高危操作显式确认:删除、外发、支付类工具,执行前转人工确认;
- 注入防御:工具返回的内容(网页、文档)可能包含诱导模型的指令,对外部内容做隔离标注,并限制其能触发的操作级别,详见评测与安全。