智能体面试准备十八Function Calling 全链路——Agent 真正动手的最后一公里前面讲了单 AgentReAct、多 AgentB15、安全B16、规划B17。但所有这些要落地都绕不开一个最基础也最关键的能力Function Calling函数调用——让 LLM 决定调哪个工具、传什么参数。这一篇把全链路从定义到生产跑通工具 schema 设计 → 模型决策 → 参数解析 → 执行 → 结果回填 → 并行调用与错误处理。每节给原理 → 代码 → 面试速答 高频追问。配合 B14MCP看刚好从单进程工具走到跨进程协议。一、Function Calling 在 Agent 链路里的位置它是 LLM 与外部世界之间的接口层用户意图 │ ▼ ┌─────────┐ ① 选工具填参 ③ 回填结果 │ LLM │◀────────────────┐ └────┬────┘ │ │ ② tool_call(JSON) │ ▼ │ ┌─────────┐ │ │ 执行器 │──▶ 真实工具/API │ └─────────┘ │ │ ④ observation │ └─────────────────────┘没它LLM 只能说有它LLM 才能做。二、工具 Schema怎么告诉模型有哪些工具用 JSON Schema 描述每个工具的元信息喂给模型{name:get_weather,description:查询指定城市当前天气,parameters:{type:object,properties:{city:{type:string,description:城市名如 北京},unit:{type:string,enum:[celsius,fahrenheit],default:celsius}},required:[city]}}关键原则description 写清楚什么时候用、参数怎么填模型靠它选工具。描述含糊会导致选错工具或漏填参数。三、模型决策与参数解析主流模型GPT-4o、Qwen、GLM 等原生支持 function calling返回结构化的 tool_callsimportopenai,jsontools[get_weather_schema,search_schema]# 上面的 JSON Schema 列表respopenai.chat.completions.create(modelgpt-4o,messages[{role:user,content:北京今天天气咋样}],toolstools,tool_choiceauto,# auto模型自选也可强制指定)msgresp.choices[0].messageifmsg.tool_calls:forcallinmsg.tool_calls:namecall.function.nameargsjson.loads(call.function.arguments)# 模型填的参数print(name,args)# get_weather {city:北京}面试速答tool_choiceauto 和强制指定有什么区别auto 让模型自己判断是否调用、调哪个强制如 {type:function,function:{name:x}}则模型必须调用指定工具常用于固定流程。四、执行器调用真实工具并回填把模型给的调用转成真实执行再把结果作为新消息回传给模型defdispatch(name,args):ifnameget_weather:returnreal_weather_api(args[city])ifnamesearch:returnreal_search(args[query])raiseValueError(funknown tool{name})# 把 assistant 的 tool_call 和 tool 结果都加入上下文messages[{role:user,content:北京今天天气咋样}]respopenai.chat.completions.create(modelgpt-4o,messagesmessages,toolstools)msgresp.choices[0].messagemessages.append(msg)# 必须保留带 tool_calls 的 assistant 消息forcallinmsg.tool_calls:resultdispatch(call.function.name,json.loads(call.function.arguments))messages.append({role:tool,tool_call_id:call.id,content:str(result)})finalopenai.chat.completions.create(modelgpt-4o,messagesmessages,toolstools)print(final.choices[0].message.content)# 自然语言回答注意tool 消息必须带 tool_call_id 且对应 assistant 的 call否则 API 报错。五、并行调用与错误处理生产必备5.1 并行调用模型可以在一次回复里返回多个 tool_call如查北京和上海天气callsmsg.tool_callsor[]results[dispatch(c.function.name,json.loads(c.function.arguments))forcincalls]# 用线程池并发执行真实工具缩短延迟fromconcurrent.futuresimportThreadPoolExecutorwithThreadPoolExecutor()asex:resultslist(ex.map(lambdac:dispatch(c.function.name,json.loads(c.function.arguments)),calls))5.2 错误处理与兜底defsafe_dispatch(call):try:returndispatch(call.function.name,json.loads(call.function.arguments))exceptExceptionase:# 把错误作为 observation 回传让模型自我修正如换参数/换工具returnfERROR:{type(e).__name__}:{e}。请修正参数或换工具重试。把错误回传而非中断模型往往能纠错例如把城市名拼写改对。六、常见坑与最佳实践坑现象对策参数 JSON 不合法arguments 不是合法 JSON用 json.loads 容错 让模型重生成工具描述含糊选错工具/漏必填写清 description required上下文丢 tool_call_idAPI 报不一致严格保留 assistanttool 消息对工具执行慢/超时整轮卡住超时熔断 并行 降级工具返回过大撑爆上下文截断/摘要后再回填面试速答为什么要把工具结果回填给模型而不是只执行因为 LLM 是无状态的它需要根据工具真实返回继续推理例如天气是雨建议带伞不回填模型就不知道结果、无法生成最终回答。七、面试速答 高频追问清单汇总速答 TOP 81. Function Calling 是 LLM 调外部工具的接口层含 schema→决策→解析→执行→回填。2. 工具用 JSON Schema 描述description 决定模型会不会选对。3. 模型返回 tool_callsname arguments JSON。4. 执行后必须以 roletool 且带 tool_call_id 回填上下文。5. 并行调用一次返回多个 call用线程池并发。6. 错误应回传 observation 让模型自我修正而非直接中断。7. tool_choiceauto 让模型自选也可强制指定。8. 坑JSON 不合法、描述含糊、丢 id、返回过大。追问清单- 模型有时不按 schema 填参、编造字段怎么约束- 几十上百个工具时全塞进 context 会爆怎么裁剪tool retrieval- Function Calling 与 MCPB14的关系MCP 解决了什么- 流式streaming场景下 tool_call 怎么逐步拼装- 如何防止模型陷入反复调用同一工具的死循环八、下一篇预告Function Calling 讲完动手的最后一公里Agent 基础能力感知-规划-行动-工具-安全基本闭环。后续可进入B19 RAG 评估或B20 可观测性 tracing/logging/评测把 Agent 从能跑推向可运维。评论区告诉我优先级。