5、Tools、Function Calling 与 Agent
Q5-1. ReAct 模式是什么?它解决了什么问题?
ReAct 的价值在于把“推理”和“行动”串起来,让模型不只是想,还能基于外部观察不断调整下一步。
它通常表现为 Thought -> Action -> Observation 的循环。模型先做当前判断,再决定调用什么工具,然后根据工具返回的结果更新判断,直到任务完成。相比只靠一次性生成,ReAct 更适合不确定路径、多步决策和外部信息依赖强的任务。
这里还需要补充一个重要点:现代 Tool Calling Agent 不一定会把 Thought 明文展示出来。实际代码中更常见的是 AIMessage.tool_calls、工具执行结果和下一轮消息。因此,更准确的理解方式是:ReAct 更接近一种工作机制,而不只是某个固定 Prompt 模板。
工程上要注意,ReAct 的优势是灵活,但代价是链路更长、成本更高、调试更复杂,所以并不是所有场景都值得上完整循环。
常见追问:
- Chain of Thought(CoT)是什么?它为什么能提升复杂推理题的效果?
- CoT 和 ReAct 的区别是什么?什么时候只用 CoT 就够了,什么时候要升级到 ReAct?
重要度:高频(出现次数:3次) | 难度:基础
**考察点:**Agent 运行范式理解。
对应章节:21 Agent智能体 §3、Agent 工作原理(V0.3);17 Tools工具调用 §2、工具调用的工作方式
Q5-2. Tool、Function Calling、Agent 三者是什么关系?
Tool 是能力单元,Function Calling 是调用机制,Agent 是把模型、工具、状态和决策流程组织起来的运行模式。
Tool 解决“能做什么”,Function Calling 解决“怎么发起结构化调用”,Agent 解决“如何围绕目标多轮地决定要不要调用、调用谁、调用几次”。所以 Tool 不等于 Agent,单次 Tool Calling 也不一定等于 Agent。
在真实项目里,很多需求只需要 Tool Calling,不一定要上完整 Agent。只有当任务需要多步规划、反复决策和状态推进时,Agent 才值得引入。
常见追问:
- 单工具助手算不算 Agent?
- ReAct 和 Function Calling 什么关系?
- Tool 设计的最小粒度应该是什么?
重要度:必刷(出现次数:2次) | 难度:基础
**考察点:**概念拆分是否清楚。
对应章节:17 Tools工具调用 §1、Tools 简介;21 Agent智能体 §6、小结:Agent、Tool、Function Calling、RAG、MCP 的区别与联系
Q5-3. 一个 Agent 应该如何设计?它通常由哪些核心组件构成?
如果按最小理解版概括,可以写成:Agent = 模型 + 工具集 + 运行循环 + 当前状态。
- 模型:负责理解目标、分析当前局面、决定下一步。
- 工具集:负责提供外部能力,比如搜索、数据库、文件系统、业务 API。
- 运行循环:负责让系统不是只回答一次,而是能“想一步、做一步、看结果、再决定下一步”。
- 当前状态:负责保存消息、工具返回、中间结果和线程上下文。
在这个最小骨架之上,记忆、规划、反思、多智能体协作都可以继续往上叠,但它们更适合作为“扩展能力”来理解,而不是每个 Agent 一上来都必须全部具备。
如果从工程设计看,一个可落地的 Agent,重点应控制五件事:
- 目标和职责:一个 Agent 解决什么问题,要尽量单一,不要什么都做。
- 工具边界:只暴露完成任务真正需要的能力,避免给模型一把通吃的权限。
- 状态设计:当前任务进展、中间结论、消息历史放在哪里,要显式设计。
- 停止条件:什么时候继续、什么时候澄清、什么时候转人工、什么时候结束,不能模糊。
- 治理能力:日志、Trace、重试、超时、审计、人工接管都要补齐。
概括来说:Agent 设计的重点不是“堆更多能力”,而是围绕 模型、工具、循环、状态 四条主线,把系统做得更可控、更可追踪、更能稳定交付结果。
常见追问:
- 在构建一个复杂 Agent 时,你认为最主要的挑战是什么?
- 为什么很多 Agent 不是能力不够,而是状态、边界和治理没设计好?
重要度:必刷(出现次数:2次) | 难度:中等
**考察点:**Agent 架构能力,而不是停留在概念层。
对应章节:21 Agent智能体 §1、Agent 简介;21 Agent智能体 §6、小结:Agent、Tool、Function Calling、RAG、MCP 的区别与联系
Q5-4. Function Calling 的基本原理是什么?
Function Calling 的核心分工,可以概括成一句话:模型负责决策,程序负责执行。
更完整地说,这条链路通常是:
- 宿主程序把工具的
name、description、参数 schema 一起发给模型。 - 模型判断要不要调用工具,如果要,会先返回结构化的
tool_calls,而不是直接给最终自然语言。 - 宿主程序读取
AIMessage.tool_calls,真正去执行 Python 函数、HTTP API、数据库查询或业务服务。 - 程序把执行结果封成
ToolMessage或等价消息,再交回模型。 - 模型基于工具结果生成最终答复。
所以 Function Calling 不是模型自己去调 API,它只是生成“调用哪个工具、传什么参数”的结构化意图。真正的鉴权、参数校验、超时、幂等、重试和安全控制,仍然都在宿主程序这一层。
如果要答得更工程化,还需要补一句:Function Calling 解决的是“模型如何表达调用意图”,不解决“工具是否安全、是否允许调用、调用失败怎么兜底”这些问题。
常见追问:
- Function Calling 和文本解析调用有什么区别?
- 为什么生产环境更推荐原生 Tool Calling?
- 工具执行失败怎么处理?
重要度:必刷(出现次数:1次) | 难度:中等
**考察点:**是否理解模型和宿主程序的职责边界。
对应章节:17 Tools工具调用 §1、Tools 简介;17 Tools工具调用 §2、工具调用的工作方式
**来源:**腾讯AI后台工程师一面(实际大厂面试题)
Q5-5. 设计 Tool 时最值得重视的工程原则是什么?
最值得重视的四点是:单一职责、明确 schema、可观测、可失败。
单一职责意味着一个 Tool 只做一件清晰的事,避免“大而全万能工具”。明确 schema 是为了让模型更稳定地理解参数含义。可观测意味着每次调用都要能追踪请求、参数、耗时、结果和错误。可失败意味着工具必须有超时、异常码、重试策略和降级逻辑,而不是假设一定成功。
如果 Tool 要连业务系统,还要加权限校验、幂等控制和审计日志。因为工具一旦从“查天气”变成“发消息、下工单、写数据库”,风险等级就完全不同了。
重要度:高频(出现次数:1次) | 难度:中等
**考察点:**是否有把工具接到生产系统的经验意识。
对应章节:17 Tools工具调用 §3、自定义 Tool;17 Tools工具调用 §4、参数 schema:为什么要配合 Pydantic
Q5-6. 如果让你实现一个“查天气、查新闻”的 AI 助手,你会怎么设计?
这类题在面试里更推荐先做场景判断,再谈方案。像查天气、查新闻这种需求,核心不是复杂规划,而是“意图识别 + 工具调用 + 结果整合”。
一个比较稳的实现通常包括四层:
- 输入与路由层:先判断用户是查天气、查新闻,还是两者都要。必要时抽取城市、时间、新闻主题等参数。
- 工具层:把天气查询和新闻检索分别封成清晰的 Tool,定义好 schema、参数说明、异常返回和超时策略。
- 调度层:先用 Function Calling 或轻量 Agent,让模型决定调用哪个工具、怎么传参、要不要串联多个工具。
- 输出层:把工具结果做统一整理,比如天气给关键字段,新闻给摘要和来源,最后再由模型生成自然语言回复。
如果需求只是单轮查天气、查新闻, Prompt + Function Calling 往往就够了,不一定要上完整 ReAct Agent。只有在需求升级成“先查天气,再根据天气推荐本地新闻,再继续追问某条新闻细节”这种多步动态链路时,Agent 的价值才会更明显。
工程上需要特别关注三点:工具描述要清楚,避免模型乱调;外部 API 要有降级和超时;结果输出最好带来源或关键字段,避免模型把工具结果又二次编造一遍。
重要度:高频(出现次数:1次) | 难度:中等
**考察点:**能否把一个简单助手拆成“意图、工具、调度、输出”四层,而不是一股脑说上 Agent。
对应章节:17 Tools工具调用 §5、天气助手实战;21 Agent智能体 §5、实操与案例
**来源:**腾讯AI后台工程师一面(实际大厂面试题)
Q5-7. 什么是“工具幻觉”?工程上怎么缓解?
工具幻觉指的是:模型调用了不存在的工具、传了不合理的参数,或者在只该读数据时却试图触发写操作。
这类问题在工具数量多、描述模糊、schema 不清晰时特别常见。模型有时不是“不会用工具”,而是“对工具边界理解错了”。
工程上通常会这样兜底:
- 工具注册表白名单:不存在的工具名直接拒绝。
- schema 强校验:参数类型、必填项、枚举值都要在运行时校验,不信任模型返回。
- 工具集收敛:按场景暴露最小工具集,别让模型在几十个相近工具里乱猜。
- 描述清晰:工具名、description、参数含义要能明显区分读写边界和适用场景。
- 高风险确认:涉及发消息、写数据库、发工单、下单等副作用动作,必须审批或二次确认。
- 失败反馈:把错误原因回传给模型,让它有机会修正,但要限制重试次数,避免死循环。
可以概括为:Tool Calling 不是“接上就行”,而是要让模型“调得准、调得住、调错了也出不了大事”。
重要度:高频(出现次数:1次) | 难度:中等
**考察点:**对 Tool Use 稳定性和风险控制的理解。
对应章节:17 Tools工具调用 §6、从课程案例走向真实项目;17 Tools工具调用 §4、参数 schema:为什么要配合 Pydantic
Q5-8. Function Calling 和“让模型输出 JSON 再自己解析”有什么区别?
两者表面上都像“模型输出结构化结果”,但稳定性和工程边界差别很大。
- 让模型输出 JSON,更接近在 Prompt 层提出要求。它简单、通用、起步快,但模型一旦多说一句自然语言、少一个字段、类型写错,程序端就要自己兜底。
- Function Calling 更接近协议级结构化输出。模型不是随便返回一段文本,而是明确返回工具名和参数,宿主按约定解析和执行,可靠性通常更高。
因此,在生产环境中通常这样判断:
- 如果只是抽取字段、做轻量结构化返回,而且平台原生能力有限,先用 JSON + parser。
- 如果要进入真实工具调用、外部系统编排、副作用执行,优先用原生 Function Calling 或等价 Tool Use 协议。
更关键的区别还在于职责边界。JSON 解析更接近“你让模型尽量长成这个格式”;Function Calling 更接近“模型和宿主之间有一层明确契约”。这层契约越清楚,后面的校验、审计、重试和观测就越好做。
常见追问:
- 什么时候 JSON + parser 已经够用?
- 为什么 Function Calling 更适合接生产系统?
- 如果平台没有原生 Function Calling,怎么尽量把 JSON 方案做稳?
重要度:中频(出现次数:1次) | 难度:中等
**考察点:**结构化输出和工具调用之间的协议级差异理解。
对应章节:14 输出解析器 §4、结构化输出;17 Tools工具调用 §2、工具调用的工作方式
Q5-9. 当工具很多时,如何控制上下文长度和调用稳定性?
工具一多,问题通常不再是“会不会调工具”,而是“会不会在一堆相似工具里选错、调错、调得越来越乱”。
比较稳的做法通常有四类:
- 分层暴露:先按业务域拆成搜索类、数据类、执行类、写操作类,不要一次把所有工具都暴露给同一个 Agent。
- 动态选择:先做 Tool Retrieval 或路由,只把 Top-N 个最相关工具描述放进当前上下文,而不是全量列出来。
- 工具聚合:把过细的底层 API 封装成更高层的业务动作,减少模型在几十个相近函数里猜名字。
- 描述治理:工具名、description、参数说明里要明确“什么时候用、什么时候不用、有没有副作用”。
如果再往前走一步,生产里还可以把“工具选择”本身做成一个独立阶段,比如先做意图分类或子域路由,再进入具体工具调用。这样既能控上下文长度,也能降低工具幻觉和误调用概率。
可以概括为:工具多不是问题,关键是别让模型在一个没有层次的工具海里盲选。
常见追问:
- 工具太多时,应该优先做路由还是优先改工具粒度?
- Tool Retrieval 和普通知识检索有什么区别?
- 为什么业务动作级工具通常比原子 API 更适合模型调用?
重要度:中频(出现次数:1次) | 难度:较难
**考察点:**多工具场景下的上下文治理和工具编排能力。