让 AI 改文档,最怕的不是它挑不出错,而是它改错了地方。上周我就踩了这么一坑:让智能体把一份 40 页报告里的"截至/截止"误用统一清理,结果它把第三段一处本来就正确的"截至"给替换掉了,而真正用错的第十一段原封没动。模型不冤,冤的是文档——读写之间的状态变了。今天复盘这个问题,顺便聊聊察元AI文档助手里我非常认可的一道设计:锚点校验。
踩坑复盘:错位是怎么发生的
先还原时间线。下午两点,我让 Cursor 里的 agent 通过 MCP 连上察元(服务地址 http://127.0.0.1:62588/mcp),流程是先读全文、列出疑似误用、再逐条替换。前两步都对,第三步出事。校对跑到一半,同事在文档里补了两句话,段落位置整体漂移,agent 手里还攥着十分钟前的"第几段第几个词",写回去自然错位。
复盘下来,裸坐标(第 N 段第 M 字)在文档场景里天然不可靠:文档是活的,人多开一份、另一个 AI 进程写一笔、甚至自己手滑敲一个回车,坐标就作废。靠"人品"保证坐标不过期,不是工程做法。
有人会反驳:这问题用全局查找替换也能防——替换前先数一遍命中数,命中数不对就停手。思路对,但只对了一半。正则管不住"这段文字在这十分钟里被人动过",也管不住表格合并单元格后的坐标漂移,更管不住另一个智能体进程同时在往文档里写。本质上,锚点校验是文档世界的乐观锁:读的时候记下"这里是什么",写的时候验证"这里还是什么",版本对不上就拒绝提交。数据库领域用了几十年的老办法,搬到文档写回上一样好使。
机制拆解:读写都带锚点
察元的做法是让锚点贯穿读写全程:
- 读的时候,
document_list_paragraphs返回的每个段落都带锚点,不是裸序号; - 定位的时候,
document_locate会返回多个命中位置的锚点,交给上层判断哪个才是目标,而不是闷头取第一个; - 写的时候,
document_replace、document_apply_ops会校验锚点处的文本是否还是当初读到的样子。
对不上,返回 LOCATE_MISMATCH;压根找不到锚点,返回 LOCATE_NOT_FOUND。两种情况都拒绝写盘。一句话:宁可失败,不错位。这两个错误码看起来碍事,实际上是把你从"错改好文"的事故里拽回来的那道闸。
拿到 LOCATE_MISMATCH 之后的标准动作
我的处理顺序,供参考:
- 别让 agent 硬重试。同一个过期锚点重试一百次还是过期,只会刷屏;
- 让它重新
document_list_paragraphs拿最新锚点,再document_locate重新定位; - 命中多处时,要求它把每处命中的前后文一起列出来,按规则挑唯一命中。比如文档里出现三个"截止日期",目标是合同条款那一个,就让 agent 把三条上下文贴出来由人点单,拿不准就问,别让它自己猜;
- 再走写回。反正未传
confirmed: true时document_replace只返回 preview,顺势对着预览再核一遍,两头保险。
表格场景:口语找锚点,坐标来执行
表格比正文更容易错位,因为"第 5 行第 3 列"这种坐标在合并单元格、插行删行之后会漂。察元的表格工具是两段式:AI 先用 header_read、column_read 这类切片读找锚点行列,真正执行时工具只认显式坐标。你只需要说人话:
在"合计"行上面插入一行,列结构和上一行一致
再比如钉批注,直接把约束写进提示词,钉到字而不是钉到段:
重点检查表格单元格里的错别字,批注必须钉在具体错字上
这两段提示词的潜台词是:找位置交给 AI 的语义理解,落位置交给工具的坐标校验,口语和坐标各干各的活。出错时错误码还能告诉你断在哪一环——LOCATE_MISMATCH 是锚点对不上,重读再定位就好;LOCATE_NOT_FOUND 是压根没找到,多半是文本已被改得面目全非,得重新圈范围。两种错误码,两条处理路径,别混着治。
为什么说这是幻觉治理的一环
这两年 AI 幻觉治理喊得很响,焦点基本都在"模型说了假话"。但文档场景里更硬的伤害其实是"改错位置"——话是对的,落点是错的,错字还留在原文,好字反被殃及。锚点校验相当于把治理从生成侧挪到了写盘侧:模型可以随便建议,落盘前系统再核一次地面真相。这类不起眼的小机制,比发布会上的参数宣传实在得多。
适用人群:长文档编校、公文流转、合同审校、学报编辑部里让 AI 动手的同学。多智能体并行的团队尤其值得看——两个 agent 同时写一份文档,锚点校验就是最后那道互斥锁。最后说边界:锚点校验防的是错位,不防内容本身错,建议写得再头头是道,采纳前还是得人过目。防线是防线,裁判永远是人。
40

被折叠的 条评论
为什么被折叠?



