这个版本 AI 直接改 非结构化文件 的水平还是不强势啊 -- 看看原理
本文最后更新于 2026年5月6日 下午
这几天一直想总结一下 AI 大人出糗经历,给自己即将被淘汰的职业生涯整点电子吗啡安慰一下,这不就来例子了。
背景:Windows、goose Agent、 Hermes Agent、Markdown 测试报告、多次表格结构重构
事后总结确实发现这个 case 根源在于工具选型,一开始就应该用诸如 .xml 这种结构化且几乎是 test report 的标准指定文件。
但当时想到所谓 “Markdown 才是 AI-native language” + 真实世界哪来这么多结构化的干净数据。
因此直接就开始干活,半天过去,结果等发现的时候,已经烧了小半个月的工资而且陷入了再也改不动的处境,着实让处在觉得 “一个行政 + AI ” 就能把我开除的焦虑中松了口气。
1. 背景:用 AI Agent 编写一份测试报告
我在做一个内部系统的测试工作,需要产出一份 Markdown 格式的测试报告(.md)。报告结构大致如下:
1 | |
整个过程中,我让 goose Agent 帮我做两件事:
- 执行测试(调用 MCP 工具、记录结果)——这部分很顺利
- 把结果回填到报告的 Markdown 表格里——这部分翻车了
2. 故障回顾:为什么 AI 改文件比人慢 10 倍还容易错?
一开始 markdown 中 table 数据还少的时候改得非常顺利,但是随着表越来越长我开始感觉到不对了。
2.1 典型的失败循环
我让 Agent 把某个测试用例的结果填进 ## 2) Accuracy test 下的 Evidence 表格。Agent 的操作路径是:
- 用
Goose edit工具,提供before(要被替换的原文)和after(替换后的内容) - 工具返回:
No match found for the specified text. - Agent 换一种写法再试——还是
No match found - Agent 改用 Python 脚本去读文件、定位、替换——脚本报编码错误
- Agent 改用 PowerShell——PowerShell 的换行拼接语法报错
- Agent 再试
edit——还是No match found - ……
下面是从 session 历史里提取的真实失败统计:
| 操作类型 | 尝试次数 | 成功 | 失败 | 典型错误 |
|---|---|---|---|---|
functions.edit(精确替换) |
~40 | ~5 | ~35 | No match found |
| Python 脚本(读取/定位/替换) | ~15 | ~3 | ~12 | UnicodeEncodeError、<< was unexpected、无输出 |
| PowerShell 脚本(读取/替换) | ~10 | ~5 | ~5 | Parser error(换行拼接)、编码问题 |
2.2 一个具体的例子
我让 Agent 把 Evidence 表格里 ACC-002 的 (TBD - paste agent answer) 替换成实际答案。Agent 尝试了这样的 before:
1 | |
工具返回:No match found。
为什么?因为文件里实际的内容可能是:
- 末尾有
\r\n而不是\n **Agent answer (excerpt)**后面有两个空格(trailing spaces)形成 Markdown 换行- 或者之前某次编辑已经改过了这段文字,但 Agent 不知道
Agent 看不到这些差异,只能不断”猜”新的 before 字符串。
2.3 有多慢?
- 人类做同样的事:打开文件 → Ctrl+F 找到位置 → 粘贴内容 → 保存。30 秒。
- Agent 做同样的事:40+ 次
edit尝试 + 15+ 次脚本尝试 + 大量上下文消耗。超过 30 分钟,而且最终还没成功。
最后我对 Agent 说:“你给我可直接粘贴的表格行文本,我自己粘贴进去。”
3. 根因①:工具层——没有结构化编辑,只有字符串替换
3.1 goose 的 edit 工具是怎么工作的?
goose 的文件编辑能力由 developer 扩展提供,核心实现在:
其中最关键的函数是 string_replace:
1 | |
核心就是 content.match_indices(before)——Rust 标准库的精确子串匹配。
这意味着:
before必须与文件内容逐字节一致- 多一个空格、少一个换行、BOM 不同、
\r\nvs\n——全都会导致No match found - 没有模糊匹配、没有正则、没有”按结构定位”
3.2 它还提供了一个”猜测扩展”功能,但不够用
注意 find_similar_context 函数:
1 | |
它只用 before 的第一行去做 contains 匹配,然后返回附近几行作为提示。这比”完全没有提示”好,但对 LLM 来说远远不够——因为:
- 返回的提示只有 2 行上下文,LLM 很难据此推断出真正的差异(是换行符?是编码?是内容变了?)
- 没有 diff 视图,LLM 不知道”差在哪一个字符”
3.3 为什么之后大量转向 Python/PowerShell?
edit 反复失败后,Agent 试图用脚本做两类事情:
第一类:定位(edit 做不到的)
1 | |
第二类:块级替换(edit 的精确匹配太脆弱)
1 | |
但脚本也不稳定:
- Windows
cmd下 Python heredoc 报<< was unexpected at this time - PowerShell 拼接换行字符串
`r`n导致 parser error - 读取 UTF-8 BOM 文件时输出乱码 /
UnicodeEncodeError
3.4 如果是 JSON/XML,还会有这个问题吗?
大概率不会这么严重。 因为:
- JSON 可以
parse → modify → serialize - XML 可以按 XPath 定位节点
- 都有明确的层级结构和标签语义
但 Markdown 没有强制层级语义。它是”给人读”的,不是”给机器改”的。Heading 之间没有显式的”结束标记”,表格只是 | 分隔的文本行——工具没法说”找到 ACC-001 那一行然后改第 3 列”。
4. 根因②:LLM 层——没读到的部分等于不存在
4.1 Transformer 的上下文窗口:一个硬边界
当前主流 LLM(GPT-4、Claude、Gemini 等)都基于 Transformer 架构。Transformer 的核心是自注意力(self-attention)机制:模型在生成每个 token 时,会对输入序列中的所有 token 计算注意力权重。
这意味着:
- 只有在上下文窗口里的 token,才会被模型”看到”
- 没有读进上下文的文件内容,对模型来说等同于不存在
- 模型无法主动说”我没看到文件的第 80-100 行,可能那里有我需要的信息”——因为它根本不知道那些行的存在
就像打游戏的时候,这个英雄的每一个技能出装加点你都知道,但是再看某些创意套路玩法的时候还是会惊呼:居然还能这样我怎么想不到。
4.2 Unknown Unknowns:不知道自己不知道
- Known knowns:我读到了文件的这一段,知道它是什么
- Known unknowns:我知道文件还有其他部分,但我没读
- Unknown unknowns:我不知道文件里还有一段跟我要改的地方相关(比如之前某次编辑已经改过了占位符文本)
在我们这次的场景里,Agent 就陷入了 unknown unknowns:
- 它记得之前我们定义的占位符是
(TBD - paste agent answer) - 但文件里这段文字可能已经被之前某次(部分成功的)编辑改掉了
- Agent 不知道这件事,继续用旧的
before字符串去匹配——反复失败
4.3 这是 Transformer 架构本身决定的吗?
基本上是的。 但需要更精确地说:
Transformer 的自注意力机制本身是一种有限窗口内的全局关联计算。它的核心公式是:
1 | |
其中 Q、K、V 都来自输入序列。序列之外的信息,在数学上就不参与计算。
这不是”模型不够大”能解决的——即使给你 100 万 token 的上下文窗口,如果你没把文件内容放进去,它就是看不见。
4.4 “真实世界模型”能从根本上解决吗?
学术界有一个持续的讨论:LLM 是否只是”统计模式匹配器”,还是能形成某种”世界模型”(world model)?
一些相关的研究方向:
- MemoryPrompt(Rakotonirina & Baroni, 2024, arXiv:2402.15268):用一个小的辅助循环网络给 LLM 补充”记忆”,让它能追踪超出窗口的事实更新。实验表明,这种方法在多轮事实更新任务上超过了能看到完整历史的更大模型。
- RAG(Retrieval-Augmented Generation):不把所有内容塞进上下文,而是按需检索相关片段。这在问答场景有效,但在”精确编辑文件”场景下,检索不能替代”知道文件当前精确状态”。
至少现阶段(2026-05-06)这还是一个典型的工程选型问题,比如文章一开始说的用结构化文件,或者我最近在学习的 Graph-Index 等,但是本质上都需要先抽象提炼真实世界,工程得不能再工程了。
5. 本质区别:人类是”模糊定位 + 即时反馈”,Agent 是”精确猜测 + 延迟反馈” (本段持续更新)
至此,我想深入的学习一下背后的原理,如果没有 AI 大人,我肯定不会去翻论文,甚至就去某些二手知识网站草草看几个科普了事。
5.1 人类怎么改一个 Markdown 表格?
- 视觉扫描:打开文件,滚动到大概位置(”记得 Accuracy 在中间偏下”)
- 模糊匹配:肉眼扫到
## 2) Accuracy test,再往下找到表格 - 精确定位:看到
(TBD - paste agent answer)那一行 - 修改:选中 → 粘贴 → 保存
- 即时确认:改完立刻看到结果,发现格式不对就马上修
整个过程依赖三种能力:
- 空间/布局记忆(layout memory):记得”大概在哪里”
- 模糊容错(fuzzy matching):多一个空格也能认出来
- 即时视觉反馈(immediate feedback):改完就能看
5.2 Agent 怎么改一个 Markdown 表格?
- 读取片段:用工具读文件的一部分到上下文
- 构造 before:根据记忆(可能已过期)猜测要替换的精确文本
- 调用 edit:发送
before+after - 等待结果:收到
No match found(唯一的反馈是”没找到”,不告诉你差在哪) - 重试:换一种
before再猜
这个过程的问题:
- 没有空间感知:Agent 不知道”表格在文件的第几行”,除非它先用脚本查
- 不能模糊匹配:工具要求逐字一致
- 反馈粒度太粗:只有 match / no match,不像人眼能直接看到”差了一个换行”
5.3 从”智能”的角度看
这个对比揭示了一个更深层的问题:
人类的”智能”很大一部分来自感知-行动的闭环(perception-action loop)。 我们的视觉系统、运动系统、工作记忆紧密耦合,形成一个低延迟、高带宽的反馈环路。改文件时,你的眼睛就是你的”即时文件状态感知器”。
当前 Agent 的”智能”主要体现在语言推理(language reasoning)上。 它可以理解你的意图、规划步骤、生成代码——但它与外部世界的交互是通过离散的工具调用完成的。每次工具调用都是一次”盲操作”:发出去,等结果回来,再决定下一步。
这就是为什么同样的”智能水平”,在不同的工具条件下表现可以差 10 倍甚至更多。Agent 的能力上限不仅取决于模型,更取决于工具。
5.5 展望:如果 Agent 不靠工具,能自己”感知”世界吗?
上面我们得出结论:Agent 缺的不是智能,是一双眼睛。 而这双”眼睛”目前需要在工具层去补。
但这就引出一个更深的问题:有没有可能,AI 不需要外部工具,就能自己感知和理解环境? 人类似乎天生就能做到——我们不需要”调用 API”来看一眼文件,我们只需要睁开眼睛。
下面从五个角度展望这个问题。不是预言未来,而是把当前 AI 与人类智能的差距拆开来看。
5.5.1 具身智能(Embodied AI):智能是从身体与环境的交互中”长”出来的
认知科学有一个重要流派叫具身认知(Embodied Cognition):人类的智能不是一个脱离身体的”纯推理引擎”,而是在身体与环境的持续交互中发展出来的。
婴儿学会”抓取”不是因为谁给了他一本物理学教材,而是因为他反复伸手、碰到东西、感受反馈、调整动作——几百万次的感知-行动循环。成人改文件时的”扫一眼就知道在哪”,本质上也是视觉系统和运动系统长期协作训练出来的能力。
当前的 LLM 是纯语言的大脑:没有眼睛、没有手、没有空间感。它的所有”经验”都来自文本语料,而不是来自与环境的交互。
具身智能(Embodied AI) 是当前 AI 研究的一个重要方向,核心思路是:让 AI 在模拟或真实环境中主动探索、操作、获得反馈。典型场景包括机器人操控(manipulation)、视觉导航(visual navigation)、以及在虚拟环境中完成任务。目前主流的研究平台包括 Meta 的 Habitat(用于视觉导航和具身问答)以及 AI2 的 AI2-THOR(用于室内场景交互)。
回到我们这个场景:Agent 编辑文件就像一个没有眼睛的人在黑暗中改文件——它只能靠”摸”(工具调用)来获取信息。而人类是睁着眼睛操作的。具身智能的终极目标,是让 AI 也能”睁开眼睛”。
参考:
- Embodied Cognition 综述:Shapiro, L. (2011). Embodied Cognition. Routledge. 豆瓣
- Habitat 平台:Savva et al., “Habitat: A Platform for Embodied AI Research” (ICCV 2019). arXiv:1904.01201
- AI2-THOR:Kolve et al., “AI2-THOR: An Interactive 3D Environment for Visual AI” (2017). arXiv:1712.05474
5.5.2 世界模型(World Models):AI 能在”脑子里”模拟文件的状态吗?
Meta 首席 AI 科学家 Yann LeCun 在多次公开演讲和论文中提出:当前的 LLM 缺少一个关键组件——世界模型(World Model)。
他提出的 JEPA(Joint Embedding Predictive Architecture) 框架的核心思想是:智能体应该学习一个环境的内部表征,能够预测环境在不同行动下会如何变化,而不仅仅是生成文本。
用一个比喻:你推一下桌上的杯子,你的大脑能”预测”杯子会滑动、可能掉下去——你不需要真的推才知道。这就是”世界模型”在起作用。
在我们这个场景里:如果 Agent 有一个”文件状态的内部模型”,它就不需要每次都去读文件才知道当前内容是什么——它能在”脑子里”维护一份文件的状态,预测”如果我替换这段文字,文件会变成什么样”。
但当前的 LLM 没有这种持久的、可更新的内部状态模型。它的”记忆”就是上下文窗口里的 token——窗口之外的信息,在数学上就不参与计算。每次对话轮次结束,如果上下文被截断或压缩,之前的”文件状态”就可能丢失。
LeCun 认为,真正的 AGI 需要的不是更大的语言模型,而是能学习世界运行规律并在内部模拟的系统。这个方向目前仍在早期研究阶段,但如果有朝一日实现,Agent 的”unknown unknowns”问题会从根本上减少——因为它”脑子里”就有一份环境的实时模型。
参考:
- LeCun, Y. “A Path Towards Autonomous Machine Intelligence” (2022). 论文 PDF
- Ha, D. & Schmidhuber, J. “World Models” (2018). arXiv:1803.10122
- LeCun JEPA 演讲(Meta AI, 2023):YouTube
5.5.3 主动推理(Active Inference):智能体应该主动”去看”,而不是被动等输入
神经科学家 Karl Friston 提出了自由能原理(Free Energy Principle):生物体的核心驱动力是减少对环境的不确定性(surprise)。换句话说,智能体天生就有动力去”搞清楚”自己不了解的东西。
人类在编辑文件时,这个原理体现得很明显:
- 你不确定表格在哪 → 你会主动滚动/搜索(减少不确定性)
- 你不确定改对了没 → 你会主动检查结果(减少不确定性)
- 你发现格式不对 → 你会主动修正(减少 surprise)
这是一种主动推理(Active Inference):不是被动地等待信息输入,而是主动地去获取你需要的信息。
当前 Agent 的问题恰恰在于它是被动的:你给它什么上下文,它就在什么上下文里工作。它不会主动说”等一下,我先完整扫描一遍文件结构再开始编辑”——除非你在 system prompt 里明确要求它这么做。
一些前沿研究正在尝试把主动推理的思想引入 AI Agent:让 Agent 自己判断”我对当前环境的哪些部分不够了解”,然后主动去探索/查询以减少不确定性。如果这个能力成熟,Agent 就不会再盲目地用过期的 before 字符串去碰运气——它会先主动确认文件的当前状态。
参考:
- Friston, K. “The free-energy principle: a unified brain theory?” Nature Reviews Neuroscience 11, 127–138 (2010). doi:10.1038/nrn2787
- Friston, K. et al. “Active Inference: The Free Energy Principle in Mind, Brain, and Behavior” (MIT Press, 2022). MIT Press
- Fountas, Z. et al. “Deep active inference agents using Monte-Carlo methods” (NeurIPS 2020). arXiv:2006.04176
5.5.4 双系统理论(System 1 / System 2):快思考与慢思考
诺贝尔经济学奖得主 Daniel Kahneman 在《思考,快与慢》中提出了著名的双系统理论:
- System 1(快系统):快速、直觉、自动化。例如:扫一眼就知道表格在哪、看到红色就觉得危险、一眼认出朋友的脸。
- System 2(慢系统):慢速、逻辑、需要集中注意力。例如:计算 17 × 24、分析一段法律条文、写一段代码。
人类在编辑文件时,两个系统紧密协作:
- System 1 负责快速定位(”表格大概在中间偏下”)、模式识别(”这行看起来像我要改的那行”)
- System 2 负责精确操作(”确认这是 ACC-002 那一行,把第 4 列改成新内容”)
当前的 LLM 更像一个纯 System 2 的存在:它擅长逻辑推理、长链条规划、代码生成——但它缺乏 System 1 式的快速感知和直觉定位能力。
这就是为什么 Agent 在”找到文件里的某一段”这件事上表现很差:这本质上是一个 System 1 任务(人类靠直觉/视觉就能完成),但 Agent 不得不用 System 2 的方式(逻辑推理 + 精确字符串匹配)去做——效率自然低一个数量级。
一个有趣的研究方向是:能否给 Agent 补上 System 1?比如用一个快速的、低精度但高覆盖的”预扫描”模块来完成粗定位,再把精确操作交给 LLM(System 2)。这其实就是我们前面说的”结构化定位工具”——它本质上就是在给 Agent 补 System 1。
参考:
- Kahneman, D. Thinking, Fast and Slow (2011). Farrar, Straus and Giroux. 豆瓣
- Bengio, Y. “From System 1 Deep Learning to System 2 Deep Learning” (NeurIPS 2019 Keynote). YouTube
- Weston, J. & Sukhbaatar, S. “System 2 Attention (is something you might need too)” (2023). arXiv:2311.16502
5.5.5 多模态 AI(Multimodal AI):给 Agent 一双”真正的眼睛”
最后一个展望,也是目前最接近落地的方向:多模态 AI。
当前的多模态模型(如 GPT-4V、Claude vision、Gemini)已经可以”看”图片和截图。如果 Agent 能像人一样”看到”文件的渲染结果(而不只是处理文本 token),是否能解决定位问题?
答案是:部分能,但不够。
“看截图”和”精确编辑文件”之间还有巨大鸿沟:
- 你能从截图里看到”表格大概在这个位置”→ 粗定位 ✅
- 但你不能从截图里精确知道”第 65 行第 3 列的文本是什么”→ 精确编辑 ❌
- 更不能直接”点击截图来修改文件”→ 操作闭环 ❌
但如果把多模态和工具链结合起来,可以形成一个很有意思的架构:
- Vision(System 1):Agent 先”看一眼”文件的渲染视图,快速定位”我要改的区域大概在哪”
- Tool(System 2):再用结构化工具精确定位并修改
这就像人类实际的操作方式:先用眼睛扫一眼(System 1),再用鼠标/键盘精确操作(System 2)。
目前已经有一些研究在探索”视觉 Grounding + 工具操作”的结合,比如让 Agent 通过截图理解 UI 布局,然后生成对应的操作指令。如果这条路走通,Agent 编辑文件的体验会接近人类——先”看”,再”改”。
参考:
- Yang, Z. et al. “Set-of-Mark Prompting Unleashes Extraordinary Visual Grounding in GPT-4V” (2023). arXiv:2310.11441
- Zheng, B. et al. “GPT-4Vision is a Generalist Web Agent, if Grounded” (2024). arXiv:2401.01614
- MemoryPrompt(辅助 LLM 追踪上下文变化):Rakotonirina & Baroni (2024). arXiv:2402.15268
5.5.6 小结:人类智能 vs AI 智能——不是谁更”聪明”,而是认识世界的方式不同
| 维度 | 人类 | 当前 AI (LLM + Agent) |
|---|---|---|
| 感知 | 多模态(视觉/听觉/触觉),持续、主动 | 单模态(文本为主),离散、被动 |
| 记忆 | 长期记忆 + 工作记忆,可灵活调用 | 上下文窗口(有限),窗口外即不可见 |
| 定位 | 模糊匹配 + 空间布局记忆(System 1) | 精确字符串匹配(System 2 only) |
| 反馈 | 即时视觉反馈(改完就能看) | 延迟工具回执(match / no match) |
| 探索 | 主动推理(不确定就去看) | 被动等待(给什么上下文用什么) |
| 世界模型 | 内置(能预测操作后果) | 无(每次都要重新读取确认) |
这张表不是说 AI 不如人——在逻辑推理、代码生成、海量知识检索等方面,AI 已经远超多数人。但在与具体环境交互、操作实体对象这类任务上,人类的”感知-行动闭环”仍然有巨大优势。
Agent 要变强,不只是模型要更大——更重要的是,它需要学会像人一样”感知”世界。
工具层的改进(结构化编辑器、模糊匹配)是当下最务实的路;而具身智能、世界模型、主动推理、多模态融合,是更远的路。两条路不矛盾,终点是同一个:让 Agent 从”盲人摸象”变成”睁眼做事”。
6. 怎么修:Agent 需要什么样的文件编辑工具?
6.1 当前阶段最务实的改进:结构化定位 + 模糊匹配
不需要等”真正的世界模型”或”超长上下文”。只需要在工具层补两类能力:
能力 A:按结构定位
1 | |
有了这些,Agent 就不需要”猜 before 字符串”——它可以先定位、再修改。
能力 B:模糊/容错匹配
类似 git apply 的 fuzzy hunk matching:
1 | |
或者更简单:让 edit 工具在失败时返回 diff 提示(”你的 before 和文件里最相似的片段差在第 3 行,你多了一个 \r“)。
6.2 Unknown unknowns 的解法:先扫描,再编辑
如果工具支持”按结构列出文件内容”,Agent 就可以在编辑前先执行一次扫描:
1 | |
这一步的意义是:把 unknown unknowns 变成 known knowns。 Agent 知道了文件的完整结构,就不会再”以为某段还在、其实已经被改过了”。
6.3 这够用吗?
对于”编辑 Markdown/文本文件”这个场景——基本够用。
更长远来看,理想的 Agent 文件编辑工具应该像一个”无头编辑器”(headless editor):
- 支持按行号/列号定位
- 支持按正则/结构化查询定位
- 支持原子化修改(插入行、替换行、删除行)
- 每次修改后返回受影响区域的上下文(让 Agent “看到”改完的样子)
这本质上是在给 Agent 补上它缺失的那条”感知-行动闭环”:改 → 看到结果 → 确认 → 下一步。
7. 结语
回到开头的问题:AI Agent 改一个 Markdown 表格为什么能失败 50 次?
答案是三层叠加:
- 工具层:
edit工具是逐字精确匹配,没有结构化定位和模糊容错 - LLM 层:Transformer 只能看到上下文窗口内的内容,文件的”当前真实状态”不一定在窗口里
- 环境层:Windows 换行符、BOM、PowerShell/cmd 语法差异,进一步放大了脆弱性
这三者的乘法效应,把一个”30 秒的任务”变成了”30 分钟的死循环”。
Agent 缺的不是智能,是一双眼睛。
而这双”眼睛”,目前需要我们在工具层去补。
附录:goose edit 工具源码位置
- 文件编辑核心实现:
crates/goose/src/agents/platform_extensions/developer/edit.rs string_replace函数:精确子串匹配 + 唯一性校验find_similar_context函数:用before的第一行做contains匹配,返回附近上下文- 工具描述注册:
crates/goose/src/agents/platform_extensions/developer/mod.rs