1. 从“只会聊天”到“能办实事”:Function Calling 到底解决了什么问题
你问大模型“上海明天天气怎么样”,它大概率会告诉你训练数据截止到某个时间点,没法给出实时结果。这不是模型笨,而是它的能力边界:它只能基于已有参数预测下一个 token,没法主动去查数据库、调接口、发邮件。Function Calling(函数调用)就是补上这块短板的关键机制——让 LLM 把自然语言需求转成结构化的调用意图,再由外部程序真正执行。
一句话定义:Function Calling 是大语言模型把用户输入解析成可执行的结构化请求(通常是 JSON),用来调用外部函数或 API 的能力。它让模型从“只会说”变成“能动手”。
适合谁看:正在做 AI Agent、想给聊天机器人接实时数据、或者被“模型答不了实时问题”卡住的开发者。你不需要先精通 MCP 或复杂框架,只要会发 HTTP 请求、能看懂 JSON,就能跟着下面的步骤跑通一次完整调用。
这里要分清两个容易混的概念。Tool(工具)是开发者写好的具体功能,比如查天气的函数、发邮件的接口,它是被动的执行单位。Function Calling 是模型具备的能力:判断什么时候该用工具、用哪个、传什么参数。工具是“被调用的”,Function Calling 是“调用工具的能力”,两者配合才完成一次真实操作。
整个链路里其实有五个角色:用户、应用服务器、API 层、底层大模型、工具函数。用户发请求到应用服务器,服务器把请求和可用工具列表一起转发给模型层,模型决定调用哪个工具并给出参数,服务器执行工具拿到结果,再把结果回传给模型,模型整理成自然语言返回给用户。八步走完,一次工具调用才算闭环。
判断一个模型是否真具备 Function Calling 能力,看三点:能不能解析工具列表、能不能挑对工具并给出正确参数、能不能解析工具返回结果并转成人话。三点都满足,才算真正可用。很多“看起来能调工具”的模型,其实卡在第二步——参数给错或工具选错,后面全崩。
理解了这条链路,接下来就要落到实操:怎么拿到可用的 API Key、怎么配 Base URL、怎么发一次真实的 Function Calling 请求。下面从环境准备开始。
2. 前置准备:在 TaoToken 拿到 API Key 并确认 Base URL
要把上面的链路跑起来,你需要一个能访问模型 API 的入口。TaoToken 提供统一的 API 接入层,你拿到 Key 之后,用标准的 HTTP 请求就能调用支持 Function Calling 的模型。这一步不复杂,但几个参数必须对齐,否则后面一定报 401。
先访问官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册并登录。登录后进入控制台,地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。在控制台里找到 API Keys 页面,路径是 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite ,点创建新 Key,复制保存。这个 Key 只显示一次,丢了只能重建。
Base URL 用 https://taotoken.net/api ,注意这个地址后面不加 UTM 参数,直接作为请求根路径。Model ID 填你账号下可用的支持 Function Calling 的模型名,具体以控制台模型列表为准。三个要素记牢:Base URL、API Key、Model ID,后面所有配置都围绕它们展开。
如果你用的是 Claude Code 这类编码工具,或者 Cline、Codex 这类支持 MCP 的客户端,配置方式略有不同。以 Claude Code 为例,它需要 Anthropic 风格的接入配置,文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 有说明。Coding Plan 适合长期编码和 Agent 场景,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。如果你只是想先验证模型能不能正常对话,可以用模型对话页面 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 快速试一条消息。
这里提醒一个常见坑:很多人把 Base URL 写成带/v1或带斜杠结尾的形式,结果请求 404。正确做法是直接用https://taotoken.net/api,具体路径由你的请求方法决定。另外 Key 不要硬编码在会提交到 Git 的文件里,用环境变量或本地配置文件管理。
准备好这三个要素后,下一节直接给可复制的配置和请求体。你可以先在一个空目录里建一个config.json,把 Key 和 Model ID 填进去,后面代码直接读这个文件,避免每次手输。
3. 可复制配置:Function Calling 请求 JSON 与客户端 settings 片段
这一节给两份可直接用的配置。第一份是 Function Calling 的请求体 JSON,第二份是支持 MCP 的客户端 settings 片段。两份都按真实字段写,你替换 Key 和 Model ID 就能跑。
先看请求体。下面这个 JSON 发给https://taotoken.net/api的对话接口,核心是tools数组和tool_choice字段。tools里定义了一个查天气的函数,参数用 JSON Schema 描述。模型收到后会判断是否需要调用,并返回结构化的tool_calls。
{ "model": "你的ModelID", "messages": [ { "role": "user", "content": "上海明天天气怎么样?" } ], "tools": [ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市指定日期的天气", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,例如上海" }, "date": { "type": "string", "description": "日期,例如明天或2025-06-01" } }, "required": ["city", "date"] } } } ], "tool_choice": "auto" }tool_choice设为auto表示让模型自己决定是否调用工具。你也可以强制它调用某个工具,写成{"type":"function","function":{"name":"get_weather"}}。description字段很关键,模型靠它判断这个工具是干嘛的,写清楚能显著降低选错工具的概率。
再看客户端 settings 片段。如果你用 Cline 或类似支持 MCP 的编辑器插件,配置通常长这样,放在settings.json或对应的 MCP 配置区:
{ "mcpServers": { "taotoken-tools": { "command": "npx", "args": ["-y", "@your/mcp-server"], "env": { "BASE_URL": "https://taotoken.net/api", "API_KEY": "你的APIKey", "MODEL_ID": "你的ModelID" } } } }注意这里三件套齐全:Base URL、API Key、Model ID 都在env里。少任何一个,MCP 客户端启动时就会报连接失败或鉴权错误。如果你用的是 Codex 的auth.json,结构不同但字段含义一致,同样要保证这三个值正确。
配置写完后,先别急着跑复杂逻辑。用一条最简单的请求验证连通性:只发messages,不带tools,看模型能不能正常回话。通了再加tools,这样出问题时能快速定位是网络问题还是工具定义问题。
4. 验证请求:用 curl 和 MCP 工具确认调用是否生效
配置就绪后,用 curl 发一次真实请求,看模型返回的tool_calls结构。这是验证 Function Calling 是否生效最直接的方式。
curl -X POST https://taotoken.net/api/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer 你的APIKey" \ -d '{ "model": "你的ModelID", "messages": [{"role": "user", "content": "上海明天天气怎么样?"}], "tools": [{ "type": "function", "function": { "name": "get_weather", "description": "查询指定城市指定日期的天气", "parameters": { "type": "object", "properties": { "city": {"type": "string"}, "date": {"type": "string"} }, "required": ["city", "date"] } } }], "tool_choice": "auto" }'如果一切正常,你会看到响应里choices[0].message下出现tool_calls数组,里面包含function.name为get_weather,arguments是类似{"city":"上海","date":"明天"}的 JSON 字符串。这说明模型已经正确解析了工具列表并给出了调用意图。
拿到tool_calls后,你的服务器需要真正执行get_weather函数,把结果作为一条role: tool的消息追加到对话里,再发第二次请求。第二次请求的messages会包含原始用户消息、模型的tool_calls消息、以及工具返回结果。模型收到后会把结构化数据整理成自然语言。
{ "role": "tool", "tool_call_id": "模型返回的id", "content": "{\"city\":\"上海\",\"date\":\"明天\",\"weather\":\"多云\",\"temp\":\"20-25度\"}" }第二次请求发出后,模型返回的content就是“明天上海多云,20 到 25 度”这样的人话。到这里,一次完整的 Function Calling 闭环就跑通了。
如果你用 MCP 工具串联验证,流程类似但工具发现由 MCP Server 负责。客户端启动 MCP Server 后,会先拉取工具列表,模型看到的tools来自 MCP 的tools/list响应。你可以在 MCP 客户端里发一条同样的天气问题,观察日志里是否出现tools/call请求。出现即说明 MCP 链路和 Function Calling 已经串起来。
实测下来,最容易出问题的不是模型本身,而是工具描述写得太模糊,导致模型选错工具或参数给错。把description和参数description写具体,能省掉大量调试时间。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
这一节对照真实报错给排查路径。你遇到的大部分问题集中在鉴权、网络、响应解析三类。
401 Unauthorized 最常见。原因通常是 API Key 写错、Key 已失效、或者请求头格式不对。检查Authorization头是不是Bearer 你的Key,中间有空格。如果 Key 是从控制台复制的,注意别把前后空格带进去。另外确认 Base URL 是https://taotoken.net/api,不是别的地址。
local proxy failed 一般出现在本地客户端或 MCP 场景。意思是客户端尝试连接本地代理或 MCP Server 时失败。先确认 MCP Server 进程是否启动,command和args是否写对。如果用了npx,确认本地 Node 环境正常。这个报错和模型 API 本身无关,是本地链路问题。
reading choices 报错通常意味着你拿到的响应不是预期的 JSON 结构,代码在解析choices字段时失败。可能原因:请求打到了错误路径、返回了 HTML 错误页、或者模型返回了非标准格式。先用 curl 看原始响应体,确认choices存在。如果响应里是error字段,按错误信息处理。
OAuth 相关报错多出现在 Claude Code 或 Anthropic 风格接入时。如果你用 Claude Code 接入,需要按文档配置 Anthropic 兼容的 Base URL 和 Key,不能直接套用 OpenAI 风格的请求。文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 有对应说明。OAuth 报错时先确认你用的是 API Key 模式还是 OAuth 模式,两者配置不同。
还有一个隐蔽问题:模型返回了tool_calls,但你的代码没处理,直接把message.content当结果返回,用户看到空回复。检查代码里是否判断了tool_calls字段。另外tool_call_id必须原样回传,写错会导致模型无法关联工具结果。
排查顺序建议:先 curl 验证 Key 和 Base URL,再验证请求体 JSON 是否合法,最后检查代码解析逻辑。大部分问题在前两步就能定位。
6. 把 Function Calling 用起来:从验证到接入 Coding Plan
跑通一次调用后,你可以把它接到真实场景里。比如做一个能查实时数据的客服机器人,或者让 Agent 自动调用多个工具完成复杂任务。核心思路不变:定义工具、发请求、处理tool_calls、执行、回传结果。
如果你要长期做编码或 Agent 开发,Coding Plan 提供更稳定的调用额度和管理能力,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 有完整的参数说明和示例。API Keys 管理在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。
一个实用技巧:把工具定义单独抽成一个 JSON 文件,代码启动时加载。这样新增工具不用改主逻辑,也方便版本管理。工具描述尽量写清楚“什么时候用”和“参数含义”,模型选对的概率会高很多。
最后提醒一点:Function Calling 的可靠性依赖模型能力,不同模型对工具列表的解析和参数提取水平有差异。上线前用一批真实用户问法做测试,覆盖参数缺失、多工具选择、模糊表达等场景,比只看单次成功更有意义。