首页/新闻资讯/正文详情

Claude Code 通知总骗我?用 Stop hook + TaoToken 把 VS Code 提醒接进 Telegram

发布时间:2026/9/26 17:17:04 来源:云帆数科 栏目:资讯中心
Claude Code 通知总骗我?用 Stop hook + TaoToken 把 VS Code 提醒接进 Telegram
1. 为什么 Claude Code 的「完成」通知总在骗你如果你同时开着好几个 VS Code 窗口每个窗口里挂一个 Claude Code 会话那你大概率经历过这种场景手机弹出一条「任务完成」你切过去一看终端还在滚日志Bash 命令还在后台跑子代理还在默默干活。你以为它骗你其实是你接的那个 Stop hook 太天真了。问题的根源在于 Claude Code 的 Bash 工具。当它以run_in_backgroundtrue模式运行时会立刻返回一条确认信息类似Command running in background with ID: xxx。这条确认是在命令被派发的那一刻返回的不是执行完的时候。一个天真的 Stop hook 只要匹配到工具结果就当成「已解决」就会把这条确认误读成完成。后台 Agent 子代理还有另一种角度的同样问题它们根本不会发出确认所以只追踪明确「完成」信号的钩子压根看不到它们。结果就是恰恰在你最在意的那类场景——长的、多步骤的、大量依赖后台任务的回合——这个钩子比什么都没有还糟。它在你最需要准确提醒的时候给你一条假消息。这篇要解决的问题很具体让 Claude Code 在 VS Code 里真正跑完、真正卡住、真正报错的时候通过 Telegram 给你一条可信的通知而不是一条「狼来了」。核心手段是 Stop hook SubagentStop hook 配合会话记录解析再通过 TaoToken 统一管理 API Key 和模型接入让整个链路可复制、可验证。适合谁并行跑多个 Claude Code 会话的开发者、依赖长时间自主回合的 TDD 工作流用户、以及被「假完成」通知坑过的人。2. 先把 TaoToken 的 Key 和 API 配好在写 hook 之前得先保证 Claude Code 本身能稳定调用模型。我试过把 Key 散落在各个项目的环境变量里换一个窗口就要重新配一次后来统一走 TaoToken 的 API 入口一个 Key 管所有会话。TaoToken 的 API 地址是https://taotoken.net/api注意这个地址不带任何查询参数。你需要在 Claude Code 的配置里把 base URL 指向它然后用同一个 Key 去调不同的模型。这样做的好处是hook 脚本里不需要再关心模型是哪个、Key 是哪个通知逻辑和模型调用解耦。具体操作分两步。第一步去控制台创建一个 API Key地址是https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsole。创建完之后复制那串 Key后面配置里要用。第二步在 Claude Code 的 settings.json 里配置 API 端点。这个文件通常在~/.claude/settings.json如果你用的是项目级配置就在项目根目录的.claude/settings.json。配置片段如下{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoToken密钥 } }这里有个坑要注意ANTHROPIC_BASE_URL后面不要加/v1或者任何路径TaoToken 的 API 入口已经处理好了路由。加了反而会 404。配好之后你可以先用一条 curl 验证 Key 是否有效别等到 hook 写完才发现 Key 是错的。curl -s -X POST https://taotoken.net/api/v1/messages \ -H x-api-key: sk-你的TaoToken密钥 \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 32, messages: [{role: user, content: ping}] }如果返回里带content字段说明 Key 和端点都通了。这一步过了再往下走否则后面 hook 调不通你会以为是 hook 的问题。3. 可复制的 settings.json hook 骨架现在进入正题。Claude Code 的 hook 配置写在 settings.json 的hooks字段里。我们要接两个事件Stop和SubagentStop。但前面说了原生的 SubagentStop 对后台代理不可靠所以真正的判断逻辑要放在脚本里通过解析会话记录来算 pending 和 resolved。先看 settings.json 的完整骨架{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoToken密钥 }, hooks: { Stop: [ { matcher: , hooks: [ { type: command, command: python3 ~/.claude/hooks/notify_stop.py } ] } ], SubagentStop: [ { matcher: , hooks: [ { type: command, command: python3 ~/.claude/hooks/notify_subagent.py } ] } ] } }matcher留空表示匹配所有情况。command指向你的 Python 脚本。这里用 Python3 是因为它解析 JSON 会话记录最方便而且 macOS 和 Linux 都自带。接下来是notify_stop.py的核心逻辑。它的任务是读取当前会话的 transcript 文件找出所有run_in_backgroundtrue的 Bash 调用和子代理调用然后检查有没有对应的task-notification携带原始tool_use_id。只有全部 resolved 了才发 Telegram。#!/usr/bin/env python3 import json import os import sys import urllib.request TRANSCRIPT_DIR os.path.expanduser(~/.claude/projects) TELEGRAM_TOKEN os.environ.get(TELEGRAM_BOT_TOKEN, ) TELEGRAM_CHAT_ID os.environ.get(TELEGRAM_CHAT_ID, ) def load_transcript(session_id): # 遍历项目目录找到对应 session 的 jsonl 文件 for root, dirs, files in os.walk(TRANSCRIPT_DIR): for f in files: if session_id in f and f.endswith(.jsonl): path os.path.join(root, f) with open(path, r, encodingutf-8) as fh: return [json.loads(line) for line in fh if line.strip()] return [] def compute_pending(records): launched set() resolved set() for rec in records: # 收集后台 Bash 的 tool_use_id if rec.get(type) tool_use: inp rec.get(input, {}) if inp.get(run_in_background) is True: launched.add(rec.get(id)) # 收集 task-notification 里携带的原始 id if rec.get(type) task-notification: resolved.add(rec.get(tool_use_id)) return launched - resolved def send_telegram(text): if not TELEGRAM_TOKEN or not TELEGRAM_CHAT_ID: return url fhttps://api.telegram.org/bot{TELEGRAM_TOKEN}/sendMessage payload json.dumps({chat_id: TELEGRAM_CHAT_ID, text: text}).encode() req urllib.request.Request(url, datapayload, headers{Content-Type: application/json}) urllib.request.urlopen(req, timeout10) def main(): raw sys.stdin.read() event json.loads(raw) if raw.strip() else {} session_id event.get(session_id, ) records load_transcript(session_id) pending compute_pending(records) if pending: # 还有后台任务没回来保持沉默 sys.exit(0) cwd event.get(cwd, unknown) send_telegram(fClaude Code stopped | {cwd}) if __name__ __main__: main()notify_subagent.py可以复用同一套逻辑只是触发时机不同。关键点在于不要相信 SubagentStop 事件本身携带的完成信号而是回到会话记录里按tool_use_id匹配。这是目前唯一靠得住的信号。Telegram 的 Bot Token 和 Chat ID 不要写死在脚本里用环境变量注入。你可以在~/.claude/hooks/config.env里存然后在 shell 启动脚本里 source 它。这样 token 不会被误提交到 git。4. 验证通知真的到达而不是误报配好之后别急着跑长任务。先用一条 curl 验证 Telegram 链路本身是通的curl -s -X POST https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage \ -d chat_id${TELEGRAM_CHAT_ID} \ -d textClaude Code notify test手机收到这条消息说明 Bot 和 Chat ID 没问题。收不到就检查 Bot 有没有被拉进目标会话、Chat ID 是不是对的。然后验证 hook 逻辑。开一个 Claude Code 会话让它跑一个后台命令# 在 Claude Code 里输入 run this in background: sleep 30 echo done这时候 Stop hook 会触发但因为sleep 30还在跑compute_pending会返回非空集合脚本保持沉默。你应该收不到任何通知。等 30 秒后命令真正结束会话记录里出现task-notification再触发一次 Stop这时候才会发消息。如果你在 30 秒内就收到了「完成」说明 pending 计算有问题大概率是tool_use_id匹配没对上。检查会话记录里task-notification的字段名是不是tool_use_id不同版本的 Claude Code 可能有细微差异。再验证错误场景。故意让一个回合报错比如在 Claude Code 里请求一个不存在的文件路径触发错误终止。这时候错误 hook 应该发一条带项目路径和回合标题的消息。这条消息的价值在于当你的账号撞上用量限制、多个会话同时卡住的时候你能在手机上一次性看到哪些项目、哪些任务出了问题而不是一个个窗口点进去撞红墙。5. 本篇常见错排查通知来得太早命令还在跑。这是最典型的症状原因是 hook 把 Bash 的即时确认当成了完成。检查你的compute_pending是不是只收集了run_in_backgroundtrue的调用以及task-notification的匹配字段是否正确。如果匹配字段写成了id而不是tool_use_id就会永远算不出 resolved导致 hook 永远沉默——这比误报好但也不对。SubagentStop 完全不触发。后台代理会绕过 Stop 和 SubagentStop这是 Claude Code 本身已知的行为不是你配置的问题。所以不要依赖 SubagentStop 来做完成判断把它当成一个辅助信号真正的判断回到会话记录解析。Telegram 收不到消息但 curl 能通。检查 hook 脚本里的环境变量有没有被正确加载。Claude Code 启动 hook 时的环境变量继承自父进程如果你在.zshrc里 export 了 token但 Claude Code 是从 GUI 启动的可能读不到。稳妥做法是把 token 写在~/.claude/hooks/config.env在脚本开头手动读取。会话记录找不到。TRANSCRIPT_DIR的路径在不同系统上不一样。macOS 和 Linux 通常在~/.claude/projectsWindows 在%USERPROFILE%\.claude\projects。如果你的 Claude Code 版本改了存储位置用find ~ -name *.jsonl -path *claude*找一下实际路径。Key 配了但模型调不通。回到第 2 节的 curl 验证。如果 curl 返回 401检查 Key 有没有复制完整如果返回 404检查ANTHROPIC_BASE_URL是不是多加了/v1。TaoToken 的 API 入口是https://taotoken.net/api不要画蛇添足。6. 把通知接进你的工作流整套东西跑通之后你的工作方式会变起一个长任务切到另一个项目然后不再去想它。会有一条消息传来而且只会因为三种原因之一——这一回合真的完成了包括所有后台任务它需要你输入或者它出错终止了。不会有东西还在跑的时候提前收到「完成」也不用手动挨个检查五个会话找哪个卡住了。如果你还没配 TaoToken 的 Key先去https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys创建一个然后按第 2 节的片段配到 settings.json。接入文档在https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc里面有不同客户端的配置示例。如果你主要用 Claude Code 做长期编码和 Agent 任务可以考虑 Coding Plan地址是https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan它针对长时间会话做了额度优化。想先验证模型对话是否正常用https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat发一条消息试试。最后提醒一句hook 脚本里的 Telegram token 和 TaoToken Key 都不要提交到 git。用config.env加.gitignore是最省事的做法。改主意了想撤掉 hook把 settings.json 里的hooks字段删掉再删掉脚本文件就行不会影响 Claude Code 本身。

相关推荐

PDE数值解工程实践:从PDF决策手册到可部署仿真代码
PDE数值解工程实践:从PDF决策手册到可部署仿真代码

简介:本资源是Elsevier出版的英文专著《Numerical Methods for Partial Differential Equations:Finite Difference and Finite Volume Methods》,由俄亥俄州立大学Sandip Mazumder教授撰写,面向计算数学、工程仿真及科学计算领域… · 2026/9/26 17:16:58

Lint静态代码检查:从原理到工程实践,守护代码质量
Lint静态代码检查:从原理到工程实践,守护代码质量

1. Lint 到底是什么——从一段真实事故说起1.1 我入行时的一段代码事故先说个真实经历。刚工作那会儿,我负责维护一个老项目,上线前夜运营发现用户充值金额对不上账。查了半天,问题出在一行看起来很正常的 JavaScript 代码上:三目… · 2026/9/26 17:16:57

开源AI智能体创业指南:从零部署到变现的完整实操路径
开源AI智能体创业指南:从零部署到变现的完整实操路径

1. 为什么“开源AI智能体”是当下最值得下注的创业切口过去一年我身边至少有七个人跟我说要“做AI创业”,最后真正跑出正向现金流的只有两个,而且他们做的都不是大模型本身,而是开源AI模型之上的智能体(AI Agent)。这个… · 2026/9/26 17:16:51

电气工程论文救急!6 个 AI 写论文网站排行与 TaoToken 配置指南
电气工程论文救急!6 个 AI 写论文网站排行与 TaoToken 配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 17:40:52

PLC、HMI与边缘AI一体化控制器:工业控制与智能融合实战
PLC、HMI与边缘AI一体化控制器:工业控制与智能融合实战

1. 从一台“三合一”控制器说起:工业控制与AI的碰撞点在哪第一次看到宏集DC-Pi这个产品定位的时候,我的反应是:终于有人把PLC、HMI和边缘AI塞进同一个盒子里了。过去几年做产线改造,最头疼的就是柜内空间和布线——PLC一个品牌、H… · 2026/9/26 17:40:52

知识蒸馏技术原理与工程实践指南
知识蒸馏技术原理与工程实践指南

我无法生成与该标题相关的内容。原因如下:标题中提及的“Nathan Lambert 与 Epoch AI 播客对谈”属于特定人物、机构及未公开传播的音频内容,目前无权威信源证实该播客真实存在,亦无公开文字稿、 transcript 或官方发布信息可供核实。“蒸馏对… · 2026/9/26 17:40:46

模型蒸馏技术原理与工程实践指南
模型蒸馏技术原理与工程实践指南

我无法基于该标题生成符合要求的博文内容。原因如下:标题中涉及具体人物(Nathan Lambert)、机构(Epoch AI)及未明确技术内涵的术语“蒸馏”与“中国实验室”,但缺乏可操作、可复现、可验证的具体项目要素&a… · 2026/9/26 17:40:40

SpringBoot+微信小程序:文旅活动预约与内容管理系统实战
SpringBoot+微信小程序:文旅活动预约与内容管理系统实战

做文旅类小程序这件事,我最初的出发点其实很简单:有朋友在景区做运营,跟我吐槽线下活动报名还在用在线表格收集,游客填完表单,后台人工核对,放票名额满了也没法及时更新;活动照片散落在公众号和… · 2026/9/26 17:40:40

Muse AI视频生成实操指南:从文案到成片的7个关键节点
Muse AI视频生成实操指南:从文案到成片的7个关键节点

1. 这个标题不是在问“Muse火了没”,而是在问“火了之后,谁在真正用它、怎么用、用得对不对”最近刷到“Muse火了”这个标题,几乎每条信息流里都夹着一两条——不是带货链接,就是测评截图,再不就是“三分钟上手Muse生成… · 2026/9/26 17:40:40

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码