☰
我们为什么需要一只 Codex 桌面宠物:用 Hooks 把 Agent 状态改到 TaoToken
2026/10/15 9:59:31 网站建设 项目流程

1. 从盯终端到看宠物:Agent 状态可视化到底解决什么问题

Codex 桌面宠物是什么?简单说,它是 Codex 桌面版里的一个状态可视化组件,把 Agent 会话的运行状态映射成一只小动物的动作。它能做什么?让你不用反复切回终端,就能知道当前任务是还在跑、需要你批准、已经完成,还是直接报错挂了。适合谁?适合那些一次派活给 Agent 要跑几分钟到几十分钟、同时手上还开着好几个会话的开发者。

我自己的日常是这样的:早上开三个 Codex 会话,一个跑测试,一个改前端组件,一个在整理接口文档。以前的做法是每隔一会儿切一遍窗口,看哪个跑完了、哪个卡在权限确认上。这种人工轮询最要命的地方不是费时间,而是你没法真正切走——注意力一旦离开,再回来就要重新加载上下文,成本比想象中高。

Codex 宠物把这件事变成了事件驱动。它用四种状态反映会话情况:

状态含义对应动作
Running会话正在工作跑步
Needs input需要你批准、回答或做决定挥手
Ready已完成且有未读活动待机提示
Blocked失败或遇到系统错误低落晃动

多个对话并发时,优先级是 needs input > blocked > ready > running,也就是最需要人介入的排最前。这个优先级设计很关键,它把 Agent 的进程状态翻译成了人的注意力优先级。你不用去数进程、翻日志,眼角余光扫一下桌面就知道该处理哪个。

但这里有个前提:宠物显示的状态,来自 Agent 实际发出的事件。如果 Agent 的请求根本没走到你配置的 endpoint,或者鉴权失败,宠物可能一直显示 Running,实际上任务早就断了。所以状态可视化的第一步,不是捏宠物,而是确保 Agent 的事件链路是通的、可观测的。这也是为什么我把 endpoint 和 auth.json 统一改到 TaoToken 的原因——请求走哪里、用哪个 Key、调哪个模型,全部可控,宠物显示的状态才可信。

这一篇就按这个思路走:先讲清楚状态可视化背后的信号链路,再给一套可复制的 Hooks 配置,把 Codex 和 Claude Code 的事件接到 TaoToken,最后做一次本地验证,确认事件能正确触发。全程可以跟着做,不需要你先把宠物捏出来。

2. 把 Codex 与 Claude Code 的请求接到 TaoToken

在配 Hooks 之前,得先把 Agent 的请求出口固定下来。原因很直接:Hooks 捕获的是 Agent 运行事件,而这些事件背后是一次次模型请求。如果请求的 endpoint、Key、模型 ID 是散的,排障时你根本分不清是 Hooks 没触发,还是请求本身就没发出去。

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。这三件套在 Codex、Claude Code、Cline 这类工具里是通用的配置逻辑,只是文件位置和字段名不同。

先拿 Key。打开 https://taotoken.net/api-keys ,创建一个新的 API Key,复制出来。注意这个 Key 只在创建时完整显示一次,丢了就得重建。拿到之后,建议先放到环境变量里,避免直接写死在配置文件里被误提交:

export TAOTOKEN_API_KEY="sk-你的key"

然后是 Codex 的 auth.json。Codex 的鉴权信息通常放在用户目录下的 .codex/auth.json,路径大致是 ~/.codex/auth.json。如果你用的是自定义 endpoint,需要把 base_url 指向 TaoToken 的 API 地址,同时把 key 填进去。一个可参考的结构如下:

{ "OPENAI_API_KEY": "sk-你的key", "OPENAI_BASE_URL": "https://taotoken.net/api" }

注意字段名可能随 Codex 版本变化,有的版本用 base_url,有的用 OPENAI_BASE_URL。改完之后不要靠猜,直接用一次请求验证。Claude Code 这边则是通过环境变量或 settings.json 指定 base URL 和 Key,常见做法是在 shell 配置里写:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的key"

Model ID 也要显式指定。Codex 和 Claude Code 默认会用自己的模型名,如果你走 TaoToken,需要确认你用的模型 ID 在 TaoToken 的模型列表里存在。可以在 https://taotoken.net/doc 查接入文档,或者在 https://taotoken.net/console 里看可用模型。模型 ID 写错最典型的表现就是请求返回 404 或 model not found,而 Hooks 那边看起来一切正常,宠物一直 Running,实际请求早就失败了。

这里有个我踩过的坑:一开始我只改了 base URL,没改 Key,结果请求一直 401。Hooks 的 Notification 事件照样触发,因为 Claude Code 认为它发出了通知,但通知内容是鉴权失败。所以宠物显示 Needs input,我点进去一看是 401,白紧张一场。后来我把三件套统一在一处管理,排障路径就清晰了:先看请求通不通,再看 Hooks 触发没触发。

如果你同时用 Codex 和 Claude Code,建议把 endpoint 和 Key 的配置写成一个可复用的片段,比如放在 ~/.agent-env.sh 里,两个工具都 source 它。这样改一次,两边都生效,不会出现 Codex 走 TaoToken、Claude Code 还在走旧地址的情况。

3. 可复制的 Hooks 配置:让事件真正触发

Hooks 是 Claude Code 暴露事件的方式,Codex 桌面宠物则通过内置事件驱动状态显示。两者机制不同,但目标一致:在 Agent 状态变化时,主动通知你。这一节给一套可以直接复制的配置,重点是让事件能触发、能验证。

Claude Code 的 Hooks 配置写在 ~/.claude/settings.json 或项目级 .claude/settings.json 里。和状态通知最相关的两个事件是 Notification 和 Stop。Notification 在 Claude 发通知时触发,可以用 matcher 区分 permission_prompt(要你批准工具调用)和 idle_prompt(等你输入)。Stop 在 Claude 完成一轮回复时触发,适合做任务跑完的提醒。

下面是我自用的配置片段,直接复制到 settings.json:

{ "hooks": { "Notification": [ { "matcher": "permission_prompt|idle_prompt", "hooks": [ { "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/notify.sh" } ] } ], "Stop": [ { "hooks": [ { "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/notify.sh" } ] } ] } }

注意 ${CLAUDE_PROJECT_DIR} 这个变量,它指向当前项目根目录。如果你把脚本放在用户级目录,也可以写绝对路径。关键是路径要真实存在,否则 Hooks 会静默失败,你什么都看不到。

然后是 notify.sh 脚本。它的作用是从 stdin 拿到 JSON,取出 message 字段,扔给系统通知。macOS 用 osascript,Linux 可以用 notify-send。先给 macOS 版本:

#!/bin/bash input=$(cat) message=$(echo "$input" | jq -r '.message // "任务执行完成"') osascript -e "display notification \"${message}\" with title \"Claude Code\" sound name \"Glass\"" exit 0

Linux 版本把最后一行换成:

notify-send "Claude Code" "${message}"

给脚本加执行权限:

chmod +x .claude/hooks/notify.sh

这里依赖 jq 来解析 JSON。如果没装,macOS 用 brew install jq,Ubuntu 用 apt install jq。没有 jq 的话,脚本会拿不到 message,通知内容就变成默认值,虽然也能弹,但信息量少很多。

Codex 这边,桌面宠物的状态来自会话事件,你不需要自己写 Hooks 脚本,但需要确保 Codex 的请求出口是 TaoToken。Codex 的配置里,base URL 和 Key 决定请求发往哪里。如果你用的是 Codex 桌面版,可以在 Settings 里找模型或 API 配置项,把 endpoint 改成 https://taotoken.net/api ,Key 填你创建的 Key,Model ID 填你在 TaoToken 控制台看到的模型名。

如果你用 Cline 或类似插件,配置逻辑一样,三件套齐全即可。Cline 的 MCP 配置里,Base URL、Key、Model ID 分别对应不同字段,缺一不可。Codex 的 auth.json 如果出现 OAuth 相关报错,通常是鉴权方式没选对,改成 API Key 方式即可。

配置完成后,先别急着捏宠物。先做一次最小验证:手动触发一次 Notification 事件,看脚本有没有执行。方法很简单,在 Claude Code 里发起一个需要权限确认的操作,比如让它执行一个 shell 命令。如果配置正确,你应该看到系统通知弹出,同时终端里显示通知发送状态。

4. 本地验证:确认事件能正确触发

配置写完不验证,等于没配。这一节做一次完整的本地验证,确认 Hooks 事件能正确触发,同时确认请求确实走到了 TaoToken。

第一步,验证脚本本身能跑。直接在终端里模拟一次 stdin 输入:

echo '{"message":"测试通知"}' | .claude/hooks/notify.sh

如果系统通知弹出「测试通知」,说明脚本没问题。如果没弹,先检查 jq 是否安装、脚本是否有执行权限、osascript 或 notify-send 是否可用。这一步排掉脚本层面的问题,后面就不用怀疑脚本了。

第二步,验证 Claude Code 能触发 Notification。在项目里启动 Claude Code,让它做一个需要批准的操作。比如输入「帮我删除临时目录下的 log 文件」,Claude 会请求执行 rm 命令,这时应该触发 permission_prompt。观察两件事:终端里是否显示通知发送状态,系统通知是否弹出。如果终端显示了但通知没弹,问题在脚本;如果终端没显示,问题在 settings.json 的路径或 matcher。

第三步,验证 Stop 事件。让 Claude Code 完成一个简单任务,比如「读一下 README 并总结三句话」。任务结束时应该触发 Stop,弹出完成通知。这一步验证的是任务完成通知链路。

第四步,验证请求走的是 TaoToken。这一步容易被忽略,但很关键。打开 https://taotoken.net/console ,看请求日志里有没有刚才那几次调用的记录。如果有,说明 endpoint 和 Key 配置正确,请求确实到了 TaoToken。如果没有,说明请求还在走旧地址,或者 Key 无效。常见报错是 401,表示 Key 不对;也可能是 local proxy failed,表示本地代理配置有问题,需要检查环境变量里有没有冲突的代理设置。

第五步,验证 Codex 宠物状态。如果你已经配好 Codex 的 endpoint,启动一个会话,让它跑一个稍长的任务。观察宠物动作:Running 时在跑步,需要批准时挥手,完成时待机,失败时低落。如果宠物一直 Running 但任务实际已经结束,大概率是请求没走通,或者事件没被宠物捕获。回到 console 看请求日志,确认请求是否成功。

这里有个细节:Codex 宠物的状态优先级是 needs input > blocked > ready > running。如果你同时开多个会话,宠物会显示最需要你介入的那个。验证时可以故意开两个会话,一个跑长任务,一个触发权限确认,看宠物是否切到挥手状态。

验证通过后,你就有了一个可信的状态通道:请求走 TaoToken,事件通过 Hooks 触发,宠物或系统通知把状态推给你。这时候再去捏宠物,才有意义——因为你知道它显示的状态是真实的。

5. 常见报错排查:401、local proxy failed、reading choices、OAuth

配置过程中最容易卡在几个固定报错上。这一节按真实报错逐个拆,给出排查路径。

401 是最常见的。表现是请求返回 Unauthorized,Hooks 可能照常触发,但通知内容是鉴权失败。原因通常是 Key 不对、Key 过期、或者 Key 没填对位置。排查顺序:先确认环境变量里的 Key 和 TaoToken 控制台里创建的一致;再确认配置文件里引用的变量名没写错,比如 ANTHROPIC_API_KEY 和 OPENAI_API_KEY 不能混;最后确认 Key 没有多余空格或换行。如果用的是 auth.json,检查 JSON 格式是否合法,可以用 jq . ~/.codex/auth.json 验证。

local proxy failed 通常和本地代理配置有关。表现是请求发不出去,或者连接被拒绝。排查时先看环境变量里有没有 http_proxy、https_proxy、all_proxy 这类设置,如果有,确认它们指向的地址是否可用。如果你不需要代理,直接 unset 掉再试。另外检查 base URL 是否写成了 https://taotoken.net/api 而不是带路径的完整地址,路径写错也会导致连接失败。

reading choices 这个报错一般出现在流式响应解析阶段。表现是请求发出去了,但客户端读响应时出错。常见原因是模型 ID 不对,或者响应格式和客户端预期不一致。排查时先确认 Model ID 在 TaoToken 的模型列表里存在,再确认客户端版本是否支持该模型的响应格式。如果用的是 Codex 或 Claude Code 的旧版本,升级到最新版通常能解决。

OAuth 相关报错通常出现在 Codex 的 auth.json 配置里。表现是提示 OAuth 鉴权失败或 token 无效。原因是 Codex 可能默认走 OAuth 流程,而你填的是 API Key。解决办法是在配置里显式指定使用 API Key 方式,或者把 auth.json 里的鉴权字段改成 Key 模式。具体字段名参考 https://taotoken.net/doc 的接入文档,不同版本可能略有差异。

还有一个不报错但很迷惑的情况:Hooks 配置了,但事件不触发。排查顺序是:先确认 settings.json 的 JSON 格式合法,可以用 jq . ~/.claude/settings.json 验证;再确认脚本路径存在且有执行权限;最后确认 matcher 写对了,permission_prompt 和 idle_prompt 是区分大小写的。如果用的是项目级配置,确认当前目录下有 .claude/settings.json。

排障的核心思路是分层:先确认请求通不通(看 console 日志),再确认 Hooks 触发没触发(看终端输出),最后确认通知送达没送达(看系统通知)。三层分开查,比一上来就改配置高效得多。

6. 把状态通道用起来:从验证到日常

配置和验证都通过之后,这套状态通道就可以进入日常了。我的用法是:Codex 宠物常驻桌面,负责多会话的状态总览;Claude Code 的 Hooks 通知负责单会话的关键节点提醒。两者互补,宠物看全局,通知看细节。

如果你还没捏宠物,可以按 Codex 的设置流程创建一个。Settings > Pets 里点创建,Codex 会挂载 hatch-pet 技能并开新对话,你用提示词描述想要的形象,它会生成一整套 spritesheet。提示词里建议加负面清单,比如不要额外符号、不要切开四肢、背景必须透明。生成后回到 Settings > Pets 刷新,就能选用了。

但记住,宠物只是显示层。真正决定它显示是否准确的是底层的事件链路。所以每次改完 endpoint 或 Key,都建议回到 https://taotoken.net/console 看一眼请求日志,确认请求确实到了 TaoToken。如果日志里没有记录,宠物显示什么都是假的。

日常使用中,我建议把三件套配置集中管理,改一处生效多处。同时保留一份最小验证脚本,每次改完配置先跑一遍,确认通知能弹、请求能通。这样即使换了项目或换了机器,也能快速恢复状态通道。

最后一步,也是最实际的一步:下次派活给 Agent 之后,试着真的把手从键盘上拿开。去倒杯水,或者处理另一件事。让宠物和通知替你盯着。如果它们没响,说明任务还在跑;如果响了,你再回来处理。这才是状态可视化真正想给你的东西——不是一只可爱的动物,而是一段可以放心切走的注意力。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询