DeepSeek Harness Hub
← 返回列表

上下文预算审计liyixuan201211/ctx-budget

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

逐项测量指令、skill 与 MCP 工具定义的 token 开销

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/16 · 已提供中文文档

你的智能体在运行前的上下文成本会是多少?按来源审计指令文件、技能、MCP 工具模式和记忆——包括重复、常驻与按需成本,以及一个你可以在 CI 中强制执行的预算。只读取文件,不执行其他操作。

综合分
30
GitHub 分
30
用户评分
★ Stars
0
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add liyixuan201211/ctx-budget
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

ctx-budget

你的 agent 在运行之前,它的上下文要花多少钱——又是什么在消耗它?

它会找出你的 agent 加载的文本,对其进行测量,按来源归因,并把你在每次请求都要付的成本与只有在加载某些东西时才付的成本区分开来。然后它给你一个可以放进 CI 的退出码。

npx --yes github:liyixuan201211/ctx-budget --help

作为 DSH 插件使用(安装的是 skill,而不只是 CLI):

dsh plugin --profile web add github:liyixuan201211/ctx-budget

中文:agent 跑起来之前,它的上下文要花多少钱? 它找出 agent 会读的东西——
指令文件、skill、MCP 工具定义、memory——逐项测量,并且分清每次请求都要付的
和只有加载时才付的。然后给你一个可以卡在 CI 里的退出码。

关于中文,它做了一件大多数同类工具不做的事:「4 字符 1 token」是英文散文的
经验法则,用在中文上会低估约 2.4 倍。所以它把 ASCII / CJK / 其他字符分开数,
各自用各自的比率,并且把原始字符数一起打出来,让你可以用真正的 tokenizer 复算。

问题所在

每个 agent 都有上下文预算,但几乎没有人去测量它。有三件事让它值得测量:

1. 两种不同的成本被加在了一起。 指令文件存在于每一次请求中。skill 正文只有在 skill 被加载时才存在。一个 12,000 token 的 skill 正文没问题;一个 12,000 token 的 AGENTS.md 则是危机——而一个只报告单一数字的工具无法告诉你你面对的是哪一种。
2. 工具定义是一种永久性的税。 DSH MCP 客户端自己的文档说得很直白:“工具定义会为每一次模型请求增加 token。” 接上四个服务器、它们之间共有五十个工具,你就为每一轮都买下了一笔成本,无论模型是否真的调用过其中任何一个。
3. 过长的描述会被静默截断。 skill provider“会把这个 provider 的可调用名称和被截断的描述渲染进初始或替换目录中”。写一个 1,200 字符的描述,尾部永远到不了模型那里——所以你精心放在最后的那部分,恰恰是不存在的部分。

ctx-budget 测量以上全部三项,而且它通过读取文件来完成。没有进程,没有 socket,没有写入。

使用中

$ ctx-budget --mcp-tools tools.json
ctx-budget  /home/me/project

always-on        808 tokens  (646–1,076)    paid on every request
on-demand        161 tokens  (129–215)      paid when a skill loads
counted        3,873 characters                 across 15 sources (12 always-on, 3 on-demand)

MCP tools are 221 of that (27%) — tool definitions you may never call

always-on, biggest first
258  32%  skill  skill verbose — catalog
136  17%  file   AGENTS.md
68   8%  mcp    github / create_issue
63   8%  mcp    github / list_pull_requests
57   7%  memory memory/old-notes.md
49   6%  skill  skill docs-writer — catalog
46   6%  mcp    filesystem / read_file
44   5%  mcp    filesystem / write_file
27   3%  file   CLAUDE.md
24   3%  skill  skill quick-notes — catalog
23   3%  memory MEMORY.md
13   2%  memory .dsh/memory/facts.md

on-demand, biggest first
127  79%  body   skill docs-writer — body
22  14%  body   skill verbose — body
12   7%  body   skill quick-notes — body
MCP 服务器
131  2 个工具   github
90  2 个工具   filesystem

发现
! 一个 190 字符的块出现了 2 次副本——每次请求约 48 个 token
AGENTS.md:13, memory/old-notes.md:3
在运行任何会删除或覆盖的操作之前,先弄清楚它会破坏什么,以……
! 每次请求有 48 个 token 花在了重复出现的文本上
! skill verbose——catalog:description 有 1205 个字符,而 catalog 只保留 1024 个:最后 181 个字符永远到不了模型——把有用的部分放在前面,或者缩短它
! skills/README.md:没有 YAML frontmatter:agent 的 catalog 无法列出这个 skill,因此它不可达

测量
精确计数:3,873 个字符,3.8 KiB,其中 0 个是 CJK
按 4 字符/token(ASCII)、1.5(CJK)、2.5(其他非 ASCII)估算 token。用 --chars-per-token 及相关选项来设置它们。
上面的排名、占比和重复都是根据字符计数计算出来的,所以即使这些比率有误,它们依然成立。

看看它发现了什么:这个项目上下文中最昂贵的单个东西是一个 skill 描述——258 个 token,比 AGENTS.md 还多——其中 181 个字符甚至从未到达模型。这不是任何人能猜到的数字,而且只需两行就能修复。

双成本模型

一个 skill 不是一个可能加载也可能不加载的整体。它是两个部分:

| | 它是什么 | 你何时付费 |
|---|---|---|
| catalog | name + description(有上限)+ whenToUse | 每次请求,无论该 skill 是否被使用 |
| body | frontmatter 之后的文本 | 仅当该 skill 被加载时 |

这不是关于 agent 如何工作的假设;它是从 DSH 文件系统提供者的实现中读出来的,该实现将 frontmatter 解析为 catalog 条目,并按需加载 body。搞错这一点会在两个方向上误读决策,这就是为什么报告从不把这两个层级混成一个数字。

一个无效的 skill——没有 frontmatter、没有 name、没有 description,或者名称不是 kebab-case——会被提供者完全跳过。所以它不产生成本,把它计入会高报。它改为作为一个发现来报告:“agent 的 catalog 无法列出这个 skill,因此它不可达”。

测量值与估算值

这是引用数字之前需要阅读的部分。

精确计数: 字符、字节、行,以及 ASCII / CJK / 其他非 ASCII 的划分。还有排名和重复背后的每一个字符计数。

估算: token。默认是 chars/4.0 + cjkChars/1.5 + otherChars/2.5。精确计数意味着要为某个特定模型附带一个分词器,对于每次提交都要运行的东西来说,这是错误的依赖。

为什么这个划分不是装饰。 “每个 token 四个字符”是一条关于英文散文的规则。应用到中文上,它会少报两倍以上:

$ ctx-budget --root ./chinese-project --json     # 一个 208 字符的 AGENTS.md
chars 208 (ASCII 22, CJK 178)
CJK-aware estimate : 127 tokens
naive 4.0 estimate :  52 tokens   、--skill-root、--memory 和 --system 会添加更多;--user 还会扫描你主目录下的全局技能根目录(默认关闭——每次运行都读取 ~ 会是个意外,而且是一个没人要的数字)。

MCP 成本需要一次导出,因为配置不包含任何 schema。用以下方式生成一份:
同级工具,或与任何 MCP 客户端一起使用:
bash
mcp-cap inspect --json -- npx -y @modelcontextprotocol/server-filesystem /srv > tools.json
ctx-budget --mcp-tools tools.json

mcp-cap 锁文件同样可用,并会作为下界报告:它存储的是模式哈希,而非模式本身,并且会截断描述。

诚实的定位

审计智能体上下文这一想法并非处女地,已有的两次尝试足够接近,值得点名:

| | 它做什么 | 本工具的差异 |
|---|---|---|
| jamespheffernan/agent-context-audit | Python;盘点 AGENTS.md/CLAUDE.md,报告指令文件在何处重复或分歧,以及技能/记忆表面的规模 | 精神上最接近。本工具增加了常驻 vs 按需的划分、MCP 工具模式、带明确比率的按来源 token 归因,以及带退出码的预算 |
| Ismail-2001/mcp-token-auditor | 位于 MCP 客户端与服务器之间的代理,进行实时 token 计数与告警 | 性质不同:那个观察实时流量;本工具是预检静态审计,无需代理、无需流量、无需启动服务器 |
| toumai266/Vibe-Audit | 用于智能体意图对齐的 FastAPI + React 控制台 | 针对不同问题的应用 |

在 GitHub 上搜索这种形态的预检上下文预算 CLI,基本一无所获,这要么是机会,要么是警告。诚实的答案是,目前大多数人通过把文件逐个粘贴到 token 计数器中来估算,并且从不将结果与任何东西比较。

它诚实承认自己不知道的事情

- Token 是估算的,从不精确计数。 比率可配置,原始计数会被打印出来,以便你重新计算。排名和重复情况不依赖于它们。
- 它看不到你的系统提示。 无论你的运行框架在你的文件之前添加了什么,都无法从文件系统中测量,因此这里的数字是真实请求大小的下限。
- 你的客户端实际渲染什么是你客户端的事。 目录被建模为名称 + 截断的描述 + whenToUse;截断默认值为 1024,并且是文档化的假设(--description-cap),而非测量值。提供商截断到什么程度是其自身的实现细节。
- --json 从不包含文件内容。 文本输出也不包含,除了重复块的 90 字符预览,且任何形似凭据的内容都会被遮蔽。审计在 CI 中运行,而 CI 日志公开的频率比人们预期的更高——因此粘贴到 AGENTS.md 中的 token 绝不能被注意到它的工具回显。
- 超过 8 MiB 的文件被报告为未测量,而非被读取。 若设置了预算,则为退出码 5。
- 符号链接的技能目录不会被跟随,因此指向项目外部的链接
不会被拉进来。--user 是刻意用来向更远处查找的方式。
- 它不会告诉你该删减什么。 它进行排序和归因;关于哪些指令值得占用其 token 的判断,是关于你项目的判断。

开发

需要 Node >= 20。使用带 JSDoc 类型的纯 ESM JavaScript:没有构建步骤,没有安装时脚本,并且发布后的 bin 在安装后确实可以运行——CI 通过打包 tarball 并从真实的 node_modules 中运行它来断言这一点。
bash
npm test            # 101 tests
npm run typecheck   # tsc --noEmit over the JSDoc types
npm run check       # both
./examples/demo.sh  # end to end, asserting every exit code

src/
cli.js          the exit-code contract and argument parsing
discover.js     what an agent will read, and where it lives
frontmatter.js  a lenient SKILL.md frontmatter reader
skills.js       the two-cost model: catalog vs body, and validity
mcp.js          tool definitions from a tools/list dump, never from a server
sources.js      a file becomes a measurable source
estimate.js     the exactness boundary: what is counted and what is assumed
dupes.js        duplication, attributed by tier
report.js       human output, and the measurement footer
audit.js        assembling it, with no path that can drop a source

结构性主张——只读取文件,不读取其他任何东西——在 test/safety.test.js 中断言,方法是检查 src/ 中没有任何文件提及进程、套接字、eval 或写入,并且 package.json 没有定义任何生命周期脚本。CI 在 Node 20/22/24 上运行测试套件,将打包后的 tarball 安装到真实的 node_modules 中并用它审计一个项目,单独运行安全不变量,运行演示,并从外部重新检查无网络和无生命周期脚本这两个属性。

许可证

MIT。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

同作者(liyixuan201211)的其他插件

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群