本地编码代理循环:Aider、Ollama、Git工作树与简易回滚功能
一种针对本地编码代理的有界工作流程,通过Aider、Ollama、Git工作树、针对性测试以及简单的恢复路径,确保所有更改均可被审查和撤销。
来源: A Local coding agent workflow with Aider, Ollama, and Git worktrees
先从返回路径开始,稍后再选择模型。一个本地编码代理能够在完成一个小型的、有明确范围的循环任务后证明自己的价值:定位缺陷、进行适度修改、运行相关检查,最后留下可提交或丢弃的差异文件。
实现该循环的保守型技术栈假设仓库已处于 Git 管理之下,并配有专门的测试命令:
- 代理:Aider
- 模型运行环境:Ollama,在本地机器上提供模型服务
- 隔离机制:Git 工作树
- 搜索工具:从仓库根目录运行的
rg - 验证方式:仓库中已有的专门测试命令
- 恢复手段:使用
git diff,之后可选择提交或执行git restore
只有代理和本地运行时是新的。其他一切都是普通的仓库工具,其设置不应变成第二个开发平台。
各角色的职责很简单:Ollama负责提供模型,Aider在Git仓库中运行,工作树则为任务提供独立的检出环境,通常是在专用的分支上,而git restore则可用于将未提交的更改恢复到指定的文件中。这种设计刻意保持简洁,旨在适用于那些需要可审查且可逆的仓库操作。它并非某种基准标准,也不声称这些工具在所有方面都优于其他选择。命令、模型名称以及审批行为还会随着安装版本和本地配置的不同而变化。
可供人工审查的流程
代理的输出应当是开发者能够检查的小规模进展单元,而让机器被广泛且无人监管地访问则与此背道而驰。
流程如下:
- 创建一个独立的工作目录。
- 找到相关实现及其现有的测试用例。
- 明确一个预期结果及其范围限制。
- 在进行任何修改之前先提交计划。
- 批准该计划或对其进行调整。
- 查看差异内容。
- 运行项目检查。
- 提交更改或恢复原状。
这些关键步骤都是按程序执行的:在计划获得批准之前不得进行任何修改,且在查看差异内容和测试用例之前也不得保留任何更改。只有当已安装的代理程序和主机配置确实能够强制执行这些规则时,才能称其为技术控制措施。只有当结果易于验证和撤销时,速度才有意义。
示例:空显示名称
设想有一个TypeScript服务,虽然API应当拒绝接受空显示名称,但它却允许这样的输入。该代码仓库中有一个专门的测试文件以及用于验证的npm脚本。
这项任务并非清理验证相关内容。其要求如下:
拒绝仅包含空格的显示名称,更新现有的测试文件,保持公共 API 不变,并运行相关测试。
这为自动化脚本明确了行为规范、边界条件以及检查项。
为该变更设置独立的检查流程
从主检查流程中:
git worktree add -b fix/display-name-validation ../service-display-name-fix
cd ../service-display-name-fix
工作树是附加在同一个代码库上的第二个工作目录。上述命令会在 fix/display-name-validation 分支上创建 ../service-display-name-fix,从而使主分支仍可用于其他工作。
从现在开始,所有修改、测试结果以及待处理的差异都会与主目录分开。如果该实验被证明毫无意义,可以恢复相关文件,或在确认其状态后删除该工作树。
先找到代码和测试文件
使用代码库自身的术语来设定范围:
rg -n "displayName|display name" src test
假设搜索结果如下:
src/users/validateProfile.ts
test/users/validateProfile.test.ts
边界现已明确。该工具需要那两个文件以及用于验证它们的命令,而那种模糊的、要求探索整个代码库的提示并无实际意义。
在本地 Ollama 模型上启动 Aider
在执行此步骤之前,请确认 Git、Aider、Ollama 以及 rg 已安装,且该机器上可运行 Ollama。所选的模型还必须能与已安装的 Aider 和 Ollama 版本兼容。Aider 提供了关于 Ollama 提供商的说明:请确保目标模型存在于 Ollama 中,然后在工作目录中使用模型名称前的 ollama_chat/ 前缀来启动 Aider。
ollama pull <installed-model>
aider --model ollama_chat/<installed-model>
将 <installed-model> 替换为 Ollama 实际使用的模型标签。两个命令中都会出现相同的标签,因为 Ollama 负责提供该模型,而 Aider 则通过标签名称来选择它。
Aider 可以通过 Git 跟踪其变更。在工作目录中启动它,每次编辑后查看差异,并由人工决定是否提交。
它还提供了聊天内命令、仓库结构图、配置选项以及上下文长度限制控制功能。这些功能有助于导航,但都无法确定任务范围或验证补丁的正确性。
将首次响应转化为计划
利用已安装的 Aider 版本所规定的文件添加流程(而非 Git 的暂存功能),将智能体的上下文限制在相关文件范围内。随后提供一个提示语,说明期望的输出结果、允许的路径以及验证命令:
Task: Fix whitespace-only display names being accepted.
Files in scope:
- src/users/validateProfile.ts
- test/users/validateProfile.test.tsConstraints:
- Preserve the public API.
- Do not edit generated files, lockfiles, deployment configuration, or unrelated tests.
- First, explain the current behavior, name the files you would change, and propose the smallest fix.
- Do not edit files until I approve the plan. Treat this as a required review step, and use any available approval controls in your local agent configuration to enforce it where possible.Validation:
- Run: npm test -- validateProfile
- Report the exact command run, files changed, test result, and any unresolved assumption.
这样的提示可以避免几种常见的问题:任务规模无限扩大、编辑偏离预定路径,以及没有明确验证方法的补丁。
尽早拒绝过于宽泛的计划
一个好的初步回复应类似这样的计划:
1. Inspect src/users/validateProfile.ts to confirm how displayName is validated.
2. Inspect test/users/validateProfile.test.ts for the existing validation-test pattern.
3. Add a failing test for a whitespace-only displayName.
4. Make the smallest validation change required to reject that input.
5. Run npm test -- validateProfile.
在批准任何修改之前,请先询问:
- 该计划是否明确了预期的实现方式和测试内容?
- 它是否仅针对单一功能进行设计?
- 其中是否说明了建议的验证规则变更内容?
如果计划中提到架构迁移、依赖项安装、锁文件更新或与当前任务无关的端点变更,应立即停止处理。应当缩小任务范围,而非批准那些仅看似合理的扩展方案。
差异对比与测试结果是最终成果
一旦计划获得批准,此后每次都需重复相同的审查流程。
仅查看已约定的文件
git diff -- src/users/validateProfile.ts test/users/validateProfile.test.ts
此处预期的结果是针对空输入新增一个测试用例,以及一个能够满足该需求的实现调整。具体调整方式取决于仓库现有的验证规则,因此需确保只有经过修剪后仍为空的输入才会被拒绝,而有效的显示名称则无需修改即可通过。
注意会话总结可能掩盖的内容:
- 尽管有明确禁止,但公共API仍被修改
- 有文件被操作,但超出了约定的列表范围
- 与故障无关的格式调整
- 存在一个从未触发目标行为却能通过测试的新用例
- 存在会同时拒绝合法名称的验证调整
差异对比和测试结果才是最终交付物。代理自动生成的总结仅用于辅助阅读,无法证明其正确性。
运行针对性检查
<repository-focused-test-command>
请用仓库实际使用的命令及文件选择语法替换占位符。
Aider可以在代码更改后自动进行代码检查与测试。这或许能缩短反馈周期,但仓库自身的命令仍是权威标准。
有意保留或放弃该更改
如果差异对比和测试结果均正常:
git status
git add src/users/validateProfile.ts test/users/validateProfile.test.ts
git commit -m "Reject whitespace-only display names"
如果他们不这样做:
git restore src/users/validateProfile.ts test/users/validateProfile.test.ts
由于没有提供源代码,git restore会从HEAD恢复这两个指定文件,仅丢弃这些文件中未提交的修改。在认定实验结果已被放弃之前,请先通过git status查看已暂存的更改、未跟踪的文件以及其他地方的修改。
当整个分支都可以丢弃时,在确认其状态并保存所有值得保留的内容后,即可删除工作树:
git worktree remove ../service-display-name-fix
Git通过其worktree命令来管理关联的工作目录。恢复是常规操作,也正是这一机制使得小型代理实验可以安全地重复进行。
边界:文件系统、权限、上下文
从仓库根目录启动
应在项目目录或其专用worktree中运行该代理。从用户主目录启动并期望命令提示符能自动设定边界是行不通的。
工作目录提供了默认范围,但并不会强制执行任何限制。代理实际能够访问的范围由操作系统权限、工具设置以及现有的沙箱环境决定。
有意识地允许副作用发生
文件写入、依赖项安装、凭证访问、网络使用以及基础设施变更均需经过审慎批准。若代理或主机无法实现此类控制,则应将其视为手动审核步骤,而非技术控制措施。在依赖这些控制之前,请先确认其是否存在。
OWASP将注入攻击列为一项风险,它可能导致支持大语言模型的应用程序做出非预期操作或泄露信息。
实用的基准标准:
- 仅允许读取指定仓库中的文件。
- 写入操作前必须获得批准。
- 会引发副作用的shell命令执行前也需获得批准。
- 网络访问应设置为可选模式。
- 将敏感信息置于代理的常规上下文之外。
这些措施可控制影响范围,但并不对代理的可靠性作出判断。
保持配置简洁且透明
Aider能够读取YAML配置文件、环境文件以及API密钥设置。共享的项目配置应清晰可见、简洁明了,并与机密信息分开存放,且凭证绝不能出现在仓库的指令文件中。最好避免出现大量无人能查看或解释的全局默认设置。
提供任务所需的上下文
仓库结构图有助于Aider了解代码库的架构,而上下文则能限制单次请求所能处理的信息量。对于需要集中解决的特定问题,应提供相关任务、文件、验证命令以及与此次修改相关的所有项目规则。引入生成的文件、各类文档或无关的旧提交通常只会增加混乱。
重复性工作的项目规范
如果同样的工作流程反复出现,应在代码旁边保存已提交的指令文件、可重复使用的提示或任务模板:
Project contract
Goal:
- [Describe one bounded outcome.]Scope:
- You may edit: [paths]
- Do not edit: [paths, generated files, secrets, deployment configuration]Conventions:
- Follow: [formatter, naming, architecture rules]
- Preserve: [public APIs, compatibility constraints]Validation:
- Run: [exact test, lint, type-check, or build command]
- Report: commands run, files changed, failures, and unresolved assumptionsDefinition of done:
- The requested behavior is implemented.
- Relevant checks have run, or the reason they could not run is stated.
- The final response summarizes the diff and any follow-up work.
格式并不重要,关键是要让约束条件清晰可见。
故障模式与后续小步骤
搜索范围过宽。暂停操作,缩小文件列表,然后使用手动搜索得到的路径或标识重新开始。
重构方案过于庞大。在可测试的节点处拆分任务。一个失败的测试、一种行为或一个重构边界,都比整体架构要求更为重要。
修改超出了范围。拒绝该补丁,恢复无关文件,并在下次提示中注明被禁止的路径。
请求执行不安全的命令。在批准之前,先询问该命令会带来什么变化以及为何需要执行它。
检查失败。在允许进一步修改之前,先要求提供故障诊断结果,并明确指出故障原因以及最简化的后续测试方案。
本地推理速度慢。应先缩小任务范围和上下文规模,之后再评估其他模型或运行时设置。此处未进行性能比较,后续的任何比较都应记录测得的延迟时间、所用模型、运行时环境及硬件信息。
那些虽速度更快但会产生更大、更难审查的差异结果的智能体,并未提升工作流程效率。
一次调整一个参数
当搜索、规划、差异对比、测试和恢复等功能表现稳定时,每轮只调整一个变量。如果输出质量是瓶颈,则更换模型;如果相关代码始终被遗漏,则调整上下文策略。只有在多个小型、范围明确的任务都证明提示词并未起到保护作用之后,才能放宽默认的审批要求,且即便如此也需保留差异对比结果、测试数据及回滚功能。最后,在验证命令可信之后,再添加自动化功能。
Aider 的配置对版本很敏感,因此在重复使用之前务必查看其配置页面和版本历史记录页面。需将所有命令、模型标识符及配置选项与当前机器上实际安装的 Aider 和 Ollama 版本进行比对。
决策规则很简单:只有那些能提升任务完成度、可审查性或恢复能力的工具或设置才应保留。