1. 为什么你的 AI 编码助手总在“自由发挥”
如果你用过本地 AI 编码工具,大概率遇到过这些情况:让它改一个函数,它顺手把整个文件重写了;让它输出 diff,它给你一段散文式解释;你明明说了“不要动配置文件”,它转头就去改settings.json。这些不是模型能力问题,而是指令层没搭好。
在 Harness 这套拆解框架里,指令层(Instruction)是六大组件的第一块基石。它回答三个问题:AI 是谁、要做什么、绝对不能做什么。放到本地编码工具场景里,指令层落地成两个具体文件:AGENTS.md负责项目级规矩和人设,settings.json负责运行时把请求接到统一的 Key/API 通道。前者管“行为”,后者管“通路”,缺一不可。
这篇面向正在用本地 AI 编码工具、准备接入统一 API 通道的开发者。我会给出可直接复制的AGENTS.md骨架、settings.json配置片段,以及验证指令层是否真正生效的具体动作。全程围绕一个目标:让 AI 从“随机应变”变成“按规矩执行”。
2. 前置准备:统一 Key/API 通道与项目目录
在写指令之前,先把通路打通。本地编码工具要调用模型,需要一个稳定的 API 入口。我用 TaoToken 作为统一通道,好处是 Key 和模型名集中管理,换模型不用改一堆配置文件。
先拿到 API Key。访问控制台创建:
https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite创建后到 API Keys 页面复制:
https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewriteAPI 基础地址统一用:
https://taotoken.net/api注意这个地址不加 UTM 参数,直接作为base_url写入配置。项目目录建议这样组织,让指令层文件有明确归属:
my-project/ ├── AGENTS.md # 项目级指令层 ├── .agent/ │ └── settings.json # 运行时配置 ├── src/ └── README.mdAGENTS.md放在项目根目录,工具启动时会自动读取。.agent/settings.json放运行时参数,包括 API 通道和模型选择。两者分工清晰:一个定义“怎么做事”,一个定义“通过哪条路做事”。
3. 可复制配置:AGENTS.md 骨架与 settings.json
3.1 AGENTS.md 骨架
下面这份骨架经过实际项目验证,分角色、目标、边界、输出格式四段。你可以直接复制后改业务词。
# 角色 你是本项目的 AI 编码助手,名字叫 DevBot。 你熟悉 TypeScript 与 Node.js,代码风格遵循项目 ESLint 配置。 语气简洁,只讲重点,不寒暄。 # 目标 1. 根据用户描述修改或新增代码,改动范围严格限定在用户指定的文件内。 2. 每次改动前,先用一句话说明你打算改什么、改哪个文件。 3. 输出代码时使用 diff 格式,标明文件路径。 # 边界 - 不要修改 AGENTS.md、settings.json、package.json 之外的配置文件。 - 不要执行 git push、git reset --hard、rm -rf 等破坏性命令。 - 如果用户要求改动超出指定文件范围,回复:“该改动超出当前文件范围,请确认是否继续。” - 不要编造不存在的依赖或 API,不确定时明确说“需要确认”。 # 输出格式 - 先输出改动说明(不超过 50 字)。 - 再输出 diff 代码块,标注语言为 diff。 - 最后输出一句验证建议,例如“运行 npm test 验证”。这份骨架的关键在于边界用了具体禁止项,而不是“注意安全”这种空话。模型对 if-then 式规则执行得更稳。
3.2 settings.json 配置片段
运行时配置把请求接到统一通道。以下片段适用于多数本地编码工具的配置结构:
{ "provider": "openai-compatible", "base_url": "https://taotoken.net/api", "api_key": "sk-你的Key", "model": "claude-sonnet-4-20250514", "instruction_file": "AGENTS.md", "max_tokens": 4096, "temperature": 0.2 }几个参数说明:base_url指向统一通道;instruction_file告诉工具去读根目录的AGENTS.md;temperature设 0.2 是为了让编码任务更稳定,减少自由发挥。如果你做的是长期编码或 Agent 类任务,可以考虑 Coding Plan 方案,额度更适配高频调用:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite配置写完后,工具启动时会先加载AGENTS.md作为 System Prompt 的一部分,再拼接用户输入。这就是指令层的组装过程。
4. 验证指令层是否生效:三个具体动作
配置写完不代表生效。下面三个动作可以快速验证指令层是否真正起作用。
4.1 动作一:越界请求测试
在对话里输入:“帮我把 package.json 里的版本号改成 2.0.0。”
如果指令层生效,AI 应该回复类似:“该改动涉及 package.json,属于配置文件,根据边界规则需要你确认是否继续。”如果它直接改了,说明AGENTS.md没被读取,或者边界写得不够具体。
4.2 动作二:输出格式测试
输入:“给 utils.ts 加一个 formatDate 函数。”
生效时,AI 会先给一句改动说明,再输出 diff 代码块,最后给验证建议。如果它输出一大段散文解释、没有 diff,说明输出格式约束没生效。检查AGENTS.md里“输出格式”段是否被正确解析。
4.3 动作三:角色一致性测试
输入:“你好,今天天气怎么样?”
生效时,AI 应该简短回应并拉回编码任务,比如:“我是 DevBot,专注本项目编码。有代码需要改吗?”如果它开始聊天气,说明角色定义太弱,需要加强“只讲重点,不寒暄”这类约束。
三个动作都通过,说明指令层基本生效。任何一个失败,回到对应段落加具体规则。
5. 本篇常见错排查
5.1 AGENTS.md 没被读取
最常见的原因是文件名或路径不对。确认文件在项目根目录,且settings.json里的instruction_file值与实际文件名一致。有些工具要求文件名全大写,有些要求放在.agent/目录下,以你所用工具的文档为准。
5.2 边界规则被忽略
如果 AI 仍然越界,通常是边界写得太抽象。把“不要做危险操作”改成具体列表:“不要执行 git push、git reset --hard、rm -rf”。模型对具体命令名的识别率远高于抽象描述。
5.3 API 请求 401 或 404
401 一般是 Key 错误或没带对。检查api_key是否完整复制,base_url是否为https://taotoken.net/api。404 通常是路径拼错,确认没有多余斜杠或缺少/api。可以在模型对话页面先测一下 Key 是否可用:
https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite5.4 指令太长导致截断
AGENTS.md如果超过几千字,可能被截断,后面的边界规则就丢了。把最重要的边界放在文件前部,或者拆分成多个文件按需加载。接入文档里有关于指令长度和组装顺序的说明:
https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite5.5 模型不遵守 diff 格式
有些模型对 diff 格式支持不稳定。可以在AGENTS.md里加一个正例,展示期望的 diff 样式。示例比描述更有效。如果仍然不行,换一个对代码格式支持更好的模型,在模型对话页面切换测试。
6. 把指令层当成项目资产来维护
指令层不是写一次就完事。项目在变,规矩也要跟着变。我的做法是把AGENTS.md纳入版本控制,每次调整都提交,方便回滚和对比。团队协作时,谁改了哪条边界一目了然。
另外一个小技巧:把AGENTS.md里的边界规则和 CI 检查对齐。比如边界说“不要改配置文件”,CI 里就加一条检查,确保 AI 提交的 diff 没碰配置文件。指令层管事前,CI 管事中,两层配合才稳。
如果你还在用裸 Key 直连、每个工具配一遍,建议统一到一条通道上。Key 集中管理,模型随时切换,指令层文件跟着项目走。这样换工具、换模型,规矩不用重写。接入方式和配置示例都在文档里,照着改一遍就能跑通。