这个版本 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# System Test Report

## 1) UX test
### Findings (UX) — action-based table
| Action | Severity | Actual | Evidence | Recommendation |
|---|---|---|---|---|
| action_a | P2 | ... | ... | ... |
| action_b | P1 | ... | ... | ... |

## 2) Accuracy test
### 2.1 Results table (compact)
| ID | Action | Correctness | Turns | External check |
|---|---|---|---:|---|
| ACC-001 | ... | Correct | 1 | Not found |
| ACC-002 | ... | Correct | 1 | Not found |

### 2.2 Evidence
| ID | Ground truth | Agent prompt | Agent answer | External check |
|---|---|---|---|---|
| ACC-001 | `node:xxx` — "quote..." | prompt text | answer excerpt | Not found |

### 2.3 How to locate (common)
...

## 3) Performance test
...

整个过程中,我让 goose Agent 帮我做两件事:

  1. 执行测试(调用 MCP 工具、记录结果)——这部分很顺利
  2. 把结果回填到报告的 Markdown 表格里——这部分翻车了

2. 故障回顾:为什么 AI 改文件比人慢 10 倍还容易错?

一开始 markdown 中 table 数据还少的时候改得非常顺利,但是随着表越来越长我开始感觉到不对了。

2.1 典型的失败循环

我让 Agent 把某个测试用例的结果填进 ## 2) Accuracy test 下的 Evidence 表格。Agent 的操作路径是:

  1. Goose edit 工具,提供 before(要被替换的原文)和 after(替换后的内容)
  2. 工具返回:No match found for the specified text.
  3. Agent 换一种写法再试——还是 No match found
  4. Agent 改用 Python 脚本去读文件、定位、替换——脚本报编码错误
  5. Agent 改用 PowerShell——PowerShell 的换行拼接语法报错
  6. Agent 再试 edit——还是 No match found
  7. ……

下面是从 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
2
**Agent answer (excerpt)**  
(TBD - paste agent answer)

工具返回: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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
pub fn string_replace(content: &str, before: &str, after: &str) -> Result<String, String> {
let matches: Vec<_> = content.match_indices(before).collect();

match matches.len() {
0 => {
// 没找到 → 报错,附带建议和文件预览
let suggestion = find_similar_context(content, before);
let mut msg = "No match found for the specified text.".to_string();
if let Some(hint) = suggestion {
msg.push_str(&format!("\n\nDid you mean:\n```\n{}\n```", hint));
}
let preview = build_file_preview(content, NO_MATCH_PREVIEW_LINES);
msg.push_str(&format!("\n\nFile preview:\n```\n{}\n```", preview));
Err(msg)
}
1 => Ok(content.replacen(before, after, 1)), // 唯一匹配 → 替换
n => {
// 多个匹配 → 报错,要求更多上下文
// ...
Err(msg)
}
}
}

核心就是 content.match_indices(before)——Rust 标准库的精确子串匹配。

这意味着:

  • before 必须与文件内容逐字节一致
  • 多一个空格、少一个换行、BOM 不同、\r\n vs \n——全都会导致 No match found
  • 没有模糊匹配、没有正则、没有”按结构定位”

3.2 它还提供了一个”猜测扩展”功能,但不够用

注意 find_similar_context 函数:

1
2
3
4
5
6
7
8
9
10
11
12
fn find_similar_context(content: &str, search: &str) -> Option<String> {
let first_line = search.lines().next()?.trim();
if first_line.is_empty() {
return None;
}
for (i, line) in content.lines().enumerate() {
if line.contains(first_line) || first_line.contains(line.trim()) {
return Some(get_line_context(content, i + 1, 2));
}
}
None
}

它只用 before第一行去做 contains 匹配,然后返回附近几行作为提示。这比”完全没有提示”好,但对 LLM 来说远远不够——因为:

  1. 返回的提示只有 2 行上下文,LLM 很难据此推断出真正的差异(是换行符?是编码?是内容变了?)
  2. 没有 diff 视图,LLM 不知道”差在哪一个字符”

3.3 为什么之后大量转向 Python/PowerShell?

edit 反复失败后,Agent 试图用脚本做两类事情:

第一类:定位(edit 做不到的)

1
2
3
4
5
# 找到某个 heading 的位置
text = open("report.md").read()
start = text.find("## 2) Accuracy test")
end = text.find("## 3) Performance test")
print(text[start:end])

第二类:块级替换(edit 的精确匹配太脆弱)

1
2
3
4
5
$report = Get-Content -Raw -Encoding UTF8 report.md
$start = $report.IndexOf("## 2) Accuracy test")
$end = $report.IndexOf("## 3) Performance test")
$updated = $report.Substring(0, $start) + $newSection + $report.Substring($end)
Set-Content -Encoding UTF8 report.md $updated

但脚本也不稳定:

  • 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:不知道自己不知道

这正是 Donald Rumsfeld 的经典分类

  • Known knowns:我读到了文件的这一段,知道它是什么
  • Known unknowns:我知道文件还有其他部分,但我没读
  • Unknown unknowns:我不知道文件里还有一段跟我要改的地方相关(比如之前某次编辑已经改过了占位符文本)

在我们这次的场景里,Agent 就陷入了 unknown unknowns:

  • 记得之前我们定义的占位符是 (TBD - paste agent answer)
  • 但文件里这段文字可能已经被之前某次(部分成功的)编辑改掉了
  • Agent 不知道这件事,继续用旧的 before 字符串去匹配——反复失败

4.3 这是 Transformer 架构本身决定的吗?

基本上是的。 但需要更精确地说:

Transformer 的自注意力机制本身是一种有限窗口内的全局关联计算。它的核心公式是:

1
Attention(Q, K, V) = softmax( Q·Kᵀ / √dₖ ) · V

其中 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 表格?

  1. 视觉扫描:打开文件,滚动到大概位置(”记得 Accuracy 在中间偏下”)
  2. 模糊匹配:肉眼扫到 ## 2) Accuracy test,再往下找到表格
  3. 精确定位:看到 (TBD - paste agent answer) 那一行
  4. 修改:选中 → 粘贴 → 保存
  5. 即时确认:改完立刻看到结果,发现格式不对就马上修

整个过程依赖三种能力:

  • 空间/布局记忆(layout memory):记得”大概在哪里”
  • 模糊容错(fuzzy matching):多一个空格也能认出来
  • 即时视觉反馈(immediate feedback):改完就能看

5.2 Agent 怎么改一个 Markdown 表格?

  1. 读取片段:用工具读文件的一部分到上下文
  2. 构造 before:根据记忆(可能已过期)猜测要替换的精确文本
  3. 调用 edit:发送 before + after
  4. 等待结果:收到 No match found(唯一的反馈是”没找到”,不告诉你差在哪)
  5. 重试:换一种 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 列的文本是什么”→ 精确编辑 ❌
  • 更不能直接”点击截图来修改文件”→ 操作闭环 ❌

但如果把多模态和工具链结合起来,可以形成一个很有意思的架构:

  1. Vision(System 1):Agent 先”看一眼”文件的渲染视图,快速定位”我要改的区域大概在哪”
  2. 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
2
3
4
5
6
7
8
get_section(file, heading="## 2) Accuracy test")
→ 返回该 section 的精确文本 + 起止行号

list_markdown_headings(file)
→ 返回所有 heading 的层级/行号/标题

get_table_row(file, section="2.2 Evidence", key_column="ID", key_value="ACC-002")
→ 返回该行的完整内容

有了这些,Agent 就不需要”猜 before 字符串”——它可以先定位、再修改。

能力 B:模糊/容错匹配

类似 git apply 的 fuzzy hunk matching:

1
2
3
edit_fuzzy(file, before="...", after="...", tolerance=0.9)
→ 找到相似度 ≥ 90% 的片段,替换之
→ 如果多个匹配,返回候选列表让 Agent 选择

或者更简单:让 edit 工具在失败时返回 diff 提示(”你的 before 和文件里最相似的片段差在第 3 行,你多了一个 \r“)。

6.2 Unknown unknowns 的解法:先扫描,再编辑

如果工具支持”按结构列出文件内容”,Agent 就可以在编辑前先执行一次扫描:

1
2
3
4
5
6
list_markdown_headings("report.md")
→ ## 1) UX test (line 5)
→ ## 2) Accuracy test (line 43)
→ ### 2.1 Results table (line 54)
→ ### 2.2 Evidence (line 61)
→ ## 3) Performance test (line 88)

这一步的意义是:把 unknown unknowns 变成 known knowns。 Agent 知道了文件的完整结构,就不会再”以为某段还在、其实已经被改过了”。

6.3 这够用吗?

对于”编辑 Markdown/文本文件”这个场景——基本够用。

更长远来看,理想的 Agent 文件编辑工具应该像一个”无头编辑器”(headless editor):

  • 支持按行号/列号定位
  • 支持按正则/结构化查询定位
  • 支持原子化修改(插入行、替换行、删除行)
  • 每次修改后返回受影响区域的上下文(让 Agent “看到”改完的样子)

这本质上是在给 Agent 补上它缺失的那条”感知-行动闭环”:改 → 看到结果 → 确认 → 下一步。

7. 结语

回到开头的问题:AI Agent 改一个 Markdown 表格为什么能失败 50 次?

答案是三层叠加:

  1. 工具层edit 工具是逐字精确匹配,没有结构化定位和模糊容错
  2. LLM 层:Transformer 只能看到上下文窗口内的内容,文件的”当前真实状态”不一定在窗口里
  3. 环境层:Windows 换行符、BOM、PowerShell/cmd 语法差异,进一步放大了脆弱性

这三者的乘法效应,把一个”30 秒的任务”变成了”30 分钟的死循环”。

Agent 缺的不是智能,是一双眼睛。

而这双”眼睛”,目前需要我们在工具层去补。


附录:goose edit 工具源码位置


这个版本 AI 直接改 非结构化文件 的水平还是不强势啊 -- 看看原理
https://gou7ma7.github.io/2026/05/03/devops/@2026_unstructured_text_the_blind_spot_of_ai_agents/
作者
Roy Lee
发布于
2026年5月3日
许可协议