☰
大模型Function Call实战:原理、Demo与面试避坑指南
2026/10/21 8:01:34 网站建设 项目流程

面试官问到你Function Call的时候,十有八九不会只问一句"你了解吗",而是像连环炮一样往下追:函数描述怎么写、模型怎么选择工具、参数错了怎么办、多轮对话怎么接上下文、和Agent有什么区别。这不是刁难,是因为Function Call是大模型从"聊天机器人"走向"能办事的系统"最关键的一环,凡是做应用落地的人都绕不开它。这篇文章我把自己准备面试时整理的全套思路、可复现的Demo代码、还有实际踩过的坑一次性写出来,适合正在准备大模型岗位面试的开发者,也适合刚接触工具调用想系统理解原理的同学。

1. 面试官为什么逮着Function Call不放

1.1 大模型的"高智商,低执行力"困境

先说一个常识:大模型本质上是一个靠海量文本训练出来的"语言预测器",它的强项是理解和生成自然语言,但有几个天然短板。

第一,它没有实时数据。你问它"今天北京气温多少",如果训练数据里没有这一条,它只能靠猜,甚至胡编一个数字出来,这在我们行业里叫幻觉。第二,它不能执行代码。让它算一道复杂的积分它能把推导过程写得头头是道,但你真让它去调用一个数据库、发一封邮件、操作一个订单系统,它做不到。第三,它不能主动连接外部世界。模型就是一个跑在GPU上的参数集合,没有网络权限,也没有文件句柄,它唯一的输出通道就是token。

那怎么让模型去"办事"?答案就是Function Call。它的思路很朴素:既然模型不能执行代码,那就让它学会"表达意图",由我们自己的程序去真正执行。比如模型说"我想调用get_weather函数,参数是city=北京",然后你的代码去请求天气API,再把结果塞回给模型,让模型基于真实天气数据组织回答。说白了,Function Call就是给大模型装了一双手,让它可以"指使"外部系统干活。

1.2 面试官真正想考察的四个层次

我后来自己也模拟过面试官出题,发现对方考察Function Call并不是为了让你背概念,而是顺着四个层次往下问的。

第一层是"你知不知道它解决什么问题"。答不上来这一点的人,基本上连基本场景都没搞明白,面试直接下了一个档次。

第二层是"你知不知道协议细节"。这里的协议不是网络协议,而是模型层面约定的一套JSON格式:函数怎么声明、参数用什么Schema、模型返回哪个字段表达调用意图、执行结果怎么回填。面试官会追问你"如果缺少参数怎么办""description写不好会怎样",考察的就是你对这套机制的敏感度。

第三层是"你有没有在生产环境踩过坑"。Function Call在Demo里跑通很容易,但到了真实业务里全是细节:上下文长度管理、工具调用失败重试、权限校验、函数结果截断、并行调用,每一样都是问题。面试官问"你遇到什么坑"就是在看你有没有真刀真枪做过。

第四层是"你能不能把它放入更大的架构里"。比如Function Call和RAG的关系、在Agent里扮演什么角色、如何做评测和监控。这考察的是系统设计能力,而不只是会用API。

明白这四层,你就知道后面我拆解的内容为什么这样编排了:先原理、再追问、再实战、再避坑,每一步都是在给这四个层次喂答案。

2. Function Call运行原理一次讲透

2.1 三块积木:函数声明、模型决策、应用执行

把Function Call拆到最底层,就是三块积木。

第一块是函数声明。你需要把"模型可以调用哪些函数"告诉它,这份声明用JSON Schema格式描述,包含函数名、功能描述、参数名称、参数类型、参数含义、是否必填、枚举值等。注意一个关键点:模型看不到你的函数体代码,它只读这份"说明书"。所以说明书写得到不到位,直接决定模型选得对不对、参数抽得准不准。

第二块是模型决策。当你把用户问题和函数声明一起发给模型之后,模型会在内部做一次"意图判断":这个问题需要调用工具吗?如果需要,调用哪个?参数怎么填?然后它输出一段结构化的JSON,比如"tool_calls"字段里写函数名和实参。此时模型并没有真正执行函数,它只是表达了"我建议这么调"。

第三块是应用执行。我们的代码收到模型输出的调用请求后,负责真正的执行:访问外部API、查询数据库、判断权限、拿到结果。执行完成之后,把结果作为一条新的消息拼回对话历史,再次发给模型,让模型用这个真实结果组织最终回答。这种"模型动嘴、代码动手"的分工,是Function Call的灵魂。

2.2 一次完整调用的六个步骤

用文字走一遍完整链路,面试让你说流程时可以直接背这个顺序。

假设用户问:北京今天需要带伞吗?

第一步,应用准备函数声明,定义一个get_weather函数,参数是city和date,描述里写明"根据城市名查询天气"。

第二步,把用户问题和函数声明一起作为请求发给模型。这一步通常带上系统提示词,比如"如果需要获取实时信息,请调用可用工具"。

第三步,模型判断"查天气"这件事可以交给get_weather,于是输出一个结构化调用指令:函数名get_weather,参数city为"北京"。它还会附带一段给用户的话,比如"我来查一下"。

第四步,应用层解析这个输出,校验函数名白名单,检查参数是否完整,然后真正调用天气API,拿到"多云、24度、下午有雨"这样的结果。

第五步,把函数执行结果作为role为tool的消息拼回历史,连同原始用户问题、模型上一步的调用意图一起,再次发给模型。

第六步,模型看到真实天气数据,生成最终回答:"北京今天下午有雨,出门建议带伞。"整个链路结束。

这六步里,最容易被新手忽略的是第五步。很多人以为调用完工具直接把结果返回给用户就完事了,结果模型根本不知道刚才发生了什么,答非所问。正确做法永远是把工具结果放回对话上下文,让模型"看见"结果之后再开口。

2.3 Function Call与普通问答、JSON Mode的区别

面试的时候几乎必被问到:它和普通问答有什么区别?和JSON Mode又有什么区别?我用一个表格说清楚。

对比项普通问答JSON ModeFunction Call
模型输出形式自由自然语言强制JSON格式文本专门字段表达调用意图
是否触发外部动作不触发不触发,只是输出结构化文本由应用层执行真正的函数
典型场景聊天、写作、翻译信息抽取、结构化输出查天气、操作数据库、调用API
输出确定性低中,格式固定但内容可变高,必须匹配已声明函数
失败模式答非所问JSON语法错误函数名错、参数缺、执行失败

补充一个容易混淆的点:JSON Mode只是让模型输出合法的JSON文本,模型自己不会去执行什么,你的代码拿到JSON后做什么完全由你决定。而Function Call在协议层面就已经把"调用工具"变成了一个一等公民,模型输出的是一个可执行的调用意图,二者定位完全不同。如果面试官问你"在什么场景下选JSON Mode而不是Function Call",你可以说:当只需要从文本中抽字段、不需要触发真实动作时,JSON Mode更轻量;当需要模型决定调用哪个工具并触发系统动作,就选Function Call。

3. 面试连环炮:十连问与参考回答

3.1 函数描述写不好会怎样

这个问题考察的是你对"函数选择机制"的理解深度。模型在决定要不要调用函数、调用哪个函数时,主要靠语义匹配。它把函数名、description、参数名和参数含义这些文本,和用户问题的语义做相似度匹配。所以description就是模型做路由决策的核心依据。

如果description写得过于笼统,比如只写"查询信息",模型看到任何一个"查一下"的请求都可能选中这个函数。如果description里全是功能罗列而没有触发场景,模型在边界情况下就容易乱选。参数描述同理:参数名是city但你没说明它是"城市名,支持中文和拼音",模型就可能把"北京"以外的其他内容硬塞进city字段。

我自己的经验是,描述一个函数时用"动词开头 + 触发条件 + 返回内容"这个句式。比如:查询指定城市当前天气,当用户询问某地的气温、降水、风力时使用,返回实时天气数据和未来三日预报。这样既有触发场景,又有能力边界。面试时能说出这一层,面试官会立刻觉得你不是只会调API。

3.2 模型怎么在多个函数之间做选择

这个问题开始有点压力了。嵌入的函数的数量越来越多时,函数描述在Prompt里占据的token也越来越大,模型的选择准确率会下降。原因在于模型的注意力被分散了,相近语义的函数会出现竞争。比如你同时声明了查询天气和查询空气质量,用户问"北京空气怎么样",模型可能犹豫不决。

面试时你可以分三层答。第一层,模型本质上在做一次"意图分类":先判断用户问题是否需要工具,再在候选函数里做相似度排序。第二层,工程上要控制候选函数规模,最好控制在五到十个以内,超过这个量就要考虑加一层函数路由,先用一个轻量分类器缩小候选范围。第三层,函数之间要在描述里刻意做差异化,明确边界。比如天气函数写"气温降水",空气函数写"PM2.5和空气质量指数",避免两个函数语义重叠。

我实际做过的项目里,一个Agent平台接了几十个工具,直接在系统提示词里全部塞进去效果很差。后来我加了一道预路由:先用关键词和向量检索把候选工具缩小到三个,再交给大模型决策,准确率从60%多直接拉到90%以上。这个案例在面试里非常加分,它说明你不是只懂原理,还懂规模化后的工程解法。

3.3 模型说想调用函数,但参数给少了怎么办

这是一个非常实战的问题。模型的参数遵循能力不是100%,即使你在JSON Schema里把某个参数写成required,它也可能漏掉。面试官问你这个问题,其实就是想知道:你有没有做防御性编程,还是天真地把模型输出当成了圣旨。

标准答案分四步。第一,模型输出解析后,立刻用JSON Schema做一次校验,检查必填字段是否存在,类型是否符合要求。第二,如果必填参数缺失,不要直接拿空值去执行函数,而是把校验错误信息作为系统反馈塞回上下文,让模型重新生成一次调用请求。第三,设置最大重试次数,比如两到三次,超过次数就向用户坦白"这个信息我拿不到,请补充XX参数"。第四,日志里要记录每次参数校验失败的样本,定期分析是description写得不清楚,还是模型本身经常漏字段。

在代码层面,你需要用一个校验器而不是手写一堆if。把声明函数的那份JSON Schema同时作为运行时校验标准,一份Schema两处用,保证声明和执行的一致性。这个问题回答好了,面试官会觉得你具备上线意识。

3.4 模型幻觉,凭空调用不存在的函数怎么办

面试官喜欢用"极端情况"来压你。模型幻觉并不罕见,它可能编一个函数名,也可能调了一个存在的函数但参数是胡编的。这里面有个方向性问题:模型的输出空间天然是开放的token序列,所以"模型不会调用未声明函数"这个说法并不完全准确,必须在协议之外再加一道护栏。

我的方案是白名单校验。模型返回的tool_calls后,我们会解析出函数名,然后和已注册函数列表比对,不在列表里就直接丢弃,并附带提示让模型重新生成。参数层面的幻觉还要再校验枚举值、取值范围。比如一个函数接受"订单状态"参数,枚举是created、paid、shipped,模型输出一个delivered,这种属于参数幻觉,要靠枚举校验打回。

还有一个实践经验:模型在不确定的时候更倾向于调用工具,而不是承认自己不知道。所以你可以在系统提示词里加一句"仅当能明确匹配用户意图时才调用工具,否则直接回答"。这句话能显著减少瞎调用。

3.5 多轮对话中函数调用的历史怎么塞进上下文

这是个必考题,而且答得好不好最能拉开差距。很多人以为Function Call就是"一问一查一答",但实际对话是多轮的:用户先问天气,再问"那明天呢",再问"适合跑步吗",每一步都可能触发工具调用。

关键点是:每一次工具调用的输入和输出,都要以消息的形式进入下一轮上下文。主流接口里,工具执行结果会以role为tool的消息拼接,并且通常要带上对应的tool_call_id,这样模型才能把函数结果和那次调用请求关联上。如果不带关联信息,模型会分不清这个结果到底是哪来的。

上下文长度是另一个大坑。工具返回结果可能很长,比如一个订单查询API返回几百行JSON,多轮累积之后Prompt直接爆掉。我的实践做法是三层,第一层控制历史轮数,只保留最近N轮;第二层对工具结果做结构化摘要,而不是原样塞进去;第三层对于超长结果,只提取关键字段再拼回上下文。面试官问到这里时,你可以补一句"工具结果是外部世界的压缩表示,所以我会尽可能让它精简,因为模型读的是token,不是原始数据库"。

3.6 Function Call、Agent、ReAct之间到底是什么关系

这个问题考察的是概念边界,答好了显得系统性强。Function Call是模型的一种输出能力,它定义了模型如何表达"我要调用外部工具"这个意图,本质上是一个协议。ReAct是一种推理模式,完整的名字是Reason and Act,指模型在思考、行动、观察结果之间循环,每一轮都先推理下一步该干什么,再行动,再根据结果继续推理。Agent则是一个更完整的决策系统,它把目标拆解、工具调用、记忆管理、自我反思组合在一起,去完成一个多步骤任务。

用一句话概括:Function Call是"手",ReAct是"脑回路",Agent是"装上了手和脑回路的完整人"。面试时可以这样展开:一个Agent内部可能用ReAct模式驱动,每一步如果需要触发外部能力,就通过Function Call格式输出工具调用请求。所以三者不是同层概念,而是协作关系。

这里有个加分的细节:早期ReAct的实现里,工具调用是通过让模型输出特定格式的文本(比如"Action: get_weather\nAction Input: {'city': '北京'}")来实现的,解析比较脆弱。Function Call把它变成了结构化的、协议化的字段,让解析更稳定。面试官如果问"Function Call的优势在哪",你可以对比这一层。

3.7 延迟和token成本怎么优化

做工程就要面对成本。第一个痛点是所有函数描述都要写进Prompt,函数一多token成本和首token延迟都上去了。第二个痛点是多轮调用,一次工具任务可能对话三轮、四轮,每一轮都要带上历史,延迟线性增长。

我是这么优化的。第一,函数路由前置,用小模型或向量检索做候选过滤,避免大模型每次读二十个函数的描述。第二,并行调用,如果用户问"北京和上海的天气",可以一次输出两个tool_calls,应用层并发请求两个API,再把两个结果一起回填。很多接口支持一次请求里带多个tool_calls,你要主动用起来。第三,结果摘要和缓存,短期内重复的请求直接命中缓存,函数调用结果也可以复用,省掉重复调用。第四,如果只需要做工具路由,可以用一个更小更快的模型来判断意图,再由大模型基于选中的工具生成最终回答,这是实践里性价比很高的方案。

面试时补充一句实测数据更有说服力:我在某个项目里把函数候选从二十个压缩到三个,首token时间降了将近一半,准确率反而因为注意力更集中而上升。

3.8 安全与权限怎么设计

这是架构师视角的问题。Function Call等于把模型暴露给了外部系统,模型一旦被恶意Prompt注入,可能诱导它调用危险函数。安全设计不能只在模型层面解决,要在外部系统立规矩。

第一,最小权限原则。给模型声明函数时,只暴露当前用户场景真正需要的工具,不要把所有内部系统接口全部挂上去。第二,身份与权限校验在应用层执行。模型只是传递调用意图,真正执行前,你的代码要校验"这个用户有没有权限调用这个函数、操作这条数据"。第三,高危操作要加人工确认。比如转账、删除、发消息,函数执行前先返回一个待确认状态,由用户点击确认后再真正执行。第四,所有工具调用要记录审计日志,包括谁触发的、传了什么参数、返回了什么结果,方便事后追溯。

面试官如果继续追问"提示词注入怎么防",你可以说:模型可能被用户话术诱导去调用某个函数,所以对函数的参数值也要做过滤,不能直接拼接进SQL、不能直接拿来做系统命令,所有参数要先走一遍安全校验。这一答就把问题从模型层拉到了系统层,面试官会认为你有生产级的安全意识。

3.9 如何评测Function Call做得好不好

评测这块很多人没想过,但面试官后面一定会问。Function Call的评测我建议拆成三个维度。第一是选对率,给定用户意图和一批候选函数,模型选中的函数是不是正确的那个。第二是参数准确率,函数选对了,但参数值抽取得对不对,比如城市名是不是抽进了city字段,有没有把别的实体的词硬塞进来。第三是端到端完成率,把工具执行、结果回填、最终回答串起来,看用户问题是否真的被圆满解决,这一步最接近业务指标。

数据集构造也有方法论。需要准备一批"问题-目标函数-目标参数"的三元组,覆盖每个函数的正常场景、边界场景和易混场景。特别要造一批"不需要调用工具"的负样本,因为模型容易过度调用工具。评测跑起来之后要定期回归,因为模型版本一更新,函数调用的表现很可能波动。面试时能说出"负样本"和"定期回归"这两个词,就能证明你做过正经评测。

3.10 Function Call和RAG怎么配合

RAG和Function Call经常被放在一起问。区别可以用一句话说清楚:RAG解决的是"模型不知道"的问题,它去知识库里检索相关资料给模型参考;Function Call解决的是"模型做不到"的问题,它去调用系统动作或实时接口。一个偏向读知识,一个偏向动手执行。

在真实系统里两者经常组合。比如一个售前客服机器人,用户问"你们产品的退货政策是什么",先走RAG从知识库检索政策文档;用户接着问"帮我查一下我的订单到哪了",这就得Function Call调用订单查询API。所以一个完整业务系统往往是"RAG + Function Call"双引擎。

组合时有个顺序问题:有的场景先检索再决定是否调用工具,有的场景先调用工具再基于结果继续推理。我在项目里的做法是把RAG也封装成一个"工具",名字叫search_documents,这样模型可以统一决策:是查知识库、调订单API,还是先查知识库再调订单API。这种"一切皆工具"的设计能让决策逻辑统一,代码结构也清晰。面试提到这个思路,是很加分的。

4. 最小可跑Demo:跟着做就能放进简历

4.1 环境准备与工具声明定义

原理聊再多,不如一个能跑的Demo有说服力。我自己面试前就手写过一遍完整代码,这里把最小可跑版本写出来,用的是Python和一个主流的OpenAI兼容接口。主要依赖就一个openai库,安装好再把API地址和密钥填进环境变量。

先定义一个函数声明。假设我们要做一个天气查询工具,让模型学会调用它。函数声明的本质是JSON Schema,下面这段就是完整的声明结构:

tools = [ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市的当前天气,当用户询问气温、降水、风力、天气状况时使用", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名,支持中文和拼音,例如北京或beijing" } }, "required": ["city"] } } } ]

这段声明里有几个值得注意的点。一是type设置为function,这是当前主流接口约定的标记方式。二是description里明确写了触发场景,模型只有在用户意图匹配"查询天气"时才会选中它。三是required标明了city必填,但这只是给模型的"建议",运行时仍要自己做校验,前面说过模型不一定100%听话。四是参数描述里给了格式示例,这些细节能明显提升参数抽取的准确率。

4.2 首次请求与工具调用解析

环境准备好之后,第一步是把用户问题和函数声明一起发给模型。这里我模拟用户问"北京今天有雨吗":

from openai import OpenAI client = OpenAI() messages = [{"role": "user", "content": "北京今天有雨吗?"}] response = client.chat.completions.create( model="your-model-name", messages=messages, tools=tools, )

请求发出去后,重点看返回结果里的tool_calls字段。如果模型认为需要调用工具,这个字段会包含一个列表,每个元素里有function.name和function.arguments,而arguments是一段JSON字符串。字符串里面就是模型抽取出来的参数,比如{"city": "北京"}。

新手容易在这里踩一个坑:拿到response后直接把它当成最终回答返回给用户。实际上这次返回只是"调用意图",模型还没有拿到真实天气数据,你要去执行函数而不是直接回答。正确定位是:这次response告诉你"模型想查北京天气",接下来该你动手了。

解析代码很简单:

tool_calls = response.choices[0].message.tool_calls if tool_calls: fn_name = tool_calls[0].function.name fn_args = json.loads(tool_calls[0].function.arguments) print("模型想调用:", fn_name, fn_args)

4.3 执行函数并回填上下文

解析完调用意图,就要真正执行函数。在真实项目里这里会有权限校验、参数校验、日志记录,但Demo里我们直接调用一个模拟函数就行:

def get_weather(city: str) -> str: data = { "北京": "多云,24度,下午有雨", "上海": "晴,28度" } return data.get(city, "暂无该城市数据")

执行得到结果后,把结果回填给模型。回填是Function Call里最关键的一环,必须用role=tool的消息,并且带上对应的tool_call_id,让模型知道这个结果对应刚才哪一次调用请求。

tool_message = { "role": "tool", "tool_call_id": tool_calls[0].id, "content": get_weather(fn_args["city"]), } messages.append(response.choices[0].message) messages.append(tool_message) final_response = client.chat.completions.create( model="your-model-name", messages=messages, tools=tools, ) print(final_response.choices[0].message.content)

这一步把两部分内容追加进了消息历史:一是模型上一次的回复本身,里面包含tool_calls信息;二是这次的tool结果消息。然后再让模型基于真实数据组织最终回答。输出会类似"北京今天多云,下午有雨,出门建议带伞",这才是完整的Function Call闭环。

4.4 Demo再进一步:处理参数缺失和报错

能跑通主流程只是第一步,面试如果只写到上面那一步,还是会被追问"缺参数怎么办""函数执行异常怎么办"。所以Demo里要补上防御逻辑。

参数缺失的兜底套路是把错误信息也拼回上下文,让模型重新生成调用请求,或者直接反问用户。伪代码如下:

if "city" not in fn_args: retry_messages = messages + [ { "role": "tool", "tool_call_id": tool_calls[0].id, "content": "参数校验失败:缺少city字段,请重新提供城市名" } ] # 重新调用模型,让它补全参数

函数执行异常同理,执行过程包一层try-except,执行失败时把异常信息作为tool消息回填。这样模型就知道了外部系统出了什么问题,可以回复用户"查询服务暂时不可用,请稍后再试",而不是让整个程序直接崩溃。

如果简历里写了Function Call相关项目,建议把这几段防御逻辑补上,并在面试时主动讲这段。因为能跑通主流程的人很多,能处理异常的人才是真正上过线的。

5. 实战高频坑位与排查心得

5.1 高频问题速查表

我把自己做过的一个工具调用平台里遇到的高频问题整理成了一张表,面试前扫一遍会有帮助。

现象可能原因排查方向
模型永远不调用函数系统提示词没说清楚可以调用工具,或函数描述与用户问题语义匹配不上检查系统提示词是否明确"需要时调用工具";尝试改写函数description
模型频繁瞎调用函数函数描述给了过多权限感,或负样本场景不足在描述里加"仅当XX时才调用";增加"不需要工具"的提示
参数总是抽错参数description太简单,没有给格式示例在参数description里加"例如:北京或beijing";用枚举限制取值
函数结果模型看不到忘了把tool消息拼回上下文,或tool_call_id没对上检查回填逻辑,确认role=tool且携带正确tool_call_id
多轮后上下文超限工具结果太长且全部保留对工具结果做摘要、截断,控制历史轮数
返回JSON解析失败模型输出被截断,或参数里混入了多余字符解析时做容错,截断时放弃该结果并重新生成
并行工具调用未生效没处理多个tool_calls条目遍历tool_calls列表,逐个执行后统一回填

排查工具调用问题有一个通用方法:把模型返回的完整JSON打印出来,人眼先看一遍。很多时候问题不在模型,而在你发给模型的函数声明写得有歧义,或者回填时消息顺序不对。先用最简单的一组数据和两个函数复现问题,再逐步增加复杂度,是最稳妥的排查路径。

5.2 三个容易忽略的细节

第一个细节是消息顺序。在把模型上一轮回复拼进历史时,必须保留message里的tool_calls字段,不能只提取content。如果后面拼接tool消息时丢了关联,模型就无法把函数结果和调用请求对上。这个顺序错误很隐蔽,不容易报错,但结果就是第二次生成的回答莫名其妙。

第二个细节是温度参数。温度调得越高,模型输出越随机,tool_calls里的参数就可能越不稳定。我自己实践时,工具调用的场景通常把温度压到0或者0.2。如果面试官问你为什么,你可以回答:工具调用本质上是结构化决策任务,不需要创造性,低温度能减少参数幻觉。

第三个细节是流式输出。开启stream之后,tool_calls不是一次性返回的,而是以增量片段的形式陆续到达,需要自己在代码里累积拼接每个delta的function.arguments片段,全部收完再做JSON解析。很多人在流式场景下解析参数失败,就是因为忽略了"增量"这件事。如果面试官问"流式模式下Function Call怎么处理",你能说出delta累积和结束后再解析,就已经超过大多数候选人了。

6. 面试官视角:这样回答Function Call更容易过

6.1 回答问题的黄金结构

面过一些想应聘大模型岗位的候选人之后,我总结出一个通用的回答结构,适用于几乎所有Function Call追问。不论问题多小,都按"结论先行、原理为证、实践兜底"三层来答。

第一层,先用一句话给出结论。比如问缺参数怎么办,直接说"应用层要自己校验,不能盲信模型输出,校验失败要让模型补充信息"。第二层,拆原理。说明为什么模型会漏参数:模型输出是概率性的token序列,JSON Schema的required只是一个软约束,不是硬保证。第三层,给出自己的实践案例或兜底方案。可以说"我在项目里会把Schema抽出来做运行时校验,并设置最大重试次数"。

这三层结构的好处是,哪怕你第一句话不够全面,但中间有原理支撑,最后有实践收尾,面试官能立刻判断出你是真懂还是背稿子。很多人答Function Call问题只停留在"调API""模型会生成tool_calls"这种表层,就是因为少了第二层和第三层。

6.2 加分动作与避雷清单

最后分享几个让回答显得更老练的加分动作。第一,主动说边界条件。讲到函数描述时,主动补充"函数描述既是路由依据也是token开销,所以描述要精确且简洁";讲到执行时,主动提"执行失败后的重试和回填"。边界条件说得越多,越像做过生产系统。

第二,主动把Function Call放回系统架构里谈。比如被问原理时,可以带一句"在Agent系统里,它承担的是工具调用能力和协议层设计";被问到评测时,说清楚三个维度并强调负样本。这些东西面试官不会直接打分,但会让整体印象上一个台阶。

避雷清单也很重要。一不要只背官方文档里的定义,那会让面试官觉得你只看了文档没上过手。二不要贬低模型的工具调用能力,说"模型经常乱调用所以不可靠"这类话容易显得你缺少调试能力,更好的说法是"模型工具调用是概率性的,需要通过声明优化和应用层校验来提高可靠性"。三不要过度堆砌术语,面试官问"什么是Function Call"你就先把一次完整链路讲清楚,不需要一上来就扯Agent、ReAct、评测框架,等对方追问再展开。

我在实际做项目中还有一个体会:Function Call的很多问题,根源并不在模型本身,而在于函数声明的设计质量、上下文管理的策略、异常兜底的完整度。所以面试前与其拼命背概念,不如亲手把一套包含校验、回填、重试的Demo跑通,再在面试时把踩坑过程讲出来,这种真实感是任何八股都给不了的。如果你正在准备面试,建议把我上面这套思路整理成自己的话,再配合动手实现,效果会好很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询