编辑引擎
AI 生成的代码需要精确写入文件。如果匹配失败,要么整个编辑丢失(用户白等),要么重试消耗额外 token(用户多花钱)。wescode 的编辑引擎用三级匹配解决这个问题。
为什么精确匹配不够
模型在生成 edit 工具调用时,需要指定"在文件的哪个位置"修改代码。它给出的定位文本(old_string)基于它"记忆"中的文件内容。但这份记忆可能已经过时:
- 文件在对话过程中被其他工具修改
- 模型的上下文窗口只看到了文件的部分内容
- 模型在复述代码时产生了微小的空白 / 缩进差异
此时精确匹配(old_string 必须一字不差地出现在文件中)就会失败。传统方案让模型重试——但重试意味着额外的 API 调用和 token 消耗。
三级匹配
wescode 的编辑引擎在精确匹配失败后,自动尝试更宽松的匹配策略,不需要模型重试:
Level 1:精确匹配(Exact)
old_string 与文件内容逐字节比较。这是最快、最安全的路径,大多数编辑在这一级完成。
Level 2:模糊匹配(Fuzzy)
忽略空白差异进行匹配:
- 行尾空格 / tab 与空格差异
- 连续空行数量差异
- 缩进层级的轻微偏移
模糊匹配有相似度阈值。匹配度过低时不会硬上——宁可失败也不错位替换。
Level 3:AST 结构匹配(Structural)
当文本级匹配都失败时,解析文件的 AST(抽象语法树),在结构层面定位修改目标:
- 按函数名 / 类名 / 方法签名定位
- 忽略注释和格式变化
- 在结构相同但文本不同的节点上应用修改
这是最强大也最昂贵的匹配方式,仅在前两级失败时触发。
Buffer Overlay
wescode 的编辑引擎与 VS Code 编辑器深度集成:
AI 读到的永远是最新内容。 当你在编辑器中修改了文件但未保存(dirty buffer),AI 的 read 工具会读到编辑器内存中的版本,而不是磁盘上的旧版本。
这通过 Buffer Overlay 实现:
- VS Code 监听文件变化(
onDidChangeContent),debounce 后推送到后端 - 后端的
BufferStore维护(cellID, path) → content的内存映射 read工具先查 BufferStore,未命中才读磁盘- 保存文件时自动清除 overlay
路径解析使用 filepath.EvalSymlinks 确保 symlink 不导致匹配失败(macOS 的 /var → /private/var 是典型场景)。
编辑后的文件状态
关键不变量:AI 编辑后 buffer === disk,无 dirty 状态。
当编辑被应用后,wescode 调用 textFileService.revert(uri) 原子地完成:读磁盘 → 更新 buffer → 清 dirty flag。
这意味着:
- 关闭文件不会弹出"是否保存"对话框
- Accept 是纯 UI 操作(清除 diff decoration)
- Reject 是磁盘回滚 + 重新同步
Diff 预览
编辑并非静默发生。wescode 在编辑器中显示 inline diff:
- 绿色高亮显示新增内容
- 红色高亮显示删除内容
- Accept / Reject 按钮直接在编辑器中操作
这让你在 AI 每次编辑后都能审查变更,而不是事后 git diff 发现意外。
下一步
- 渐进验证 — 编辑之后的自动检查
- Chat 与 Agent 模式 — Agent 如何决定编辑策略
- 上下文管理 — 模型如何拿到准确的文件内容