本地LLM不是不行,是你的上下文有Bug

4B本地模型反复读取文件暴露Agent框架丢弃工具结果的缺陷,修复后同模型完成最短路径。
作者在纯CPU环境用Ollama运行qwen3.5:4b作为编码Agent,发现模型反复读取同一文件并声称“看不到内容”。深入排查后确认,问题出在自研Agent框架:工具结果(文件内容、命令输出)仅在上下文中保留一轮,随后被静默丢弃,而去重逻辑仍提示模型“使用已读内容”。修复工具结果持久化并剥离GREP模式外层引号后,同一4B模型从六轮失败变为五轮完成。控制实验显示,9B模型在旧框架下用重复读取自我修复,修复后三步零重复完成。核心结论是模型表现等于模型能力乘以框架约束,弱模型反而是更好的框架测试器。
一款小型本地模型在编码任务中反复读取同一文件,并声称“读过了但看不到内容”。开发者一度认定是模型太弱。深入排查后发现,问题出在他自己写的Agent框架:工具结果只存活一轮就被丢弃。一个4B参数的模型,反而用最诚实的方式暴露了这个缺陷。
故障现场:反复读取与“看不见”的内容
作者在纯CPU环境(Ryzen 5 4500U、32GB内存、Ollama)下,将本地LLM当作IDE内的编码Agent进行基准测试。任务T3要求模型修复pytest失败:找到原因、修复、确认全部通过。他交给qwen3.5:4b——一个快速的小模型。
在旧版框架下,模型的表现堪称灾难:先读test_calc.py,再读calc.py,然后再次读取test_calc.py。框架的去重逻辑返回“文件未变化,请使用你已读取的内容”。模型却回复:“我读了,但内容在这里不可见。”随后它尝试GREP,零命中,再次读取,六轮耗尽,任务失败。
作者的第一反应是:4B模型不够聪明,无法遵循指令。

Ollama 是一个开源的本地大语言模型运行工具,支持在消费级硬件(包括纯CPU环境)上加载和推理多种开源模型(如Llama、Qwen等)。它通过简洁的API和命令行接口,让开发者无需GPU即可在本地运行模型,常用于隐私敏感或资源受限的场景。本文作者正是在Ollama上运行qwen3.5:4b等模型进行Agent基准测试。Ollama的轻量特性使其成为本地Agent开发的常见底座,但也意味着模型推理速度受CPU性能制约,上下文窗口管理需更加谨慎。
pytest 是Python生态中最流行的测试框架之一,用于编写和运行单元测试、功能测试。它支持自动发现测试文件、丰富的断言重写和插件扩展。在Agent编码任务中,pytest失败常被用作修复任务的起点:Agent需要读取测试代码和被测代码,定位失败原因,修改源码,再重新运行测试确认通过。本文的T3任务正是要求模型完成这一完整闭环。
根因追踪:工具结果只保留一轮
追踪Agent循环的代码后,缺陷浮出水面。历史累积逻辑存在严重不对称:用户消息被保留,助手回复被保留,但工具结果——文件内容、命令输出——在执行后仅存在于上下文一轮,然后被静默丢弃。
这意味着:第一步读取文件,第二步还能看到内容;从第三步开始,内容已从上下文中消失。而框架的去重抑制机制仍在告知模型“未变化,用你已有的”,指向的却是模型根本不再拥有的数据。
模型说“我看不到内容”并非胡言乱语,而是一份准确的状态报告。它知道自己的历史命令中包含READ_FILE,但载荷已经蒸发。这个4B模型实际上在正确地调试框架的上下文组装逻辑。
Agent循环中的上下文组装 是指框架在每一轮推理前,将系统提示、用户消息、助手历史回复以及工具调用结果按顺序拼接成完整提示词的过程。大模型本身是无状态的,它只能看到当前提示词中的内容,无法访问此前的会话记忆。因此,框架必须负责持久化所有关键信息——尤其是工具返回的文件内容、命令输出等——并在后续轮次中重新注入。如果框架丢弃了某些消息,模型在后续轮次中就会“失忆”。本文的缺陷正是工具结果仅在执行后的一轮内存在,随后被静默移除,导致模型无法引用已读取的文件内容。
意外发现:过去对9B的评估也要重写
这个bug改变了对早期测试结果的解读。作者的9B模型(qwen3.5:9b)曾被评价为“冗余地重复读取文件”,7步中有2步浪费在旧框架上。
但真相是:那不是记忆薄弱,而是合理的自我修复——重新获取已经消失的内容。更强的模型在绕开作者的bug,而较弱的模型只是诚实地报告了它。这一对比揭示了一个常被忽视的事实:模型表现是模型能力与框架约束的乘积。
修复方案与连带发现的第二个bug
修复包含两项。第一,将工具结果持久化到运行历史中——每一步的工具输出在整个运行期间保留在上下文中,“未变化”的提示终于名副其实。第二,剥离GREP模式的外层引号——模型反复输出GREP "member.*discount",字面引号进入正则表达式,导致零匹配;七轮重复引用,零命中。解析器现在会剥离包围引号,零匹配的GREP回复也会附带提示,建议简化模式或直接READ文件。
修复随Teaspoon IDE v1.5.1发布,采用FSL-1.1-MIT许可证。
GREP 是Unix/Linux系统中用于文本搜索的命令行工具,支持正则表达式匹配。在编码Agent中,GREP常被封装为工具,让模型通过模式匹配快速定位代码中的特定字符串或结构。正则表达式中的特殊字符(如.、*、")具有特定含义,若模型输出的模式被外层引号包裹且未剥离,引号会作为字面字符进入正则,导致匹配失败。本文中模型反复输出GREP "member.*discount",解析器未剥离引号,使正则实际匹配包含引号的字面串,因而零命中。修复解析器剥离包围引号后,GREP才能按预期工作。
控制实验:同一模型从“绝望”到最短路径
作者用相同模型、相同任务、相同提示词,仅改变框架修复状态,进行了控制实验。
| 条件 | 结果 |
|---|---|
| 4b · 旧框架 | 六轮耗尽,重复读取循环,失败 |
| 4b · 修复后 | 五轮完成(pytest→读取→修复→复验,正确) |
| 9b · 旧框架 | 七步,含两次重复读取(自我修复) |
| 9b · 修复后 | 三步,零重复读取,最短路径 |
| e4b · 修复后 | 四轮,零重复读取,干净完成 |
同一个4B模型,仅靠修复周围代码,就从“无药可救”变为“干净的最短路径完成”。
三个值得记住的教训
“模型弱”与“框架弱”在检查之前不可分割。 每一篇“这个模型没用”的文章,评的可能都是框架的约束。如果你在构建Agent工具,先怀疑上下文里有什么,再怀疑模型。
去重与上下文节省必须针对模型实际可见的内容来设计。 “它之前读过”只在那个内容物理存在于提示词中时才成立。
弱模型是最好的框架测试器。 强模型用自我修复掩盖缺陷;4B模型没有余量,忠实地可视化了作者的漏洞。测试自己的Agent循环时,跑一个边缘模型。
数据与环境
所有原始日志、任务定义和评估记录均已公开,包括完整测量数据与分析(labo.mond.jp/articles/localllm-harness-bug.en.html)、fixtures与prompts及运行产物(github.com/cuculhart/ai-editor-lab),以及Teaspoon IDE框架(github.com/cuculhart/teaspoon-ide)。
环境刻意保持简陋:老旧六核笔记本CPU,无GPU。如果框架更差,每个模型看起来都会是坏的。在检查你的模型之前,先检查你的上下文。
相关推荐

WorkBuddy全流程教程:从零搭建AI办公自动化智能体
WorkBuddy 全流程教程精讲:从下载安装、三种工作模式到多模态绘本视频实战,再到专家团搭建智能体与工作流配置,帮你用低成本 AI Agent 实现办公自动化。

WorkBuddy智能体全攻略:7天从入门到自动化实战
基于B站256集WorkBuddy全套精讲课程,系统拆解腾讯AI办公工作台的核心能力:Agent原理、Skill封装、连接器跨平台、定时自动化、知识库与零代码开发,附学习路径建议。

8个AI账号翻车7个:我用AI干活的真实复盘
B站8个AI运营账号仅1个跑通。本文拆解"演AI"与"用AI干活"的本质区别,分析5条视频217万播放背后的产能控制、评论区运营和交付节奏策略。