agent面试必备29-Tool Use / Tool Calling (工具调用)

📅 2026/7/4 4:29:50
agent面试必备29-Tool Use / Tool Calling (工具调用)
AI Agent 核心进阶Tool Use / Tool Calling (工具调用) 原理与面试指南如果说大模型LLM是大脑那么Tool Use工具使用/工具调用就是为这个大脑装上了可以触碰物理世界的“手和脚”。在上一篇我们了解了基础的 Function Calling函数调用。但在目前的 AI Agent 面试中面试官更喜欢用“Tool Use”这个词。这不仅是一个技术接口更是智能体Agent解决复杂问题的核心行为模式。这篇文章将用大白话带你搞懂 Function Calling 和 Tool Use 的细微区别、常见工程架构以及大厂极爱考的“工具调用容错机制”附带保姆级实战代码 一、 Function Calling vs Tool Use到底有啥区别很多初学者觉得这两个词是一回事但在资深面试官眼里它们代表了不同的业务抽象层级Function Calling函数调用偏向于底层 API 机制。比如 OpenAI 提供的tools参数它的本质是让大模型输出一段结构化的 JSON 数据。它只是一个单纯的“参数提取器”。Tool Use工具调用偏向于Agent 的高级行为。它不仅包含了让模型输出 JSON还包含了 Agent 拿到 JSON 后去执行代码、将报错信息捕获、将执行结果重新喂给模型、让模型继续思考的完整闭环即 ReAct 循环。 面试话术提炼“Function Calling 是模型具备的一种能力输出结构化参数而 Tool Use 是 Agent 利用这种能力去和外部环境交互的工作流Workflow。”⚙️ 二、 工具Tool的标准结构不管是 LangChain、LlamaIndex 还是自己手搓 Agent一个标准的“工具”都必须包含以下三个核心要素Name工具名称必须是唯一的通常只能包含字母、数字和下划线如web_search、python_interpreter。Description工具描述这是最重要的部分大模型完全依靠这段自然语言来决定什么时候该用这个工具。描述写得不好大模型就会“乱用”或“不用”。Schema / Arguments参数格式定义这个工具需要接收什么参数类型、是否必填等。️ 三、 面试必考Tool Use 的容错与防御机制在生产环境中把工具交给大模型是非常危险的。它可能会传错参数、漏传参数或者本地的 API 直接挂掉。如何保证系统不崩溃这是面试的重中之重。大厂核心防坑策略绝不让大模型直接执行危险操作对于删库、付款等敏感 Tool必须在执行层加入HITLHuman-In-The-Loop人工确认节点。捕获异常并“告诉”大模型如果本地代码报错了比如缺参数千万不要直接把程序抛出 Exception 挂掉要把报错信息Error Traceback转成字符串作为 Tool 的Observation观察结果返回给大模型聪明的大模型会自动向用户追问缺失的参数或者尝试换个参数重试。 四、 高频面试 QA 实战演练Q1各大模型厂商在 Tool Use 的底层实现上有什么区别标准答案OpenAI体系主要通过底层的 JSON Schema 强制约束返回特定的tool_calls对象。Anthropic (Claude)早期和部分开源模型更倾向于使用XML 标签如tool_use.../tool_use来进行工具调用。在工程落地时我们通常会使用统一的中间件如 LangChain 的tool装饰器来屏蔽这些底层模型的 API 差异。Q2如果系统里有 100 个工具每次提问都要把 100 个工具的描述都发给大模型吗标准答案高阶题绝对不行这会导致 Token 严重超载且大模型的注意力会分散导致选错工具。正确的架构是“工具检索Tool Retrieval”把所有工具的描述Description向量化存入向量数据库。当用户提问时先在向量库里检索出 Top-5 最相关的工具然后再把这 5 个工具发给大模型做最终决策。Q3Agent 调用工具陷入“死循环”怎么办比如模型一直传错同一个参数标准答案必须在系统层面设置硬性拦截机制设置最大迭代次数max_iterations比如超过 5 次调用同一个工具失败强制中断并回复用户“系统遇到技术困难”。在工具执行层维护一个状态机如果检测到连续两次传入完全相同的错误参数直接在本地截断强制要求模型向用户求助。 五、 面试加分代码手搓一个带容错机制的 Agent Tool在面试中用 Python 写一个优雅的 Tool 装饰器并展示“如何优雅地把报错信息扔回给大模型”会让你显得极具工程经验。importjsonimporttracebackfromtypingimportCallable,Any# # 1. 定义一个通用的工具类 (Tool Wrapper)# classAgentTool: 包装本地函数的工具类专门处理异常并与 LLM 交互 def__init__(self,name:str,description:str,func:Callable):self.namename self.descriptiondescription self.funcfunc# 真实要执行的 Python 函数defexecute(self,**kwargs)-str: 执行工具的核心逻辑包含面试必考的“容错捕获机制” print(f [执行工具]{self.name}| 传入参数:{kwargs})try:# 尝试执行本地真实的函数resultself.func(**kwargs)# 无论结果是什么都转成字符串因为大模型只认字符串文本returnjson.dumps({status:success,result:result},ensure_asciiFalse)exceptTypeErrorase:# 面试亮点参数传错了不要崩溃把报错信息返回给大模型error_msgf参数类型错误或缺失必需参数:{str(e)}。请检查你生成的参数并重试。print(f⚠️ [工具报错]{error_msg})returnjson.dumps({status:error,message:error_msg},ensure_asciiFalse)exceptExceptionase:# 捕获其他所有未知的业务异常error_tracetraceback.format_exc()returnjson.dumps({status:error,message:f工具执行遇到内部错误:{str(e)}},ensure_asciiFalse)# # 2. 定义真实的业务函数# defsearch_stock_price(symbol:str,date:strtoday)-float:模拟查询股票价格的函数# 模拟一个常见的业务报错用户没传必填参数或者参数格式不对ifnotisinstance(symbol,str)orlen(symbol)0:raiseValueError(股票代码(symbol)不能为空且必须是字符串)# 模拟查库返回结果mock_db{AAPL:150.5,TSLA:200.1}ifsymbolinmock_db:returnmock_db[symbol]else:raiseKeyError(f数据库中未找到股票代码:{symbol})# # 3. 实例化我们的 Tool并模拟 Agent 执行流# stock_toolAgentTool(namesearch_stock_price,description查询指定股票代码的实时价格必须传入 symbol 参数。,funcsearch_stock_price)if__name____main__:# --- 场景 1大模型很聪明传对了参数 ---print(--- 场景 1正常调用 ---)# 假设这是大模型通过 JSON 解析出来的参数字典llm_generated_args_1{symbol:AAPL}observation_1stock_tool.execute(**llm_generated_args_1)print(f返回给 LLM 的观察结果 (Observation):{observation_1}\n)# --- 场景 2大模型犯蠢了传错了参数名字 (面试核心展示点) ---print(--- 场景 2大模型传错参数 ---)# 假设大模型幻觉了把 symbol 传成了 company_namellm_generated_args_2{company_name:Apple}observation_2stock_tool.execute(**llm_generated_args_2)print(f返回给 LLM 的观察结果 (Observation):{observation_2}\n)# 面试讲解要点# 告诉面试官“在场景 2 中由于参数不对Python 会抛出 TypeError。# 但由于我们的 AgentTool 做了 try-except 封装程序并没有崩溃。# 我们把错误文本转成了 JSON 扔回给大模型。# 大模型看到 参数类型错误 的提示后它会在下一个回合中自我纠正Self-Correction重新输出正确的 {symbol: AAPL}”