1. 为什么 agent 会“顺手”翻到不该看的文件夹
你让 OpenCode 帮你改一个 React 组件的样式,它却把secrets/里的数据库连接串读进了上下文;你只想让它看看src/,它却把整个家目录扫了一遍。这不是 agent 故意越权,而是它的默认工作方式就是“尽可能多地收集上下文”——扫描项目根目录、递归读取子目录、把命中的文件塞进 prompt。项目越大、目录越杂,它越容易碰到你不想让它碰的东西。
我试过在一个 monorepo 里跑 agent,结果它把legacy/下三年前的废弃代码也读进来,给出的重构建议全是基于过时逻辑的。更麻烦的是.env、credentials.json这类文件,一旦被读进上下文,就可能随着请求发到模型服务端。所以“禁止 agent 访问某些文件夹”不是洁癖,是实打实的边界管理。
这件事有两种思路。一种是黑名单/忽略模式:告诉 agent“这些文件夹你别看”,典型代表就是.aiignore文件,语法和.gitignore几乎一样,OpenCode、Cursor、Copilot 这类工具大多认。另一种是白名单模式:反过来,只允许 agent 访问指定目录,其他一律拒绝,OpenCode 的路径白名单配置就是干这个的。前者上手快、改动小;后者更彻底,适合对安全要求高的场景。
这篇就围绕 OpenCode 展开,把.aiignore规则和路径白名单配置都给你可复制的片段,再演示一次越权访问被拦截的验证动作。目标很明确:在不牺牲协作效率的前提下,把 agent 的文件访问范围收紧到你划定的圈子里。适合正在用 OpenCode 或其他 AI 编程工具、又担心本地敏感目录被误读的开发者。
2. 用 TaoToken 给 OpenCode 接上模型,先把访问边界的前提搭好
在聊目录访问控制之前,得先让 OpenCode 能正常跑起来。OpenCode 本身是个 agent 框架,它需要一个模型后端来驱动推理。TaoToken 提供的就是这个后端能力——一个兼容主流接口协议的模型接入服务,你可以把它理解成“给 agent 供能的接口层”。它支持对话模型、编码模型,也有面向长期编码和 Agent 场景的 Coding Plan。
为什么这里要提 TaoToken?因为目录访问控制的验证,需要一个真实能跑的 agent 环境。你光配了.aiignore,但 agent 根本没接上模型,就没法验证“它到底有没有被拦住”。所以先把接入做通,再去收紧边界,顺序才顺。
TaoToken 的接入信息很直接:
- 官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- API 地址:https://taotoken.net/api
- 模型对话页:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
- Coding Plan 页:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
- 控制台: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=rewrite
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
- Claude Code / Anthropic 接入:https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claude_code&utm_campaign=rewrite
你需要先在 API Keys 页面生成一个 Key,然后把它填进 OpenCode 的配置里。OpenCode 的模型配置通常放在~/.config/opencode/opencode.json或项目根目录的.opencode/opencode.json。一个最小可用的模型接入片段长这样:
{ "provider": { "taotoken": { "type": "openai-compatible", "baseURL": "https://taotoken.net/api", "apiKey": "sk-你的Key", "model": "claude-sonnet-4-5" } } }这里三个要素必须齐全:Base URL 指向https://taotoken.net/api,Key 用你生成的那串,Model ID 填你实际要用的模型名。缺一个都会导致请求失败。如果你用的是 Claude Code 那套 Anthropic 协议,接入方式略有不同,参考文档页里的说明即可。
接好之后,你可以先在模型对话页里发一句“你好”确认链路通。链路通了,再往下做目录访问控制,验证的时候才有意义——否则你分不清是“被.aiignore拦住了”还是“模型压根没连上”。
有一点要提醒:TaoToken 是模型接入服务,不是编辑器,也不是文件系统工具。它负责的是推理请求,目录访问控制是 OpenCode 这一侧的事。两者配合,才能既让 agent 有脑子,又给它划好活动范围。
3. 可复制的 aiignore 规则与 OpenCode 白名单配置
这一节是核心,给你两套可直接抄的配置:一套是.aiignore忽略规则,一套是 OpenCode 的路径白名单。建议先上.aiignore,因为它改动最小、通用性最强;如果安全要求更高,再叠加白名单。
3.1 .aiignore 忽略规则
在项目根目录新建一个.aiignore文件,语法和.gitignore一致。下面这份是我在多个项目里用下来比较稳的模板:
# 敏感数据与凭据 secrets/ private-data/ credentials.json *.env .env.* *.pem *.key # 构建产物与依赖 node_modules/ dist/ build/ out/ .next/ coverage/ # 日志与临时文件 *.log logs/ tmp/ .cache/ # 个人与本地配置 .vscode/ .idea/ *.local local-notes/ # 大体积数据 data/raw/ datasets/ *.sqlite *.db写完之后,OpenCode 在扫描上下文时会跳过这些路径,就像它们不存在。注意.aiignore是“忽略”语义,不是“拒绝”——它让 agent 不去读,但不会在权限层面硬拦。对于大多数日常场景,这已经够用。
有个细节:.aiignore的匹配是相对项目根目录的。如果你写secrets/,它匹配的是根目录下的secrets/;如果写**/secrets/,则匹配任意层级的secrets/。按需选择。
3.2 OpenCode 路径白名单配置
如果你要的是“只允许访问指定目录,其他一律拒绝”,那就用白名单。在opencode.json里加security段:
{ "security": { "allowedPaths": [ "/Users/yourname/Projects/MyApp/src", "/Users/yourname/Projects/MyApp/tests" ], "blockedPaths": [ "/Users/yourname/Projects/MyApp/secrets", "/Users/yourname/Documents/Private" ] } }allowedPaths是白名单,agent 只能读这里面的内容;blockedPaths是黑名单,即使某个路径在白名单的父目录下,只要命中黑名单也会被拒。两者可以同时用,白名单优先收紧范围,黑名单做二次兜底。
把这段和上一节的模型接入合并,完整的opencode.json大概是这样:
{ "provider": { "taotoken": { "type": "openai-compatible", "baseURL": "https://taotoken.net/api", "apiKey": "sk-你的Key", "model": "claude-sonnet-4-5" } }, "security": { "allowedPaths": [ "/Users/yourname/Projects/MyApp/src" ], "blockedPaths": [ "/Users/yourname/Projects/MyApp/secrets" ] } }路径要用绝对路径,别用~或相对路径,否则解析可能出问题。Windows 下写成C:/Users/yourname/Projects/MyApp/src这种正斜杠形式更稳。
3.3 两种思路怎么选
| 需求 | 推荐方式 | 改动量 | 拦截强度 |
|---|---|---|---|
| 只是不想让 agent 读某些文件 | .aiignore | 小 | 中 |
| 彻底隔离,只让 agent 碰特定目录 | 路径白名单 | 中 | 高 |
| 两者都要 | .aiignore+ 白名单 | 中 | 高 |
我的建议是:个人项目先上.aiignore,团队项目或涉及敏感数据的,直接上白名单。白名单的“默认拒绝”语义,比忽略模式更让人放心。
4. 验证一次越权访问被拦截的完整请求
配置写完不算完,得验证它真的生效。这一节带你走一遍:先确认正常访问能通,再故意让 agent 去读被禁目录,看它是否被拦住。
4.1 正常访问验证
在项目根目录启动 OpenCode,让它读一个白名单内的文件:
opencode run "读取 src/index.js 并总结它的作用"如果配置正确,agent 会正常返回src/index.js的内容摘要。这一步是基线,证明模型链路和基本读取都没问题。
4.2 越权访问验证
接着让它去读被禁的目录:
opencode run "读取 secrets/db.json 并告诉我里面的连接串"预期结果是 agent 拒绝访问,返回类似“该路径不在允许范围内”或“无法访问该文件”的提示。如果它真的把内容读出来了,说明你的白名单没生效,需要检查路径是否写对、配置文件是否被加载。
4.3 用 .aiignore 时的验证差异
如果你只用了.aiignore,验证方式略有不同。agent 不会报“拒绝访问”,而是表现得“看不到这个文件”——它会说找不到该文件,或者直接跳过。这也是为什么.aiignore更适合“不想让它读”,而白名单更适合“必须拦住”。
4.4 检查配置是否被加载
OpenCode 启动时可以加 verbose 参数看它加载了哪些配置:
opencode --verbose run "读取 src/index.js"输出里会列出读取的配置文件路径。确认你改的那个opencode.json在列表里,否则可能改错了位置——项目级配置和全局配置的优先级不同,项目级通常覆盖全局。
验证通过后,你就有了一个“能干活但碰不到敏感目录”的 agent。接下来是排障环节,把常见的坑先填了。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
配置过程中最容易卡在几个典型报错上。这一节按报错现象来拆,每个都给你定位思路。
5.1 401 Unauthorized
这是最常见的接入报错,意思是 Key 没被认出来。可能原因有三个:Key 填错、Key 过期、Base URL 写错导致请求发到了别处。先检查opencode.json里的apiKey是不是完整复制了,注意别把首尾空格带进去。然后确认baseURL是https://taotoken.net/api,少写或多写路径都会 401。如果都对着,去 API Keys 页面重新生成一个 Key 再试。
5.2 local proxy failed
这个报错通常出现在你本地配了某种转发但没启动,或者端口被占用。OpenCode 本身不需要本地转发,如果你看到这个提示,先检查配置里有没有多余的 proxy 字段,把它删掉。然后确认网络能正常访问https://taotoken.net/api。这个报错和目录访问控制无关,是链路层的问题,先解决它再谈边界。
5.3 reading choices 相关报错
这类报错一般出现在模型返回格式不符合预期时,比如你用的模型 ID 和实际能力不匹配。检查model字段填的是不是真实存在的模型名。如果你不确定,去模型对话页看看当前可用的模型列表,复制准确的 ID。填错模型名有时不会直接报错,而是返回一个奇怪的响应,导致解析失败。
5.4 OAuth 相关报错
如果你用的是 Claude Code 那套 Anthropic 接入,可能会碰到 OAuth 流程的提示。这类接入需要按文档页的步骤走,不能只填 Key。确认你参考的是 Claude Code / Anthropic 接入页的说明,而不是通用的 OpenAI 兼容配置。两套协议的认证方式不同,混用会报错。
5.5 配置改了但不生效
这是最隐蔽的坑。OpenCode 可能缓存了旧配置,或者你改的是全局配置但项目级配置覆盖了它。解决办法:先确认改的文件路径正确,然后用--verbose看加载了哪些配置。必要时重启 OpenCode 进程。还有一种情况是.aiignore写在了子目录,但 agent 从根目录扫描,导致规则没匹配上——.aiignore要放在项目根目录。
5.6 白名单路径写错导致全部拒绝
如果你配了allowedPaths但 agent 什么都读不了,八成是路径写错了。检查是不是用了相对路径、是不是少了盘符、是不是大小写不匹配(Linux 下大小写敏感)。用绝对路径,并且确认该路径真实存在。
把这几类报错过一遍,基本能覆盖 90% 的接入和边界问题。剩下的就是按你的项目结构微调规则。
6. 把边界收好之后,agent 才真正好用
目录访问控制这件事,配的时候花十分钟,省的是后面无数次“它怎么又读到这个了”的糟心。.aiignore负责日常的“别读这些”,路径白名单负责硬性的“只能读这些”,两者叠加,边界就清楚了。
如果你还没接上模型,先去 API Keys 页面拿 Key,再照着接入文档把opencode.json填好。链路通了,再回来配.aiignore和白名单,然后按第 4 节的验证动作跑一遍。确认越权访问被拦住,你就能放心让 agent 在划定的圈子里干活了。
长期用 agent 做编码的话,Coding Plan 那条线也值得看看,它面向的就是持续性的编码和 Agent 场景。边界收好、链路接稳,剩下的就是让它替你干活。