进阶
Function Calling 实战:让 Agent 调用真实 API
AI Agent 如果只会"说话",那它和聊天机器人没区别。Function Calling 是让 Agent 真正"干活"的关键技术——查天气、下订单、发邮件、调数据库,全部通过函数调用实现。
💡 本教程需要基本的编程概念理解,但不需要手写代码——OpenClaw 提供了可视化配置界面,Cursor 可以帮你生成函数定义。
理解 Function Calling
1 从对话到行动
没有 Function Calling 的对话:
用户:明天北京天气怎么样?
AI:北京明天可能是晴天,气温大约20度左右。
(AI 在猜,可能不准)
有 Function Calling 的对话:
用户:明天北京天气怎么样?
AI:让我查一下天气信息。→ [调用 get_weather("北京")]
北京明天(4月23日)晴,最高22°C,最低12°C,
东南风3级,空气质量优。
(基于真实 API 数据,准确可靠)
核心区别:
纯对话 → AI "编"答案 → 可能错误
Function Calling → AI "查"答案 → 准确可靠
步骤一:定义工具函数
2 编写函数描述(JSON Schema)
Function Calling 的第一步是告诉 AI "你有哪些工具可以用":
工具定义示例:
1. 查天气
{
"name": "get_weather",
"description": "获取指定城市的天气预报,包括温度、风力、空气质量",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名,如'北京'、'上海'"
},
"days": {
"type": "integer",
"description": "预报天数,1-7天,默认1天",
"default": 1
}
},
"required": ["city"]
}
}
2. 查订单
{
"name": "query_order",
"description": "根据订单号或用户信息查询订单状态和物流信息",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "订单号,如'ORD20260422001'"
},
"user_phone": {
"type": "string",
"description": "用户手机号(与order_id二选一)"
}
},
"required": []
}
}
3. 发送通知
{
"name": "send_notification",
"description": "向用户发送通知消息,支持短信和站内信",
"parameters": {
"type": "object",
"properties": {
"user_id": {
"type": "string",
"description": "用户ID"
},
"message": {
"type": "string",
"description": "通知内容"
},
"channel": {
"type": "string",
"enum": ["sms", "in_app"],
"description": "通知渠道:sms=短信,in_app=站内信"
}
},
"required": ["user_id", "message"]
}
}
🔑 函数描述的质量直接决定 AI 会不会正确调用。描述越精确、示例越具体,AI 调用准确率越高。每个参数的 description 不能省!
步骤二:参数校验与安全
3 防止"胡乱调用"
AI 可能生成不合法的参数,必须做校验:
参数校验清单:
1. 类型校验
- 期望 integer,AI 传了 "3"(字符串)→ 转换或拒绝
- 期望 enum,AI 传了不在列表中的值 → 拒绝
2. 范围校验
- days: 1-7,AI 传了 30 → 拒绝
- amount: >0,AI 传了 -100 → 拒绝
3. 安全校验
- SQL 注入:参数中的特殊字符过滤
- 路径穿越:文件路径参数不允许 ../
- 敏感操作:需要二次确认
4. 权限校验
- 这个用户是否有权限调用这个函数?
- 函数参数是否超出用户权限范围?
- 例如:普通用户查订单只能查自己的
校验实现:
function validateParams(funcName, params, userContext) {
// 1. Schema 校验
if (!matchSchema(params, functionSchemas[funcName])) {
return { valid: false, error: "参数格式不正确" };
}
// 2. 业务校验
if (funcName === "query_order" && params.user_phone) {
if (!userContext.canViewOtherOrders) {
return { valid: false, error: "无权查询他人订单" };
}
}
// 3. 高风险操作确认
if (funcName === "send_notification" && params.channel === "sms") {
return { valid: true, needsConfirmation: true };
}
return { valid: true };
}
步骤三:多工具编排
4 串行与并行调用
Agent 常常需要组合多个工具完成任务:
场景:用户说"帮我查一下上周的订单到哪了"
Agent 的推理过程:
1. 需要先查订单 → query_order
2. 拿到物流单号 → 查物流 → track_package
3. 整合信息回复用户
串行调用(有依赖关系):
query_order(order_id)
→ 拿到 tracking_no
→ track_package(tracking_no)
→ 回复用户
场景:用户说"查一下北京和上海的天气"
并行调用(无依赖关系):
get_weather("北京") ─┐
get_weather("上海") ─┤ → 合并结果 → 回复用户
编排规则:
1. 有数据依赖 → 串行(先A后B,B需要A的输出)
2. 无数据依赖 → 并行(同时调用,节省时间)
3. 总调用次数限制 → 单次对话不超过10次
4. 总耗时限制 → 单次调用不超过30秒
OpenClaw 配置示例:
tools:
- get_weather
- query_order
- track_package
- send_notification
orchestration:
max_parallel: 3 # 最多3个并行调用
max_total_calls: 10 # 单次对话最多10次调用
call_timeout: 30s # 单次调用超时30秒
retry_on_error: 1 # 失败重试1次
5 复杂任务拆解
面对复杂请求,Agent 需要自主规划调用链:
用户:帮我取消昨天那个订单,然后通知客服
Agent 的规划与执行:
📋 任务拆解:
1. 查找昨天的订单 → query_order(date=yesterday)
2. 取消订单 → cancel_order(order_id=xxx)
3. 通知客服 → send_notification(to=cs, ...)
🔄 执行过程:
Step 1: query_order → 找到订单 ORD20260421003 ✅
Step 2: cancel_order(ORD20260421003) → 取消成功 ✅
Step 3: send_notification(cs_team, "用户取消订单ORD...")
→ 通知发送成功 ✅
📝 回复用户:
已帮您取消订单 ORD20260421003(订单内容:蓝牙耳机),
退款将在1-3个工作日原路返回。已通知客服团队跟进。
错误处理:
如果 Step 2 失败(订单已发货不能取消):
→ 跳过 Step 3
→ 回复用户:"该订单已发货,无法取消。
建议您收到货后申请退货,需要我帮您操作吗?"
步骤四:错误处理与降级
6 优雅地处理失败
错误处理策略:
1. API 超时
→ 重试1次
→ 仍超时 → 告知用户"系统繁忙,请稍后再试"
→ 不暴露内部错误信息
2. API 返回错误
→ 解析错误码
→ 用户相关错误:直接告知(如"订单号不存在")
→ 系统相关错误:模糊提示 + 记录日志
3. AI 选择错误的函数
→ 检测到调用结果不合理
→ 回退到对话模式,向用户确认意图
→ 例:"您是想查订单还是查物流?"
4. 第三方服务不可用
→ 降级方案:用缓存数据 / 模板回复
→ 例:天气API不可用 → "暂时无法获取实时天气,
根据历史数据,北京4月下旬通常..."
降级策略配置:
fallback:
get_weather:
- retry: 1
- cache_ttl: 30min # 缓存30分钟
- fallback_msg: "天气服务暂时不可用"
query_order:
- retry: 1
- fallback: 使用本地缓存
- timeout: 10s
🛡️ 安全底线:Function Calling 的所有写操作(下单、退款、发通知等),必须有人工确认环节或严格的权限控制。AI 可以"建议",但不能"擅自行动"。
实战:从零搭建一个工具型 Agent
7 完整配置示例
OpenClaw 工具型 Agent 配置:
name: smart-assistant
description: 智能助手,可以查天气、查订单、发通知
tools:
- name: get_weather
endpoint: https://api.weather.com/v1/forecast
auth: api_key
rate_limit: 60/min
- name: query_order
endpoint: https://api.internal.com/orders
auth: oauth2
rate_limit: 100/min
- name: track_package
endpoint: https://api.logistics.com/track
auth: api_key
rate_limit: 30/min
- name: send_notification
endpoint: https://api.internal.com/notify
auth: oauth2
rate_limit: 10/min
confirmation_required: true # 需确认
safety:
read_only_tools: [get_weather, query_order, track_package]
write_tools: [send_notification]
max_calls_per_turn: 10
max_parallel_calls: 3
require_confirmation: [send_notification]