news 2026/6/18 19:12:26

【实战踩坑】大模型多轮对话中 Function Calling 失效?原来是上下文(Context)管理出了锅!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【实战踩坑】大模型多轮对话中 Function Calling 失效?原来是上下文(Context)管理出了锅!

大模型 Function Calling 避坑:当你的 AI 助手“光说不练”时

前言

在开发基于大模型(LLM)的智能助手时,Function Calling(工具调用)是连接模型与外部世界的核心能力。最近在调试一个控制设备音量的场景时,遇到一个非常诡异的 Bug:

  • 第一轮对话:用户说“声音大一点”,模型准确识别并调用了set_volume工具,执行成功。
  • 第二轮对话:用户接着说“声音调小一点”,模型却不再调用工具,而是直接回复了一句“好的,明白”,导致设备没有任何反应。

经过深入排查,发现问题的根源竟然在于对话历史(Context)的构建方式。本文将记录这次排查过程及正确的解决方案,希望能帮大家避坑。


问题复现

场景描述

我正在开发一个语音助手,支持通过自然语言控制音量。

错误的历史记录构建

为了“节省 Token”或者图省事,在第一轮工具调用结束后,我在构建传给模型的 messages 历史时,手动修改了 Assistant 的回复

我构建的(错误的)历史记录:

[{"role":"user","content":"声音大一点"},{"role":"assistant","content":"好的,已为您调大音量。"}// ❌ 错误:这里丢失了 tool_calls 信息,被我替换成了纯文本]

结果
当用户进行第二轮提问“声音调小一点”时,模型看到上面的历史记录,它“学到”了一个规律:“在这个对话里,当用户要求调音量时,我只需要口头答应,不需要真的去调工具。”

这就是大模型的上下文学习(In-Context Learning)能力带来的副作用。模型被我伪造的历史记录误导了。


核心原因分析

大模型是基于“预测下一个 token”的机制工作的。它会极度依赖 messages 列表中的上下文模式。

  • 正确的模式:用户提问 -> 助手发起tool_calls-> tool 返回结果 -> 助手总结。
  • 错误的模式:用户提问 -> 助手直接回复文本(Content)。

如果我们在历史记录中抹去了tool_calls的痕迹,模型就会认为自己从未调用过工具,从而在后续对话中倾向于生成纯文本回复,导致 Function Calling 失效。


解决方案:标准的 Function Calling 链路

要解决这个问题,必须如实记录之前的工具调用过程。一个完整的工具调用闭环在 messages 中必须包含以下 4 个步骤:

  1. User: 提出需求。
  2. Assistant: 返回tool_calls字段(此时content通常为null)。
  3. Tool: 客户端执行代码,以role: tool返回执行结果。
  4. Assistant: 根据工具结果生成的最终回复。

正确的 JSON 结构示例

发给 API 的 Request Body 应该长这样:

{"messages":[{"role":"system","content":"你是一个智能硬件助手..."},// --- 第一轮 ---{"role":"user","content":"声音大一点"},// 关键点1:保留带有 tool_calls 的 assistant 消息{"role":"assistant","content":null,"tool_calls":[{"id":"call_abc123","type":"function","function":{"name":"set_volume","arguments":"{\"volumeCode\": \"volume_up\"}"}}]},// 关键点2:必须追加 tool 类型的消息,传入对应的 call_id 和执行结果{"role":"tool","tool_call_id":"call_abc123","content":"success"},// 助手对第一轮的总结{"role":"assistant","content":"好的,音量已调大。"},// --- 第二轮 ---{"role":"user","content":"声音调小一点"}// 此时模型看到上面发生过 tool_calls,这次它就会继续触发 tool_calls]}

代码实现 (Python)

下面是一个模拟正确构建对话历史的 Python 代码示例:

importjson# 模拟工具定义tools=[{'type':'function','function':{'name':'set_volume','description':'调整设备音量','parameters':{'type':'object','properties':{'volumeCode':{'type':'string','enum':['volume_up','volume_down']}},'required':['volumeCode']}}}]# 初始化对话历史messages=[{'role':'system','content':'你是一个全能AI助理,可以控制设备音量。'}]# --- 第一轮交互 ---print(">>> User: 声音大一点")messages.append({'role':'user','content':'声音大一点'})# 假设这里调用了大模型 API,模型返回了 tool_calls# 模拟模型返回的数据结构response_msg={"role":"assistant","content":None,"tool_calls":[{"id":"call_123456","type":"function","function":{"name":"set_volume","arguments":"{\"volumeCode\": \"volume_up\"}"}}]}# 【关键步骤】:将模型返回的原始消息(含 tool_calls)加入历史messages.append(response_msg)# 客户端执行工具逻辑...tool_output="Volume turned up successfully"tool_call_id=response_msg["tool_calls"][0]["id"]# 【关键步骤】:将工具执行结果以 role='tool' 加入历史messages.append({"role":"tool","tool_call_id":tool_call_id,"content":tool_output})# 模型根据工具结果给出的反馈final_feedback={'role':'assistant','content':'好的,声音已经调大了。'}messages.append(final_feedback)# --- 第二轮交互 ---print(">>> User: 声音调小一点")messages.append({'role':'user','content':'声音调小一点'})# 打印最终发送给模型的 Messages 结构print(json.dumps(messages,indent=2,ensure_ascii=False))# 此时再次调用 API,模型会因为看到了历史中的 tool_calls,从而正确地再次调用工具

总结

  1. 不要伪造历史:千万不要把 Assistant 的tool_calls响应手动转换成纯文本的content存入历史。
  2. 保持链路完整Assistant (tool_calls) -> Tool (result)这两步是成对出现的,缺一不可。
  3. 理解上下文学习:模型是很“懒”的,如果历史记录告诉它“只动口不动手”也能混过去,它下次就真的不动手了。

希望这篇踩坑记录能帮到正在折腾 Function Calling 的朋友们!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/17 9:18:11

JAVA电子签名:合同签署数字化利器

在数字化转型的关键时期,传统的纸质合同签署流程已成为企业效率提升的瓶颈。JAVA电子签名技术,正以其成熟、稳定且高度可控的特性,成为企业实现合同签署全流程数字化的可靠工具。本文旨在客观阐述其如何作为一项“利器”,解决传统…

作者头像 李华
网站建设 2026/6/17 9:21:05

OA系统开发中,KindEditor如何优化WORD截图复制流程?

(推了推黑框眼镜,手指在键盘上噼里啪啦敲击)各位老铁,咱北京程序员又来唠嗑了!最近接了个CMS官网的活儿,客户爸爸要求在KindEditor里整点花活——要能直接把Word/Excel/PPT/PDF里的内容连锅端到编辑器里&am…

作者头像 李华
网站建设 2026/6/17 9:13:51

机器学习与数据挖掘项目~消费者的预测分析(代码+数据集+报告)(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码

机器学习与数据挖掘项目~消费者的预测分析(代码数据集报告)(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码 以英国的在线电子零售公司的跨国交易数据。集作为分析样本,通过对该公司的运营指标统计分。析以及构建RM…

作者头像 李华
网站建设 2026/6/17 9:16:15

跨平台环境下,KindEditor如何优化WORD图片复制效率?

企业网站内容管理模块Word/公众号粘贴与文档导入功能实施报告 一、需求背景分析 作为重庆某国企项目负责人,我们在政府类项目开发中遇到了以下核心需求: 内容输入效率需求:需要支持从Word/公众号直接粘贴内容到网站编辑器,并自…

作者头像 李华
网站建设 2026/6/17 9:14:24

网页编辑器KindEditor如何处理WORD文档中的图片粘贴?

《Word一键转存历险记:一个穷学生的CMS升级之路》 寻找解决方案的奇幻旅程 第一天:初探Word粘贴黑科技 作为一名福建某高校的计科大三狗(啊不是,学生),我正在给我的CMS新闻管理系统做升级。需求很简单&a…

作者头像 李华
网站建设 2026/6/17 10:16:16

LDO相位补偿:提升动态响应关键方案

目录 一、核心原理:LDO 反馈环路的相位特性 二、通用 LDO 反馈网络补偿拓扑(适配可调输出 LDO) 1. ADJ 引脚并联补偿电容(最常用) 原理 适用场景 参数设计 2. 分压电阻串联补偿电容(零点补偿&#x…

作者头像 李华