news 2026/10/28 17:45:28

Claude Code会话监控面板:从JSONL日志到成本可视化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Claude Code会话监控面板:从JSONL日志到成本可视化

最近我一直在折腾 Claude Code,用得越深越觉得不对劲:终端里对话刷得飞快,但一天下来到底聊了多少轮、消耗了多少 token、烧了多少钱,完全是一笔糊涂账。项目一多,会话像流水一样从终端里滑过去,事后想翻某段上下文,只能靠 shell 历史碰运气。后来我花了点时间,给自己做了一个“Claude Code 会话监控面板”,把每次会话的耗时、token 消耗、成本、工具调用次数都捞出来可视化。这篇文章就把我踩过的坑和完整实现方案写清楚,尤其适合那些把 Claude Code 当日常工作工具、又对成本和使用习惯敏感的开发者。

1. 为什么说 Claude Code 需要一块会话监控面板

1.1 终端里的信息过载与黑盒成本

Claude Code 本质上是一个跑在终端里的 AI 编程代理,交互完全发生在命令行。你输入需求,它输出回复,中间会夹杂工具调用、文件读写、Shell 命令执行等大量文本。这种形态的优点很突出,沉浸感强、和编辑器联动顺滑,但缺点同样明显——信息没有沉淀。终端滚过去的每一条 assistant 回复、每一次工具调用,关掉窗口之后就基本不可检索了。

更麻烦的是成本。AI 编码工具按 token 计费,回复越长、缓存越密集,消耗就越快。老实说,终端里并不会实时告诉你这一轮花了几美分、这个项目累计烧了多少。你可能只记得“今天写了挺多代码”,但完全说不出哪个目录、哪个会话最烧钱。我在连续重度使用一周后,连自己用哪个模型更多都答不上来,更别说评估缓存命中率。

所以我意识到,Claude Code 缺的不是功能,而是“仪表盘”。你需要一个能告诉你“现在有什么会话在跑、过去一小时花了多少钱、哪个项目 token 消耗最猛”的东西。这就是我这次要解决的问题。

1.2 官方能力现状:CLI、日志与可选的数据源

动手之前,我先摸了一遍 Claude Code 自身的能力边界。CLI 本身有几个让我感兴趣的参数,比如非交互式的claude -p模式、调试开关、输出格式控制,这些能拿到结构化结果,但主要面向单次调用场景,不适合持续监控交互式会话。

真正的数据宝库,藏在本地的会话日志里。Claude Code 会把每一次会话的完整事件流以 JSONL 格式写到本地磁盘,存放位置在~/.claude/projects/下面。每个项目目录对应一个编码后的文件夹,里面的.jsonl文件就是会话原始记录。这个文件里有你发给它的每条消息、它返回的每个片段、工具调用的输入输出,甚至 token 使用明细。

只要解析这些 JSONL 文件,就能还原出一份完整的会话账本。我最终的技术方案也由此确定:不碰官方 API、不劫持终端输出,直接读取本地会话日志,再做聚合和展示。这样做的好处很明显,数据完全本地化、不依赖网络、不影响 Claude Code 正常工作,而且是纯只读操作,风险最小。

1.3 监控面板的定位与设计取舍

最开始我有两个激进的想法:一个是给终端输出做 tee 转发,抓实时 stdout;另一个是注入中间层拦截 API 请求。前者的问题在于终端输出格式不稳定,解析起来要命;后者风险太大,容易违反使用条款,而且一旦 Anthropic 改了接口协议就全盘崩。

权衡之后,我收敛了目标:监控面板只回答四个问题——有多少会话、什么时候发生、消耗了多少 token 和成本、主要调用了哪些工具。它不追求毫秒级实时,能延迟几秒刷新就够用了。设计上我选了“解析脚本 + 静态 JSON + 本地 Web 页面”的三段式架构。解析脚本负责把 JSONL 变成聚合数据,Web 页面负责展示,中间不需要独立数据库服务,也不需要常驻后台进程。这个架构对大部分个人开发者来说足够轻、足够稳。

2. 会话数据从哪里来:读懂 Claude Code 本地的会话档案

2.1 查找会话目录与 JSONL 日志文件

要解析数据,第一步是找到文件。Claude Code 的配置目录默认是~/.claude,所有会话历史都放在~/.claude/projects下。我建议你先在终端里确认一下是否真有这个文件存在,用下面这条命令看看:

ls -lh ~/.claude/projects/

如果目录为空或者根本不存在,说明你还没跑过任何会话,先去正常用几次 Claude Code 再回来继续。正常情况下你会发现若干个子目录,名字是十六进制编码的字符串,一个目录对应一个工作目录。目录名是 Claude Code 根据当前路径算出来的哈希值,手动反查不现实,所以面板不能靠目录名识别项目,而是要读 JSONL 内容里记录的路径字段。

再看目录里的文件,通常是一个或多个.jsonl。这些文件按会话隔离,同样一个项目目录下可能有几十个文件。文件名是时间戳和会话 ID 的组合,后缀就是标准 JSONL,每行一个事件对象。我个人经验是,解析时不要假设只有一种命名规则,最稳妥的办法是把这个项目目录下所有.jsonl文件都扫一遍。

2.2 一条会话记录里都有什么字段

打开 JSONL 文件后,每一行都是一个 JSON 对象。不同的行有不同的type字段,我实际见过的大概有这些:user、assistant、system、summary。user行记录你输入的消息,assistant行记录模型的输出,system行承载系统级状态,比如会话开始、工具执行结果,summary行往往是会话摘要或标题信息。

最有价值的是assistant行里的message.usage,它明确记录了这次回复的计费信息,我已经在多个版本里见到过这些字段,包括input_tokens、output_tokens、cache_creation_input_tokens和cache_read_input_tokens。有些记录还带costUSD字段,这是 Claude Code 按照官方定价估算的美元成本,如果你的日志里有这个字段,直接聚合就行。没有也不要紧,后面我会讲怎么用自定义价格表去算。

另外每行基本都带timestamp,格式是 ISO 8601 的 UTC 时间。这个字段是会话时间线分析的基础。如果一行里有sessionId,你可以拿它做会话分组;要是找不到,就用文件名来识别归属。

2.3 事件结构差异与工具调用日志

把日志读几段你就会发现,Claude Code 的事件结构并不是固定的教科书格式。同样是 assistant 输出,有些行带toolUse,说明模型调用了工具;紧接着的 system 行里往往带着toolUseResult,也就是工具执行后的结果内容。这两类记录凑在一起,就能还原出“模型决定调用工具 -> 工具执行 -> 返回结果”的完整链路。

如果你想统计这个会话里跑了多少次终端命令、改了多少个文件、调用了几次网页搜索,就得解析这些toolUse字段里的name和input。比如Bash代表执行 Shell 命令,Read和Write代表文件读写,Edit是文件编辑。我统计工具调用次数时,默认只看有toolUse的事件,避免把 assistant 的普通回复也混进去。

不同的 Claude Code 版本,字段嵌套层级和命名会有些差异。我的经验是,解析脚本里要做字段容错,也就是对每个字段都用“先判断存在再取值”的方式,不要假设所有行结构完全一致。日志是本地文件,多一个版本升级就可能导致解析失败,后面你会经常遇到这个问题。

2.4 读取时的关键注意点:权限与敏感数据

读取这些 JSONL 文件要特别注意两点。第一是权限,~/.claude目录下存了会话的完整对话内容,相当于你的私有笔记和数据资产。解析脚本和 Web 页面只能跑在本地,监听地址绝不能设置成0.0.0.0,必须绑定127.0.0.1,否则局域网里的其他人很容易就能打开你的面板,看到所有历史对话。

第二是敏感信息清洗。日志里包含完整的文件路径、命令参数,偶尔还会夹带我们贴在代码里的 API Key、Token 等机密。面板展示时最好做一层脱敏,比如把疑似密钥的字段替换成***。这里我采用的是简单正则过滤:遇到类似sk-开头的字符串、key、token、password等命名字段,一律打码。这块必须做,否则面板就成了你的泄密窗口。

3. 监控面板的设计与核心实现

3.1 指标口径怎么定

动笔写代码之前,我先明确监控指标的口径,毕竟口径不一致,后面的聚合结果就全是自欺欺人。

我最终确定的指标有四组:

  • 会话维度:会话 ID、起始与结束时间、持续时间、消息轮数、消耗的 token 总量、成本。
  • 模型维度:不同模型的调用次数、token 消耗比例、缓存命中率。
  • 工具维度:Bash、Write、Edit、Read等工具的调用频次。
  • 时间维度:按小时、按天聚合的 token 消耗和成本曲线。

口径上要注意几点:token 总量要把输入、输出、缓存写入、缓存读取都算进去,但计算成本时,这几类 token 的单价完全不同。缓存读取通常很便宜,只有正常输入价格的十分之一左右;缓存写入反而是较贵的操作。如果日志里没有costUSD,就需要自己维护一个模型价格表。

审计工作流时,我会把“缓存命中率”当作一个重要指标。这个数字等于cache_read_input_tokens除以cache_read + cache_write + 普通输入。缓存命中率高,说明你在同一个会话里反复利用上下文,长期来看能省不少钱。要是发现有些会话缓存命中率奇低,基本可以判断这个会话一直在写新上下文、没有复用旧内容。

3.2 采集层:解析 JSONL 的 Python 脚本

核心采集脚本我用了 Python 写,原因很简单,JSONL 解析在 Python 里非常顺手,而且 Python 的环境在开发机上基本都有。脚本的逻辑分三步:扫描目录、逐行解析、聚合输出。

给你看我简化后的解析逻辑:

import json import os from datetime import datetime from collections import defaultdict SESSIONS_DIR = os.path.expanduser("~/.claude/projects") def iter_events(): for root, _, files in os.walk(SESSIONS_DIR): for fname in files: if not fname.endswith(".jsonl"): continue fpath = os.path.join(root, fname) with open(fpath, "r", encoding="utf-8") as f: for line in f: line = line.strip() if not line: continue try: yield json.loads(line) except json.JSONDecodeError: continue def parse_session(): sessions = defaultdict(lambda: { "start": None, "end": None, "messages": 0, "tokens": 0, "cost": 0.0, "tools": defaultdict(int), "models": defaultdict(int) }) for ev in iter_events(): sid = ev.get("sessionId", "unknown") sess = sessions[sid] ts = ev.get("timestamp") if ts: dt = datetime.fromisoformat(ts.replace("Z", "+00:00")) if sess["start"] is None or dt < sess["start"]: sess["start"] = dt if sess["end"] is None or dt > sess["end"]: sess["end"] = dt if ev.get("type") == "user": sess["messages"] += 1 if ev.get("type") == "assistant": usage = ev.get("message", {}).get("usage", {}) if usage: total = (usage.get("input_tokens", 0) + usage.get("output_tokens", 0) + usage.get("cache_creation_input_tokens", 0) + usage.get("cache_read_input_tokens", 0)) sess["tokens"] += total model = ev.get("model", "unknown") sess["models"][model] += 1 tool_use = ev.get("message", {}).get("content", []) for block in tool_use: if isinstance(block, dict) and block.get("type") == "tool_use": tool_name = block.get("name", "unknown") sess["tools"][tool_name] += 1 return sessions

这个脚本里我最想强调的是容错。json.JSONDecodeError要单独捕获,因为日志写入过程中可能刚好被中断,最后一行是半个 JSON。这种残行直接跳过,不要影响整个文件解析。字段取值也要做兜底,get()默认值必不可少,否则一行数据格式稍变,脚本就直接崩了。

3.3 存储与查询:读文件还是落 SQLite

解析完成之后,数据放哪儿?最开始我图省事,直接把聚合结果序列化成 JSON,每次刷新面板就重新扫一遍所有 JSONL。但会话文件多了之后,全量解析的速度开始下降,一次扫描要几百毫秒甚至更久,而且每次刷新都在做重复劳动,很浪费。

这里我做了个折中:聚合后的 JSON 文件直接可读,但扫描后的中间结果会缓存下来。更专业的做法是落 SQLite,把每个会话的指标抽成一行记录,再用 SQL 做时间维度聚合。SQLite 唯一的代价是解析逻辑里要加一段建表和写入的代码,换来的是查询效率和增量更新的便利。

如果你追求极致简单,我也不反对直接读 JSONL。只要全局加一层“只在文件有新增时重扫”的逻辑,就用不到 SQLite。判断新增的办法很简单,记录每个 JSONL 文件的最后修改时间戳和文件大小,如果两者都没变,就跳过。这套逻辑用几句话就能写出来。

3.4 展示层:轻量 Web 面板与关键组件

展示层的技术选型我尽量少引入依赖。一个单 HTML 文件,引入 Chart.js 的 CDN,剩下全用原生 JavaScript 完成。跑起来就是一张能看的大屏,不需要前端构建工具,不需要 npm 依赖。

面板上我放了几个核心区块:

  • 统计卡片区:会话总数、今日 token 消耗、累计预估成本、当前活跃会话数。
  • 趋势折线图:按小时展示 token 消耗和成本,能直观看出一天中哪些时段使用最猛。
  • 会话表格:按时间倒序列出会话列表,包含会话 ID(截断)、起止时间、消息数、token 数、成本、模型,以及点击查看详情的按钮。
  • 工具调用排行:横向条形图,排在前面的工具一定是Bash、Write、Edit这类高频操作。

实现时要注意一个细节:JSON 里的时间戳是 UTC,前端展示时一定要用Date对象转换成本地时区。我用这段时间吃过亏,下午三点看面板,显示的全是 UTC 时间,所有曲线都偏移了 8 小时,一度怀疑数据算错了。

4. 一步一步搭起来:从零到可用的监控面板

4.1 环境准备与工具清单

你需要准备的东西不算多:一个能跑 Python 3 的开发环境、Node.js(Claude Code 本身依赖它)、还有一个浏览器。Claude Code 的安装我就不展开讲了,主流方式是npm install -g @anthropic-ai/claude-code,装完正常登录后开始使用,本地会话文件就会开始落盘。

在 Windows 上如果你遇到提示和 64 位系统不兼容的情况,多半是 Node 版本装成了 32 位或版本过旧。装 LTS 版的 Node 20 以上基本能解决。我的建议是,日常用 Claude Code 的话,尽量在 PowerShell 或 Windows Terminal 里直接跑,解析脚本则用 Git Bash 或 WSL 里的 Python 3 执行。

我在项目根目录下建了三个文件:collect.py(采集脚本)、data.json(聚合结果)、index.html(面板)。这个结构足够简单,也方便后续扩展。

4.2 编写采集脚本的完整流程

采集脚本除了解析 JSONL,还要负责输出 JSON。我在collect.py里增加了几个函数:

import json from datetime import datetime, timedelta def compute_cost(session, price_table): # 按模型和 token 类型估算成本 cost = 0.0 for model, stats in session["models"].items(): cost += stats["input_tokens"] / 1_000_000 * price_table.get(model, {}).get("input", 3.0) cost += stats["output_tokens"] / 1_000_000 * price_table.get(model, {}).get("output", 15.0) cost += stats["cache_read_tokens"] / 1_000_000 * price_table.get(model, {}).get("cache_read", 0.3) cost += stats["cache_write_tokens"] / 1_000_000 * price_table.get(model, {}).get("cache_write", 3.75) return round(cost, 4) def generate_data(sessions): rows = [] for sid, sess in sessions.items(): rows.append({ "id": sid, "start": sess["start"].isoformat() if sess["start"] else None, "end": sess["end"].isoformat() if sess["end"] else None, "duration": (sess["end"] - sess["start"]).total_seconds() if sess["end"] and sess["start"] else 0, "messages": sess["messages"], "tokens": sess["tokens"], "cost": sess["cost"], "models": dict(sess["models"]), "tools": dict(sess["tools"]) }) rows.sort(key=lambda x: x["start"] or "", reverse=True) return rows if __name__ == "__main__": sessions = parse_session() rows = generate_data(sessions) with open("data.json", "w", encoding="utf-8") as f: json.dump(rows, f, ensure_ascii=False, indent=2)

跑一次python3 collect.py,就把所有会话的统计结果写进data.json。这个流程虽然手动,但配合后台监听完全够用。想要实时性的话,在脚本里加一个简单的循环,轮询 JSONL 目录的文件修改时间,发现变化就重新解析,然后把data.json刷一遍。不要做得太复杂,个人使用场景下 5 秒一次的轮询就够了。

4.3 编写前端面板的骨架与数据绑定

前端index.html我保持极简。页面加载时用fetch("data.json")拉取数据,渲染逻辑分层处理。统计卡片用一个reduce汇总,折线图按小时切分数据,会话表格用字符串模板拼 HTML。唯一的渲染依赖是 Chart.js,图表只负责把准备好的数据画出来。

关键代码片段大致是这样的:

async function loadData() { const res = await fetch("data.json"); const rows = await res.json(); renderCards(rows); renderChart(rows); renderTable(rows); renderTools(rows); } function renderCards(rows) { const totalTokens = rows.reduce((sum, r) => sum + r.tokens, 0); const totalCost = rows.reduce((sum, r) => sum + r.cost, 0); document.getElementById("total-sessions").textContent = rows.length; document.getElementById("total-tokens").textContent = (totalTokens / 1000).toFixed(1) + "k"; document.getElementById("total-cost").textContent = "$" + totalCost.toFixed(2); }

这里要额外提醒一个前端渲染的坑:data.json如果在本地以file://协议打开,部分浏览器的fetch会直接报跨域错误。解决办法有两个,要么起一个本地静态服务器,要么干脆把数据硬编码到 HTML 里。我用的是本地服务器方案,一条python3 -m http.server 8787就够了。启动之后浏览器访问http://127.0.0.1:8787,面板立刻可用。为了省事,我在项目里加了一个start.sh,内容就是把采集脚本执行一次,再启动 http 服务。

4.4 在 VS Code 终端里的使用姿势与本地服务器启动

日常我习惯在 VS Code 的终端里跑 Claude Code,监控面板自然也要配合这个场景。我的用法是:VS Code 里开两个终端标签,一个跑claude正常工作,另一个跑bash start.sh把监控面板挂起来。面板刷出来以后,切到浏览器或者 VS Code 内置简单浏览器查看。

结合 VS Code 还有一个更轻的处理方式:面板产出的index.html本身是纯静态页面,你完全可以在 VS Code 里选中它,用内置预览功能直接打开。这种模式没有独立端口、没有服务器进程,适合只在需要的时候瞄一眼统计结果。不过一旦要实时刷新曲线图,还是得用 http 服务模式,因为file://协议下动态更新受限。

用下来我最推荐的做法是给claude命令起一个别名,同时给面板启动脚本也起一个别名,比如:

alias cc='claude' alias ccdash='python3 collect.py && python3 -m http.server 8787'

这样工作流就变成:开终端跑cc写代码,随时再开一个终端跑ccdash看消耗。整个流程不要额外点任何按钮,习惯之后非常顺手。

5. 面向第三方模型与本地模型的适配

5.1 cc switch、DeepSeek/Qwen/GLM 与 LM Studio 的接入背景

Claude Code 能接第三方模型,这在社区里已经不是什么秘密。很多朋友不希望把所有请求都走官方通道,于是会把路由指向 DeepSeek、Qwen、GLM 这类模型,或者干脆用 LM Studio 在本地起一个模型服务,目的都是降低成本、保护隐私、增加对模型的控制力。

我这里必须先把话说清楚:接入第三方模型不是让面板直接支持这些模型,而是让面板能识别出“你的会话实际用的是哪个模型”,并且用正确的价格去计税。因为不管请求最终发到哪个服务,Claude Code 都会把这个会话的完整事件流写进本地的 JSONL,所以监控面板的数据来源不受影响。

常见的连接方式是借助 API 路由工具。像 cc switch 这类工具,本质上是在ANTHROPIC_BASE_URL和认证令牌上做切换,把 Anthropic 协议请求转发到目标模型服务,从而实现 DeepSeek、Qwen、GLM 的接入。LM Studio 走的是另一个方向,它启动一个本地服务,需要通过兼容层把 Anthropic 消息格式转成 OpenAI 格式,再路由到本地模型。

5.2 模型切换后监控数据如何对齐

模型一旦切换,JSONL 里的model字段会跟着变化。你可能会在一个会话里看到默认的 Anthropic 模型名,在另一个会话里看到 DeepSeek 或 Qwen 的模型标识。面板的逻辑是按model字段做分组统计,所以只要解析脚本不硬编码模型名,切换模型后统计会自动分开。

真正要处理的是别名映射。同一个 DeepSeek 模型,在 API 网关里可能叫deepseek-chat,在日志里可能又显示成另一个名字。为了让面板上的统计更友好,我在采集脚本里加了一个MODEL_ALIAS映射表,把识别到的模型名统一成可读的中文标签或标准名。这一步纯粹是给展示层用的,不影响原始数据。

要特别留意的是,第三方模型的message.usage字段结构可能与官方日志不一致。部分路由工具会“翻译”这些字段,把 token 信息填进来;但有些版本填得并不完整,比如缺少cache_read_input_tokens。解析时必须对这些字段做缺失保护,缺什么就补 0,绝不能让一个缺失字段拖垮整次统计。

5.3 自定义计价表与成本估算的修正方法

既然模型变了,价格自然也不能再用官方默认值。我维护了一个price_table,按模型名指定 input、output、cache_read、cache_write 四个档位的单价,单位是美元每百万 token。面板里展示的成本完全由这份表计算得出。

下面是我的配置格式:

PRICE_TABLE = { "default": {"input": 3.0, "output": 15.0, "cache_read": 0.3, "cache_write": 3.75}, "deepseek-chat": {"input": 0.27, "output": 1.1, "cache_read": 0.07, "cache_write": 0.27}, "qwen-max": {"input": 0.4, "output": 1.2, "cache_read": 0.1, "cache_write": 0.4}, "local-model": {"input": 0.0, "output": 0.0, "cache_read": 0.0, "cache_write": 0.0}, }

本地模型我直接把单价设成 0,面板上只统计 token 消耗和次数,不再显示虚高的“成本”。这个做法我特别推荐给用 LM Studio 的朋友,因为本地模型的成本根本没法用单 price 量化,统计零成本反而更诚实。

计价表写好后,成本计算逻辑就非常简单了:每个会话按模型累加各类型 token,再分别乘以单价。如果你发现面板上的数字和实际账单对不上,先检查价格表参数,再看日志里的costUSD字段——如果字段存在且不是你自定义的模型,那就直接用官方的数字,别自己再算一遍。

6. 常见问题与排错记录

6.1 面板里没数据

最常见的现象是启动面板后,所有统计卡片都显示 0。这时候先别怀疑脚本,第一时间检查~/.claude/projects/目录里到底有没有 JSONL 文件。没有文件就说明 Claude Code 还没来得及落盘,或者落盘目录被环境变量改到了别的位置。

如果目录存在、文件也存在,那就检查文件的编码和读取权限。JSONL 文件是 UTF-8 编码的,解析脚本也要用utf-8打开。Windows 上如果你的 Python 默认用系统编码,很可能在遇到中文字符时报错,所有解析直接中断。另外一个隐藏坑是符号链接,部分用户把~/.claude软链到了别的盘,os.walk默认不跟随符号链接,也会导致扫不到文件。解决方式是显式加上followlinks=True。

6.2 token 统计与官方显示对不上

如果你在监控面板里看到的 token 总数和 Claude Code 官方统计不一致,先别慌,这不一定是脚本写错了。官方的计费统计通常按请求计费,而我的解析方式按日志事件里的usage聚合,两者的口径天然存在差异。还有一种情况是,面板统计了所有会话,而官方只统计你登录账号下的有效会话,二者的范围不同。

对比口径时,我建议只比较“同一个会话”的差异。如果同一个会话在两个来源的数字差很多,再检查是不是有事件缺失。比如会话结束前突然断网,最后的 usage 可能没写进日志,这时面板会少算。这个问题无法彻底修复,只能接受误差,我目前观察到的日常误差控制在 1% 以内。

6.3 会话文件过大导致页面卡顿

重度使用几周后,单个项目的 JSONL 文件可能涨到几十兆,浏览器解析data.json时就会出现明显卡顿。这时候最有效的优化不是压缩 JSON,而是让解析脚本只输出聚合结果,不输出原始事件。我的data.json只保留会话维度的统计,不嵌入任何 prompt 文本,所以文件体积小得多。

另一个优化点是做“增量解析”。采集脚本记录每个 JSONL 文件的偏移量,下次扫描时只读新增部分。我实现方式很简单,记录文件的mtime和字节数就够了,没必要真正去维护偏移量。这个优化上线之后,面板刷新速度从秒级降到了毫秒级。

6.4 权限/组织账号异常与会话不落盘

有时候你会碰到 Claude Code 在终端里报错,提示当前用户没有获得访问权限或者订阅被禁用。这类问题发生在会话真正开始之前,所以本地不会生成有效会话数据,面板自然没有新内容。遇到这种提示,先确认自己使用的账号是否具备可用的订阅权限,如果是企业账号,还要让管理员检查组织策略里的 Claude 功能开关。

多说一句,我不建议绕过这类权限校验。一方面有合规风险,另一方面它跟监控面板没关系,你该做的是先解决账号问题,让 Claude Code 正常工作,然后面板的数据流自然就恢复了。

6.5 Claude Code 升级后 JSONL 字段变化

Claude Code 迭代速度很快,升级之后事件结构偶尔会变。我遇到过的问题是升级后message.usage里的缓存字段名称变了,老的解析脚本拿不到新字段,token 统计直接下降。处理办法是给自己的解析脚本加一层“字段探测”,启动时先打印出一行完整事件的 JSON 结构,然后和脚本里的字段名核对。

维护上,我建议解析脚本不要写得太死板。所有字段引用都通过一个get_value工具函数去取,它能同时支持多个字段别名,比如既能读input_tokens,也能读新版本可能出现的别名。这样升级之后,最多改一行映射表,而不是重写解析逻辑。


我在实际使用这个面板两周之后,最大的感受不是“省了多少钱”,而是“终于知道自己是怎么在用 AI 工具了”。会话变少了会提醒自己是不是该多写点代码,token 飙高了会提醒自己是不是提示词写得太啰嗦。工具调用排行更是让我发现,很多时间都花在了Bash反复执行命令上,间接促使我去优化自己的工作流。

最后再分享一个小技巧:把面板的数据文件data.json加入 Git 仓库时一定要用.gitignore忽略掉,否则你的全部对话统计和项目信息都会被提交上去。面板只做本地展示就好,我从来不把采集脚本和面板托管到任何远程仓库,这既是为了数据安全,也是为了让这套监控方案保持真正属于自己。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 17:45:00

SQL Server参数数量限制解决方案与性能优化

1. 报错现象与背景解析"传入的请求具有过多的参数。该服务器支持最多2100个参数"这个报错信息&#xff0c;通常出现在数据库查询或API调用场景中。我第一次遇到这个问题是在一个电商促销系统的高并发测试阶段&#xff0c;当时我们的商品筛选接口突然开始大量抛出这个…

作者头像 李华
网站建设 2026/10/28 17:44:14

匿名模型Space Bunny登顶揭秘:API接入与Codex实战指南

这个圈子最近有个特别反常的现象&#xff1a;一个连团队背景都查不到、官网文案写得很随意的匿名模型&#xff0c;居然在全球模型调用统计榜上直接冲到第一&#xff0c;把一堆大家熟知的旗舰模型压在身后&#xff0c;数值上就跟Opus5贴在一起。这个模型就是Space Bunny。我连续…

作者头像 李华
网站建设 2026/10/28 17:42:49

SSH密钥过期问题解析与密钥管理最佳实践

1. SSH密钥过期问题的本质与影响当看到"Your SSH key has expired"这样的提示时&#xff0c;很多开发者第一反应是困惑——SSH密钥不是应该永久有效吗&#xff1f;实际上&#xff0c;这里存在一个关键认知偏差。传统SSH密钥对&#xff08;尤其是RSA类型&#xff09;确…

作者头像 李华
网站建设 2026/10/28 17:42:48

崖山数据库架构解析与性能优化实践

1. 崖山数据库概述崖山数据库是一款面向现代数据密集型应用设计的新型数据库系统。我第一次接触这个系统是在2020年参与一个金融风控项目时&#xff0c;当时我们需要处理每天TB级的交易数据&#xff0c;传统关系型数据库已经难以满足性能需求。崖山数据库的分布式架构和混合存储…

作者头像 李华
网站建设 2026/10/28 17:39:49

混合专家模型MoE全面解析:架构原理、训练挑战与工程实战

抱着这个疑问&#xff0c;我花了两周时间把MoE相关的论文和开源代码翻了遍&#xff0c;也实际搭过一个小规模MoE模型跑完训练和推理。这篇文章不搞教科书式的原理复述&#xff0c;而是从"为什么FFN会成为瓶颈"开始&#xff0c;把MoE层的每个关键组件、训练中的真实问…

作者头像 李华
网站建设 2026/10/28 17:39:48

哈希表在字母异位词分组中的应用与优化

1. 问题背景与核心思路字母异位词分组是LeetCode中非常经典的哈希表应用题型&#xff0c;题目要求将给定字符串数组中的字母异位词组合在一起。字母异位词指的是字母相同但排列不同的单词&#xff0c;比如"eat"、"tea"、"ate"就是一组字母异位词…

作者头像 李华