给大模型装上“手“——Function Calling 从原理到落地
你让 AI 查一下北京今天什么天气它说抱歉我无法获取实时数据。然后你给它接了一个天气 API问题来了——你怎么让模型知道什么时候该调这个 API该传什么参数2023 年 6 月OpenAI 在 GPT-4 上推出了一个叫 Function Calling 的能力。它做的事情一句话讲清让模型自己决定要不要调用一个外部函数、调哪个、传什么参数然后用自然语言把结果讲给用户。三年过去Function Calling 已经从 GPT-4 的一个新功能变成了所有主流模型的标配。OpenAI、Anthropic Claude、Google Gemini、DeepSeek、所有国产模型全都支持。它也从聊天机器人的锦上添花变成了Agent 工程的底层引擎——没有 Function CallingAgent 只是一个会聊天的对话框。Function Calling 到底是怎么工作的先说一个最容易搞混的点。Function Calling 里模型不执行任何函数。它只负责决定和填参数。真正跑代码的是你的应用层。整个交互是一个五步的循环。第一步你在请求里附上一份工具的 JSON Schema 清单告诉模型有哪些函数可以用、每个函数干什么、需要什么参数。tools [{ type: function, function: { name: get_weather, description: 获取指定城市的当前天气, parameters: { type: object, properties: { city: {type: string, description: 城市名如北京}, unit: {type: string, enum: [celsius, fahrenheit]} }, required: [city] } }}]第二步模型收到用户消息北京今天天气怎么样同时看到这份工具清单。它自己判断这个请求需要调 get_weather参数 city 应该填北京。第三步模型不生成自然语言。它直接返回一个结构化的 tool_calls 对象里面包含函数名和 JSON 格式的参数。finish_reason 标记为 “tool_calls”。{ id: call_abc123, function: { name: get_weather, arguments: {\city\: \北京\, \unit\: \celsius\} }}第四步你的应用层拿到这个 tool_calls解析出函数名和参数真正去调天气 API。拿到返回值——“北京22°C晴”。第五步你把这条 tool result 作为一条新的消息发回给模型。模型看到查询结果用自然语言组织成最终回复“北京今天 22°C晴天。”这个五步循环是所有 Agent 系统的最基本骨架。你后面看到的 LangChain Agent、LlamaIndex Agent、MCP 协议、甚至 OpenAI 的 Codex——底层全在跑这个循环。模型内部发生了什么很多人以为 Function Calling 就是在 Prompt 里写一句’如果需要调工具就输出 JSON’。那个做法有而且确实能跑但跟原生的 Function Calling 稳定程度差了一个数量级。原生 Function Calling 是训练层面的事。模型在 SFT监督微调阶段被喂了大量用户说什么→该调哪个工具→参数怎么填的标注样本。这些样本教会模型三件事判断一个请求要不要调工具、从可用工具列表里挑最合适的、按照 JSON Schema 生成合法参数。更底层的是特殊 Token。不同模型厂商用了不同的 Token 体系但逻辑一样。OpenAI 用的是一套 XML 风格的标签Claude 用的是 tool_use 内容块Llama 3.1 用|python_tag|和|end_of_tool_call|DeepSeek 用了一组全角竖线符 。这些 Token 不是普通文本是词表里专门加的标记模型经过训练后当它决定调工具时会以这些 Token 作为切换信号。引擎层检测到这些特殊 Token 后立刻把后续的输出切到受约束解码Constrained Decoding模式。在这个模式下Token 的采样不再自由——解码器拿着 JSON Schema把所有不合法 Token 的概率直接遮罩掉。Schema 说某个字段必须是 integer解码器就把所有非数字 Token 的概率压成零。Schema 说 required 字段有三个模型跳不过去。这就是为什么原生 Function Calling 的 JSON 解析错误率能压到接近零而纯 Prompt 做 JSON 输出动不动就 15-25% 的格式错误。前者靠的是训练解码器夹持后者全靠模型自觉。JSON Schema 怎么写模型才听得懂定义工具 Schema 是 Function Calling 里最被低估的工程环节。Schema 写好了模型几乎不犯错。写烂了它能调出各种匪夷所思的参数。三条铁律。第一description 是模型决策的唯一依据。模型不知道该调哪个工具时靠的就是每个工具的 name 和 description。description 不要写It’s a function that…“这种废话直接说这个工具干什么、适用于什么场景、不适用于什么场景。比如获取指定城市的当前天气包含温度、湿度和风速。不支持未来天气预报查询”。第二参数类型和约束写得越严模型越不会乱来。每个参数的 description 要精准——不是城市名而是城市中文名如北京、上海不要带’市’字。能用 enum 的就用 enum——unit 字段写成enum: [celsius, fahrenheit]模型就不会传 kelvin 进来。required 数组只放真正必需的参数放多了模型会填一堆没意义的默认值放少了它该填的不填。第三用 strict 模式。OpenAI 从 2024 年起支持strict: true强制模型输出的参数 100% 符合 Schema。Anthropic Claude 没有单独的 strict 参数但它原生的 tool_use 内容块本身就是强类型的。如果你不用 strict 模式模型偶尔会在 arguments 里塞进 Schema 没定义的字段——你代码里json.loads能解析但业务逻辑就直接炸了。{ name: search_products, description: 在商品库中搜索。传关键词搜商品名和描述传分类ID按类目过滤。两者不能同时为空。, strict: True, parameters: { type: object, properties: { keyword: {type: string, description: 搜索关键词模糊匹配商品名和描述}, category_id: {type: integer, description: 商品分类ID}, max_price: {type: number, description: 最高价格单位元} }, required: [], additionalProperties: False }}不同框架怎么写先说清楚一个概念上的区分OpenAI 的 API、Anthropic 的 Messages API——这些是模型厂商的底层接口不是应用开发框架。你直接调它们写 Agent每次都要手写五步循环、手动管理消息历史、手动处理 tool result 回传。代码能跑但工程量大。LangChain 和 LlamaIndex 是真正意义上的 AI 应用开发框架。它们在厂商 API 之上做了一层封装把工具定义、调用循环、消息管理、并行处理这些重复逻辑都抽象好了。写 Agent 的时候不用从头手写循环一行tool装饰器就能把普通 Python 函数注册成模型可调用的工具。LangChain——用 tool 装饰器注册from langchain.tools import tooltooldef get_weather(city: str, unit: str celsius) - str: 获取指定城市的当前天气。 Args: city: 城市中文名如北京 unit: 温度单位celsius 或 fahrenheit return f{city}22°C晴# LangChain 自动从类型标注和 docstring 生成 JSON Schemaagent create_react_agent(model, [get_weather])tool 装饰器会自动把 Python 函数的类型标注转成 JSON Schema把 docstring 转成 tool description。不用手写 Schema——前提是你的类型标注和 docstring 写得到位。自动生成的 Schema 也杜绝了Schema 改了但代码没改的漂移问题。LlamaIndex——FunctionTool.from_defaultsfrom llama_index.core.tools import FunctionTooldef get_weather(city: str) - str: 获取指定城市的当前天气 return f{city}22°C晴weather_tool FunctionTool.from_defaults( fnget_weather, nameget_weather, description获取指定城市的当前天气包含温度和天气状况)LlamaIndex 的 FunctionTool 和 LangChain 的 tool 本质一样——函数签名自动生成 Schema。LlamaIndex 跟 RAG 场景结合得尤其好QueryEngineTool 可以把整个检索引擎包装成一个工具Agent 既能查知识库又能调外部 API用一个统一接口管两种数据源。两套框架都解决了同一个问题不用手写工具定义的 JSON Schema、不用手动管理 tool call 的消息循环。选哪个取决于你的技术栈——已经在用 LangChain 的生态就 LangChainRAG 为主的应用场景就 LlamaIndex。Spring AI——Java 生态的工具调用方案。Spring AI 2.0 用 FunctionToolCallback 注册工具ToolCallingAdvisor 自动驱动调用循环ChatClient 统一入口BeanToolCallback currentWeather() { return FunctionToolCallback .builder(currentWeather, weatherService::getWeather) .description(获取指定城市的当前天气) .inputType(WeatherRequest.class) .build();}// ChatClient 自动处理工具调用循环chatClient.prompt() .user(北京天气怎么样) .tools(currentWeather) .call() .content();Spring AI 的做法和 LangChain、LlamaIndex 底层逻辑一致——函数签名自动生成 Schema框架接管调用循环。差异在于它是 Java 原生的跟 Spring Boot 的依赖注入、AOP、配置管理无缝集成。已经在用 Spring 技术栈的团队不需要引入 Python 依赖。AgentScope——阿里达摩院开源的 Python Agent 框架。用 Toolkit 注册工具函数ReActAgent 自动执行 Reasoning Acting 循环from agentscope.tool import Toolkitfrom agentscope.agent import ReActAgent# 定义工具函数——docstring 自动生成 JSON Schemadef get_weather(city: str) - str: 获取指定城市的当前天气。 Args: city: 城市中文名如北京 return f{city}22°C晴# 注册到工具包toolkit Toolkit()toolkit.register_tool_function(get_weather)# ReActAgent 自动管理工具调用循环agent ReActAgent( nameWeatherBot, modelDashScopeChatModel(model_nameqwen-max, api_key...), toolkittoolkit,)response await agent(北京天气怎么样)AgentScope 跟其他三个框架的关键差异有两点。一是它原生支持阿里 DashScope 的模型qwen 系列对国内开发者来说不用翻墙调 API。二是 ReActAgent 把工具调用循环完全封装在内部——你不需要手写 while 循环检查 tool_callsawait 一下 agent 调用它就自己思考、调工具、再思考直到返回最终结果。五个生产环境中最容易踩的坑并行调用没处理好。用户问北京和上海今天天气怎么样OpenAI 和 Claude 都会在一个请求里返回两个 tool_calls。你的代码如果只处理了第一个第二个直接被丢掉用户只看到北京的天气。tool result 忘了回传 assistant message。把函数执行结果发回给模型时必须先把模型上一条包含 tool_calls 的 assistant message 也追加到消息历史里。漏了这一步模型会一脸懵——“我什么时候让你查天气了”Schema 和实际代码不同步。你改了函数签名加了参数但忘了更新 Schema。模型照着旧 Schema 传了三个参数你的函数只接受两个直接 TypeError。用 LangChain 的 tool 或 Pydantic 自动生成 Schema 能根治这个问题。不校验模型返回的参数。即使开了 strict 模式模型仍然可能传合法但危险的值——比如 search_files 的 path 参数被传了../../../etc/passwd。工具执行前必须做输入校验和路径清理。工具太多时模型选错。一个 Agent 挂了三十个工具每个工具的描述模型都要看一遍选错工具的概率随工具数量非线性增长。超过 20 个工具时加一层工具搜索或标签过滤——先缩小候选集再让模型决策。Function Calling 是大模型长出手的机制。在它出现之前模型只会说话。现在它能打电话、查数据库、订机票、写文件。但机制本身不复杂——就是一个五步循环靠 JSON Schema 约束、特殊 Token 切换、受控解码保底。把 Schema 写清楚把参数校验做严把工具数量的上限守好Function Calling 在生产环境里能跑得很稳。它不炫但它可靠。对于 Agent 工程来说可靠就是最稀缺的品质。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】