Claude API 工具调用实战指南:Function Calling 怎么配、怎么用

2026-06-30 15:56:27 0点赞 1收藏 0评论

如果你在搜 Claude API Function Calling,大概率是想实现类似 OpenAI Function Calling 的能力:让模型判断要不要调用某个函数,并把参数结构化返回给后端。

先说结论:在 Claude 官方体系里,更常用的叫法是 Tool Use,也就是工具调用。它不是让 Claude 直接执行你的函数,而是让 Claude 生成一份“调用请求”,真正执行动作的仍然是你的服务端。

典型流程如下:

用户提问 → Claude 判断是否需要工具 → 返回 tool_use → 后端执行真实函数 / 查询数据库 / 请求业务 API → 后端把结果作为 tool_result 回传 → Claude 基于结果生成最终回复

简单理解:

Claude 负责“决定调用哪个工具、参数是什么”;
你的后端负责“真正执行工具,并把结果返回给 Claude”。

这篇主要按实战视角讲:该怎么配置、什么场景适合用、后端要注意什么、哪些坑容易踩。


一、Claude 工具调用适合什么场景?

不是所有 AI 应用都需要工具调用。判断标准很简单:这个问题是否依赖外部实时数据或业务系统?

适合用工具调用的场景

比如下面这些,就很适合接 Claude Tool Use:

  • 查询订单状态、物流状态、退款进度;

  • 查询天气、库存、汇率、股票等实时数据;

  • 调用 CRM、ERP、工单系统、支付系统;

  • 从用户输入中抽取结构化参数;

  • 根据规则判断是否满足某个业务条件;

  • 串联多个工具,做简单 Agent 流程。

例如用户问:

帮我查一下订单 OD20240601001 发货了吗?

这类问题,Claude 自己不可能知道真实订单状态,必须调用你的订单系统。

不太适合用工具调用的场景

下面这些通常直接让 Claude 回答就行:

  • 普通知识问答;

  • 文案生成;

  • 文章总结;

  • 翻译润色;

  • FAQ 固定问答;

  • 不依赖实时数据的解释类问题。

硬接工具调用的结果往往是:

  • 请求轮次变多;

  • token 成本增加;

  • 代码复杂度上升;

  • 问题排查更麻烦。

所以我的建议是:只有当模型必须访问外部数据或系统时,再上工具调用。


二、Claude Tool Use 里几个核心字段

在 Claude Messages API 里,和工具调用关系最密切的字段主要有这些:

字段 作用 tools 告诉 Claude 当前有哪些工具可用 input_schema 定义工具参数结构和类型 tool_use Claude 返回的工具调用请求 tool_result 后端执行工具后返回给 Claude 的结果 tool_choice 控制模型自动调用、强制调用或不调用工具

实际开发时,最常打交道的是:

  • 你传入 tools;

  • Claude 返回 tool_use;

  • 你执行函数;

  • 你再传回 tool_result。


三、完整调用流程

下面用一个“查询订单状态”的例子说明。


1. 定义工具 tools

注意,这一步不是把真实函数上传给 Claude,而是给 Claude 一份“工具说明书”。

示例:

{ "name": "get_order_status", "description": "根据订单 ID 查询订单的支付状态、发货状态和预计送达时间。只有当用户明确询问订单状态、物流进度或订单是否发货时才使用。", "input_schema": { "type": "object", "properties": { "order_id": { "type": "string", "description": "订单编号,例如 OD20240601001" } }, "required": ["order_id"] } }

这里最关键的是三个部分:

  • name:工具名,后端一般会根据它分发函数;

  • description:告诉 Claude 这个工具什么时候该用;

  • input_schema:约束参数格式。


2. 把用户问题和 tools 一起发给 Claude

用户输入:

帮我查一下订单 OD20240601001 发货了吗?

请求中同时带上工具列表。Claude 会自己判断:这个问题是否需要调用工具。

如果它认为需要,就不会直接给最终答案,而是返回一个 tool_use。


3. 解析 Claude 返回的 tool_use

Claude 返回内容可能类似这样:

{ "type": "tool_use", "id": "toolu_01ABC", "name": "get_order_status", "input": { "order_id": "OD20240601001" } }

这说明 Claude 想调用:

get_order_status(order_id="OD20240601001")

这时常见的 stop_reason 是:

"tool_use"

意思是:Claude 暂停生成最终回答,等待你执行工具并返回结果。


4. 后端执行真实函数

你的服务端需要做几件事:

  1. 根据 name 找到对应函数;

  2. 校验 input 参数;

  3. 判断用户是否有权限查询;

  4. 调用数据库或业务 API;

  5. 得到真实结果。

伪代码大概是这样:

if (toolUse.name === "get_order_status") { const { order_id } = toolUse.input; // 参数校验 if (!/^ODd+$/.test(order_id)) { throw new Error("Invalid order_id"); } // 权限校验 // 确认当前用户是否有权查询该订单 const result = await getOrderStatusFromDB(order_id); }

这里有个非常重要的点:

不要无条件相信 Claude 生成的参数。

尤其是涉及下面这些操作时,一定要做后端校验:

  • 数据库读写;

  • 支付、退款;

  • 文件系统操作;

  • 邮件、短信发送;

  • 用户权限变更;

  • 删除、取消、提交类动作。

Claude 生成的是“建议调用参数”,不是可信指令。


5. 用 tool_result 把结果回传给 Claude

工具执行完成后,需要把结果包装成 tool_result 发回 Claude。

关键是:tool_use_id 必须和上一轮 Claude 返回的 tool_use.id 对上。

示例:

{ "type": "tool_result", "tool_use_id": "toolu_01ABC", "content": { "order_id": "OD20240601001", "payment_status": "paid", "shipping_status": "shipped", "estimated_delivery": "2024-06-05" } }

不要自己随便生成 tool_use_id,否则 Claude 不知道这份结果对应哪次工具调用。


6. Claude 生成最终回答

Claude 收到 tool_result 后,会基于真实结果生成自然语言回复,例如:

你的订单 OD20240601001 已支付并已发货,预计 2024-06-05 送达。

这才是用户最终看到的答案。


四、tools 怎么写更稳定?

工具调用好不好用,很多时候取决于 tools 写得够不够清楚。


1. 工具名要具体,不要太泛

推荐:

get_order_status search_products cancel_order create_support_ticket

不推荐:

get_data query do_action handle_request

原因很简单:工具名太泛,模型容易选错,后端路由也不好维护。

如果你有多个工具,工具名最好能一眼看出用途。


2. description 不只写“能做什么”,更要写“什么时候用”

很多人会这样写:

查询订单。

这个描述太模糊了。

更推荐这样写:

根据订单 ID 查询订单的支付状态、发货状态和预计送达时间。只有当用户明确询问订单状态、物流进度或订单是否发货时才使用。

如果工具之间职责相近,更要把边界写清楚。

比如:

get_order_status:只用于查询订单支付和发货状态。 get_refund_status:只用于查询退款申请状态和退款到账时间。

否则用户问“我的订单处理到哪了”,模型可能不知道该选订单工具还是退款工具。


3. input_schema 要尽量约束参数

input_schema 建议至少包含:

  • type

  • properties

  • required

  • 字段级 description

示例:

{ "type": "object", "properties": { "order_id": { "type": "string", "description": "订单编号,例如 OD20240601001" }, "status_type": { "type": "string", "enum": ["payment", "shipping", "refund"], "description": "要查询的状态类型" } }, "required": ["order_id", "status_type"] }

如果字段只有固定选项,建议一定加 enum。

不加的话,模型可能生成:

物流状态 发货情况 delivery shipping_status

这些对人来说差不多,但后端可能完全匹配不上。


五、tool_choice 怎么用?

tool_choice 主要控制 Claude 是否调用工具,以及调用哪个工具。

常见有三种用法。


1. 自动选择工具

适合大多数客服、问答、业务助手场景。

模型会根据用户问题判断要不要调用工具。

适合:

  • 用户可能问业务数据,也可能普通聊天;

  • 多个工具可选;

  • 不确定是否必须调用工具。


2. 强制调用某个工具

适合你明确知道这个任务必须走工具的情况。

比如:

  • 表单信息抽取;

  • 固定结构化解析;

  • 必须查数据库才能回答;

  • 必须走风控规则判断。

示例:

{ "tool_choice": { "type": "tool", "name": "get_order_status" } }

这种方式可以减少模型“偷懒直接回答”的情况。


3. 不调用工具

如果只是总结、改写、写文案,其实不传 tools 就可以。

比如:

  • “帮我总结这段文字”

  • “帮我写一段商品介绍”

  • “把这句话改得更礼貌”

这类任务不需要工具,直接调用模型更省事。


六、temperature 和 max_tokens 怎么设置?

工具调用场景里,我一般建议:

temperature:0 ~ 0.3

原因是工具调用更看重稳定性,不需要太多随机发挥。

如果你希望模型稳定抽取参数、稳定选择工具,就不要把温度调太高。

max_tokens 则要根据场景设置:

  • 只是返回工具调用:可以设小一点;

  • 最终回答比较长:需要适当放大;

  • 多轮工具调用:要预留足够 token。

实战里,建议不要一开始就把 max_tokens 设得特别小,否则可能出现工具参数或最终回复被截断的问题。

Claude API 工具调用实战指南:Function Calling 怎么配、怎么用

七、实战中最容易踩的坑

下面这些是接 Claude Tool Use 时比较常见的问题。


坑 1:以为 Claude 会直接执行函数

Claude 不会直接访问你的数据库,也不会直接调用你代码里的函数。

它只会返回类似:

{ "name": "get_order_status", "input": { "order_id": "OD20240601001" } }

真正执行必须由后端完成。


坑 2:工具描述太模糊,导致选错工具

比如你定义了两个工具:

query_order query_refund

描述都写成:

查询信息。

这种情况下,模型选错并不奇怪。

建议把使用条件写清楚:

query_order:当用户询问订单是否支付、是否发货、物流进度时使用。 query_refund:当用户询问退款申请、退款审核、退款到账时间时使用。


坑 3:没有做参数校验

不要因为参数是 Claude 给的,就直接传给数据库或内部接口。

至少要校验:

  • 字段是否存在;

  • 类型是否正确;

  • 格式是否合法;

  • 是否在允许枚举中;

  • 当前用户是否有权限操作该资源。

尤其是写操作,比如取消订单、发起退款、修改地址,一定要谨慎。


坑 4:tool_use_id 对不上

回传 tool_result 时,tool_use_id 必须使用 Claude 返回的那个 tool_use.id。

错误示例:

{ "tool_use_id": "my_custom_id_123" }

正确做法:

{ "tool_use_id": "toolu_01ABC" }

这个 ID 是模型识别上下文的重要依据,不能乱填。


坑 5:把敏感权限交给模型决定

Claude 可以帮你判断意图,但不能替代权限系统。

比如用户说:

帮我取消这个订单。

Claude 可以提议调用 cancel_order,但后端仍然必须确认:

  • 这个订单是不是当前用户的;

  • 订单当前状态是否允许取消;

  • 是否需要二次确认;

  • 是否存在风控限制。

我的建议是:

读操作可以相对宽松,写操作必须加权限校验和确认流程。


坑 6:工具太多,模型选择不稳定

如果一次传给 Claude 几十个工具,模型选择错误的概率会变高,token 成本也会上升。

建议:

  • 按业务场景拆分工具集;

  • 当前页面只传当前场景需要的工具;

  • 工具描述保持明确;

  • 相似工具尽量合并或明确边界。

例如订单详情页只传:

get_order_status get_logistics_info apply_refund

不要把商品搜索、优惠券、会员积分、客服工单全塞进去。


八、推荐的后端处理结构

实战里可以按这个思路组织代码:

1. 接收用户输入 2. 调用 Claude,传入 messages + tools 3. 判断返回内容是否包含 tool_use 4. 如果有 tool_use: 4.1 根据 name 路由到对应函数 4.2 校验 input 4.3 校验权限 4.4 执行业务逻辑 4.5 生成 tool_result 4.6 再次调用 Claude 5. 返回 Claude 最终自然语言回答

简单伪代码:

const response = await callClaude({ messages, tools }); const toolUse = findToolUse(response); if (toolUse) { const result = await executeTool(toolUse.name, toolUse.input, currentUser); const finalResponse = await callClaude({ messages: [ ...messages, responseMessage, { role: "user", content: [ { type: "tool_result", tool_use_id: toolUse.id, content: JSON.stringify(result) } ] } ], tools }); return finalResponse; } return response;

核心点就两个:

  • tool_use 是 Claude 发出的调用请求;

  • tool_result 是你执行后返回给 Claude 的结果。


九、我的配置建议

如果是第一次接 Claude 工具调用,可以按下面这个配置思路起步:

工具定义

  • 工具名用英文小写加下划线;

  • 一个工具只做一类明确任务;

  • description 写清楚使用条件;

  • 参数尽量用 JSON Schema 约束;

  • 固定值一定用 enum。

模型参数

  • temperature 设为 0 ~ 0.3;

  • max_tokens 不要过小;

  • 工具调用链路先保证稳定,再考虑文案表现。

安全策略

  • 后端必须校验参数;

  • 后端必须校验权限;

  • 高风险操作增加二次确认;

  • 不让模型直接决定写操作;

  • 对工具调用做好日志记录,方便排查。


十、总结

Claude API 的 Function Calling,本质上就是官方所说的 Tool Use 工具调用

它的关键不是“让模型执行函数”,而是让模型:

理解用户意图 → 判断是否需要工具 → 生成结构化调用参数 → 等待后端执行结果 → 基于真实结果回答用户

如果你的应用需要连接订单、库存、物流、CRM、ERP、数据库等外部系统,Claude 工具调用非常实用。

但如果只是写作、总结、翻译、普通问答,就没必要强行接工具。

最后给一个实战建议:

工具调用的稳定性,主要取决于三件事:工具描述是否清楚、参数 schema 是否严格、后端校验是否完善。做好这三点,Claude Tool Use 才能真正稳定落地。

展开 收起
0评论

当前文章无评论,是时候发表评论了
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
最新文章 热门文章
1
扫一下,分享更方便,购买更轻松