上一篇写 Harness Engineering 时,我把 AI coding 的默认顺序压成了几步:
- Read
- Search
- Change
- Verify
- Record
这几步里,最容易被低估的是 Search。
很多 agent 会失败,常见原因是第一步读错了地方。用户说的是一个行为、一个 bug、一个跨层流程,代码里却可能没有同名函数。直接 rg login、rg upload、rg session 很快,但它只适合已知关键词。关键词不知道时,快只会更快地跑偏。
所以我把最近常用的一小层工具开源了:
它做的事很窄:把 Augment Context Engine 的 filesystem context search 包成一个 ace 命令,让 coding agent 可以在 shell 里先做语义检索。
为什么需要这一层 #
我关心的点很具体:把搜索动作放进 harness。
以前我经常看到这种路径:
flowchart LR A[User describes behavior] --> B[Agent guesses keywords] B --> C[Reads nearby files] C --> D[Edits plausible code] D --> E[Verification fails] E --> B
这个循环的问题是,失败后 agent 往往会继续围着同一批错误文件打转。它有修改能力,缺的是更好的候选文件入口。
ace-wrapper 想补的是这里:
flowchart LR A[User describes behavior] --> B[ace semantic retrieval] B --> C[Candidate files] C --> D[Read returned files] D --> E[rg / tests confirm evidence] E --> F[Small patch] F --> G[Verify]
这里的关键是顺序:ace 只负责找候选文件。真正的证据仍然来自读文件、精确搜索和测试。
用法很短 #
安装:
uv tool install ace-wrapper本地开发版:
uv tool install /path/to/ace-wrapper查一个不知道关键词的工作流:
timeout 60s ace "user uploads an unsupported file and should see skipped-file feedback" -w /repo
rg -n "unsupported|skipped|upload|file" /repo第一条命令回答“可能在哪些文件”。第二条命令确认“代码里到底有没有这些标识、事件、文案或测试”。
我一般会把这段规则放进项目的 AGENTS.md:
Use `timeout 60s ace "<query>" -w <repo-root>` for semantic codebase discovery.
Treat `ace` results as candidate files.
After it returns results, read the relevant files and use exact search before using them as evidence.这几行比“多读上下文”更有效,因为它给了 agent 一个具体动作,也给了停止误判的边界。
它和 rg 怎么配合 #
ace 和 rg 更适合前后配合使用。
| 场景 | 先用什么 | 为什么 |
|---|---|---|
| 不知道实现在哪里,只知道用户行为 | ace |
行为描述能跨文件、跨命名找到候选入口 |
| 知道函数名、事件名、错误文案 | rg |
精确、完整、可枚举 |
| 要做结构性重构 | ast-grep |
需要 AST 级别匹配,不能靠文本近似 |
| 要确认一个功能是否存在 | ace + 读文件 + rg |
语义命中不能证明功能存在 |
我特别在 README 里写了边界:ACE 只生成候选文件,证据还要从代码和测试里确认。这个边界很重要。
语义检索会返回“相近”的东西。你问一个不存在的功能,它也可能找出看起来相关的文件。如果 agent 把“有结果”理解成“功能存在”,后面就会开始编故事。只有读到实现、测试、路由、配置或调用点,结论才算站得住。
它在 Harness Engineering 里的位置 #
ace-wrapper 很小,也不该变成平台。它更像 harness 里的一个小齿轮:把“开放式找代码”这件事变成可重复、可约束的命令。
我现在更喜欢这样的项目规则:
Read -> Search -> Change -> Verify其中 Search 要按问题类型选工具:
- 开放式、行为式、跨层链路:先
ace - 精确标识、报错、路由、配置:用
rg - 结构性替换:用
ast-grep - 外部策略和行业做法:用 web research
- 旧决策、历史踩坑:用 memory
这套分工能减少 agent 的随机性。它先用语义检索缩小读文件范围,再用确定性工具确认事实,最后才动代码。
对 agent 来说,最重要的是提示方式 #
好的 ace query 要把行为讲完整,不能只堆关键词:
timeout 60s ace "frontend sends requestId to backend and starts a processing job" -w /repo
timeout 60s ace "用户拖入不支持的文件后应该显示跳过文件提示" -w /repo
timeout 60s ace "how provider config is persisted and restored after app restart" -w /repo我会尽量包含四类信息:
- 用户动作:点击、拖拽、上传、停止生成
- 运行边界:frontend to backend、CLI handler to core service
- 预期效果:persist config、abort loop、show skipped-file feedback
- 已知字段:
sessionId、requestId、files、workspace
这比只搜 upload 或 provider 稳得多。它让检索系统按行为和数据流找入口,也提醒 agent:这一步还只是语义检索。
开源它的原因 #
ace-wrapper 的代码量很小,核心就是 FileSystemContext.create(str(workspace)) 加 context.search(args.query)。我更想保存的是这几行 Python 周围的工作流约束:
- 不知道关键词时,先语义检索
- 一次 query 只问一个工作流
- 把结果当候选文件
- 读文件后再用
rg确认精确证据 - 没证据就不要下结论
这些规则放进工具 README、skill 和 agent prompt 后,才会稳定生效。否则每个会话都会重新靠人提醒一遍。
上一篇说 Harness Engineering 是给 AI 外面套工程轨道。ace-wrapper 就是其中一小段轨道:它不让 agent 更会写代码,只是让它更容易先读对地方。