1. 报错现场还原:agent 启动时提示 not in a git repository 到底卡在哪
这个报错我第一次遇到时也愣了一下,因为终端里明明能看到.git目录,agent 却坚持说自己不在 git 仓库里。完整报错长这样:
Error: Cannot create agent worktree: not in a git repository and no WorktreeCreate hooks are configured. Configure WorktreeCreate/WorktreeRemove hooks in settings.json to use worktree isolation with other VCS systems拆开看,它其实在说两件事。第一,agent 想给子任务开一个独立的 worktree 做隔离,但检测不到当前目录属于 git 仓库;第二,它退一步想用WorktreeCreatehooks 来自定义 worktree 的创建逻辑,结果settings.json里也没配。两条路都断了,于是直接抛错。
为什么 agent 非要 worktree?你可以把 worktree 理解成「同一个仓库的多个平行工作台」。主 agent 在main分支上跑,子 agent 需要改文件、跑测试,如果都在同一个目录里操作,文件会互相覆盖,git 状态也会打架。worktree 让每个 agent 拿到一份独立的工作目录,共享同一个.git对象库,互不干扰。这就是「worktree isolation」的价值。
那什么情况下会触发这个报错?我实测下来主要有三类场景。一是你在一个普通文件夹里直接启动 agent,这个文件夹从来没执行过git init,比如你新建了一个demo-agent/目录就开始写代码。二是你在一个 git 仓库的子目录里启动,但 agent 的工作目录被设成了子目录,而 git 仓库根在更上层,检测逻辑没往上找。三是你用的是非 git 的版本控制系统,比如 Mercurial 或者纯文件快照方案,agent 默认的 git 检测自然失败,这时候就必须靠 hooks 兜底。
面向本地多 agent 协作的场景,这个问题尤其常见。你可能是想让一个 agent 写后端、一个 agent 写前端、一个 agent 专门跑测试,三个 agent 并行。如果没有 worktree 隔离,它们会抢同一份文件。所以报错本身不是坏事,它是在提醒你:隔离机制没配好,先别急着并行。
排查的第一步永远是确认当前目录的 git 状态。打开终端,在 agent 启动的那个目录下执行:
git rev-parse --is-inside-work-tree如果输出true,说明你在一个 git 工作树里;如果输出fatal: not a git repository (or any of the parent directories): .git,那就是真的不在仓库里。再补一条确认仓库根位置:
git rev-parse --show-toplevel这条命令会打印仓库根目录的绝对路径。如果你发现打印出来的路径和你以为的工作目录不一致,那问题就找到了——agent 在子目录里找.git,没找到。搞清楚这两条命令的输出,你就知道该走「初始化仓库」还是「配 hooks」这条路了。
2. TaoToken 前置准备:把 Base URL、Key、Model ID 三件套配齐
在动手改settings.json之前,先把模型接入这条链路理顺,否则你修好了 worktree 报错,agent 一跑又卡在鉴权上。我用的是 TaoToken 做模型接入,官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。
接入的核心就三样东西,我习惯叫它「三件套」:Base URL、API Key、Model ID。任何 agent 工具要连模型,都绕不开这三个参数。Base URL 告诉工具往哪发请求,API Key 证明你有权限,Model ID 决定用哪个模型。三者缺一,请求要么 401,要么 404。
先说 Key 怎么拿。进控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,在 API Keys 页面创建一个新 key。创建时给它起个能认出来的名字,比如local-agent-dev,方便以后区分是哪个项目在用。创建完立刻复制,页面刷新后就看不全了。这个 key 就是后面填进配置里的凭证。
Base URL 这块要注意,不同工具的填法略有差异。有的工具要求填到/api这一层,有的要求填到/v1。TaoToken 的 API 根是https://taotoken.net/api,具体到某个工具的配置项,以该工具的文档为准。我一般先在模型对话页面 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 确认一下当前可用的模型列表,把 Model ID 抄准。Model ID 是大小写敏感的,抄错一个字母就是 404。
如果你是要长期跑编码类 agent,比如让多个 subagent 并行改代码,那 Coding Plan 会更合适,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。它针对编码场景做了额度上的优化,比按量计费更适合高频调用。我自己的习惯是:临时验证用按量,长期跑 agent 用 Coding Plan。
配好三件套之后,先别急着配 hooks。用模型对话页面发一条最简单的请求,确认 key 和 model 是通的。这一步能帮你把「模型接入问题」和「worktree 配置问题」彻底分开。很多人一上来就改 settings.json,改完还是报错,最后发现是 key 填错了,白白绕一圈。先验证模型通,再修 worktree,顺序不能反。
3. 可复制配置:settings.json 里 WorktreeCreate hooks 怎么写
现在进入正题。报错信息明确说了「Configure WorktreeCreate/WorktreeRemove hooks in settings.json」,所以我们要在settings.json里补上这两个 hook。先给一个最小可用的配置片段,你可以直接抄:
{ "hooks": { "WorktreeCreate": [ { "matcher": "*", "hooks": [ { "type": "command", "command": "bash -lc 'git worktree add \"$WORKTREE_PATH\" -b \"$WORKTREE_BRANCH\" HEAD'" } ] } ], "WorktreeRemove": [ { "matcher": "*", "hooks": [ { "type": "command", "command": "bash -lc 'git worktree remove --force \"$WORKTREE_PATH\"'" } ] } ] } }这段配置的含义:当 agent 需要创建 worktree 时,执行git worktree add,用$WORKTREE_PATH作为新工作目录,$WORKTREE_BRANCH作为新分支名,基于当前HEAD创建。删除时执行git worktree remove --force。matcher填*表示对所有 agent 生效。
这里有几个坑我踩过,提前说。第一,$WORKTREE_PATH和$WORKTREE_BRANCH是 agent 运行时注入的环境变量,不同工具注入的变量名可能不一样。如果你发现命令执行了但路径是空的,先打印一下环境变量确认名字:
env | grep -i worktree第二,bash -lc里的-l会加载登录 shell 的配置,有时候会拖慢启动甚至引入意外的 PATH。如果你不需要登录 shell,可以改成bash -c。第三,Windows 环境下bash不一定存在,得换成powershell -Command或者用 Git Bash 的完整路径。
如果你用的是非 git 的版本控制系统,比如 Mercurial,那 hook 命令就要换成对应的hg命令。但大多数本地多 agent 场景还是 git,所以上面这段够用。
配置文件的路径也要注意。不同工具读的settings.json位置不一样,常见的有项目根目录下的.claude/settings.json、用户目录下的~/.claude/settings.json,或者工具自己的配置目录。你得确认 agent 实际读的是哪一个。一个笨但有效的办法:在配置里故意写个语法错误,看报错信息里提到的路径是哪个,那就是它读的文件。
另外,如果你同时用 Cline MCP 或者 Codex 这类工具,它们的配置格式可能是 TOML 或者auth.json。比如 Codex 的auth.json里要填 Base URL 和 Key,Cline 的 MCP 配置里要写 Model ID。不管哪种格式,三件套的逻辑不变:Base URL 指向https://taotoken.net/api,Key 用你创建的那个,Model ID 抄准。把这些配齐,再回到 hooks 这块,链路才是完整的。
配完保存,别急着启动 agent。先用jq校验一下 JSON 语法,避免因为一个逗号导致整个配置不生效:
jq . .claude/settings.json如果jq报解析错误,就按提示的行号去修。JSON 不允许尾随逗号,这是最常见的低级错误。
4. 逐步验证:从 git init 到 agent 成功创建 worktree
配置写好了,现在按顺序验证。第一步,确认 git 仓库就绪。如果你之前不在仓库里,先初始化:
git init git add . git commit -m "Initial commit"这三条命令做完,git rev-parse --is-inside-work-tree应该输出true。注意git commit需要你先配好user.name和user.email,否则会报「Please tell me who you are」。配一下:
git config user.name "your-name" git config user.email "you@example.com"第二步,确认 hooks 配置被正确加载。启动 agent,让它创建一个 subagent。如果配置生效,你应该能看到类似这样的输出:
Creating worktree at /path/to/repo/.worktrees/agent-1 Preparing worktree (new branch 'agent-1')然后git worktree list会列出主工作树和新建的 worktree:
git worktree list输出大概是这样:
/path/to/repo abc1234 [main] /path/to/repo/.worktrees/agent-1 def5678 [agent-1]看到第二行,说明 worktree 创建成功了。第三步,验证子 agent 能在自己的 worktree 里独立改文件。让子 agent 在它的工作目录里创建一个测试文件,然后回到主目录看,主目录里不应该有这个文件。这就是隔离生效的证据。
第四步,验证删除。让 agent 结束子任务,触发WorktreeRemove。再跑一次git worktree list,那个 agent-1 的条目应该消失了。如果没消失,手动清理:
git worktree remove --force .worktrees/agent-1 git branch -D agent-1第五步,验证模型请求。在子 agent 里发一条消息,确认它能正常调用模型。如果这里报 401,说明 key 有问题;报 404,说明 Model ID 错了;报连接超时,检查 Base URL 是不是https://taotoken.net/api。这一步把 worktree 隔离和模型接入两条链路都验证了。
我实测下来,整个流程走通后,多个 subagent 并行改代码非常顺。每个 agent 在自己的 worktree 里跑测试、改文件,主分支不受影响,最后再决定合并哪个。这套机制对本地多 agent 协作来说是刚需,不是可选项。
5. 常见报错对照排查:401、local proxy failed、reading choices、OAuth
修 worktree 的过程中,你可能会撞上其他报错。我把几个高频的列出来,对照着排。
401 Unauthorized。这个基本就是 key 的问题。检查三处:key 有没有复制全、有没有多余空格、Base URL 是不是对的。如果你用的是环境变量注入 key,确认变量名和配置里引用的一致。有时候 key 创建后没保存,页面刷新就丢了,只能重建一个。
local proxy failed。这个报错通常出现在你本地起了代理转发,但转发目标配错了。检查你的代理配置里 Base URL 是不是https://taotoken.net/api,端口有没有被占用。如果你没主动起代理,那可能是某个工具自带的转发层,去它的配置里找proxy相关字段。
Error reading choices。这个多半是响应格式不对。常见原因是 Model ID 填了一个不存在的模型,服务端返回了错误结构,客户端按正常结构解析就崩了。去模型对话页面确认 Model ID,重新填。另一个可能是 Base URL 少了/v1或者多了/v1,导致请求打到了错误的端点。
OAuth 相关报错。如果你用的是 Claude Code 这类带 OAuth 流程的工具,报错可能出在 token 刷新上。检查你的 OAuth 配置有没有过期,重新走一遍授权。注意 OAuth 和 API Key 是两套鉴权,别混用。如果你已经用 API Key 接入了,就不需要再走 OAuth。
worktree 创建了但 agent 说找不到。这通常是路径问题。$WORKTREE_PATH如果是相对路径,agent 的工作目录一变就找不到了。在 hook 命令里尽量用绝对路径,或者先cd到仓库根再执行。
hooks 配了但没生效。先确认配置文件路径对不对,再确认 JSON 语法对不对,最后确认matcher有没有匹配上。有的工具要求matcher填具体的 agent 名字,填*反而不生效。这种情况去看工具的文档,确认 matcher 的匹配规则。
排查的核心思路是「分层隔离」:先确认 git 层没问题,再确认 hooks 层没问题,最后确认模型接入层没问题。一层一层往下查,别跳步。每修一层,跑一次验证命令,确认这层通了再动下一层。
6. 把配置沉淀成模板:多 agent 协作的长期实践
worktree 报错修好之后,建议你把整套配置沉淀成一个模板,下次新项目直接抄。我自己的做法是在仓库里放一个.claude/settings.json,把 hooks 和模型接入都写进去,然后提交到 git。这样团队里其他人拉下来就能用,不用每人配一遍。
模板里除了WorktreeCreate和WorktreeRemove,还可以加上一些常用的 hook,比如任务开始前自动拉最新代码、任务结束后自动跑 lint。但别加太多,hook 越多启动越慢,按需加。
模型接入这块,长期跑编码 agent 的话,Coding Plan 比按量更划算,入口在 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。Key 的管理建议一个项目一个 key,方便排查和吊销。Key 列表在 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 相关的接入说明也有专门页面:https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_content=claude-code-anthropic&utm_campaign=rewrite 。遇到不确定的参数,先查文档再改配置,比瞎试快得多。
最后说个实用技巧:把git worktree list和git worktree prune加进你的日常命令。worktree 用多了会残留一些失效条目,prune能清理掉。定期跑一下,保持仓库干净。多 agent 协作的稳定性,往往就藏在这些小习惯里。