教程中心Function Calling
进阶

Function Calling 实战:让 Agent 调用真实 API

2026.04.22· 45 分钟实战· 🎨 Cursor + 🌊 OpenClaw

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]