尧图精选

别让 Agent 空转,TaoToken 给巡检机器人设成本审计

🕒 发布时间:2026/9/18 3:41:52 📁 来源:尧图网络
1. 从一次“看似忙疯”的巡检开始空转 Agent 比报错更贵TaoToken 的实战判断很直接当 Claude Code 或 Codex 的巡检日志里出现“工具调用很多、文件 diff 为零”时先去 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentagent_audit_intro 统一入口和 Key再把 Base URL 固定为 https://taotoken.net/api。我见过最像“勤奋故障”的 Agent 日志不是报错而是安静地烧 TokenClaude Code 连续执行read_file - grep - read_file每一步 tool_result 都很长Codex 反复apply_patch每次都返回“已尝试”但仓库没有新 diff群聊里三个 Agent 互相补充上下文却没有一个任务被真正关闭。表面上看它们在协作、在搜索、在修正从成本审计视角看这是一条典型的空转链路有事件、有 Token、有等待没有状态变化。这类问题很难靠“换个更聪明的模型”解决。模型越强越会用合理措辞解释自己为什么还在查如果没有成本审计和权限隔离自动化系统就会把“没有产出”包装成“正在深度推理”。所以巡检机器人不应该只做健康检查它要先做三件事把任务、事件、Token、权限拆开记录把重复工具调用和无 diff 循环标成空转把 Token 消耗归因到具体 Agent而不是只看到月底总账单。原文里那组 Agent 实操建议可以压缩成三个设置动作但这里不复述新闻式观点而是直接落到巡检机器人规则里第一优先调用 API不要让 Agent 靠屏幕坐标模拟点击因为点击链路既难审计又难复现第二把最终稿和中间草稿做差分把纠正逻辑写成可复用技能而不是每次靠人提醒第三群聊里的 Agent 默认静默只有被点名才发言登录 Cookie 按最小权限下发。没有第三条成本审计会变成猜谜到底是哪个 Agent 在说话、在读取、在消耗在让巡检机器人调用 API 前先去 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentagent_audit_key 获取 KeyBase URL 填 https://taotoken.net/api。Key 占位符统一写成YOUR_API_KEY不要把它写进仓库、规则文件或审计报告。巡检机器人可以读取本地导出的日志但不要让它通过 MCP 直连 Oracle 或生产库SQL 和命令由读者在本地只读副本执行。这样做的目的不是增加流程而是让“空转”变成可计算、可过滤、可归因的事件。2. 四张审计表任务、事件、Token、权限如果巡检机器人只抓一个token_usage总数它最多告诉你“这个月花多了”无法回答“哪个 Agent 在空转”。要把成本审计做实至少需要四张逻辑表。它们可以来自本地日志、CI 记录、工具调用中间件或网关侧导出不需要直连生产库。第一张是agent_task记录任务从创建到关闭的状态。关键字段包括task_id、agent_id、source、created_at、closed_at、close_reason、diff_lines。source可以标注任务来自哪个入口例如命令行巡检、群聊点名、定时任务。close_reason很重要区分done、timeout、empty_loop、permission_denied。第二张是agent_event记录 Agent 每一步动作。关键字段包括event_id、task_id、agent_id、event_type、tool_name、args_hash、state_hash、token_in、token_out、latency_ms、created_at。args_hash用于判断重复调用state_hash用于判断状态是否真的变化。如果连续 10 次state_hash都一样基本可以标记为空转候选。第三张是token_ledger按任务和 Agent 汇总 Token。关键字段包括task_id、agent_id、model、prompt_tokens、completion_tokens、total_tokens、cost_estimate。成本审计不只看总 Token还要看空转 Token 占比。一个 Agent 总消耗高不一定有问题但如果它的空转 Token 占比超过 40%就需要进入巡检机器人的重点名单。第四张是permission_grant记录 Cookie、API Key、文件系统、群聊发言权限。关键字段包括agent_id、scope、resource、granted_at、expires_at、last_used_at。很多“空转”其实是权限过大导致的Agent 能读取所有仓库、能加入所有群聊、能调用所有工具于是它不断尝试“多查一点”。最小权限不是安全口号它直接降低无效探索。下面这段 SQL 只在本地只读副本执行用来找出“事件很多、状态很少、Token 很高、没有 diff”的空转任务-- 本地只读副本执行不要直连生产库 CREATE TEMP TABLE empty_loop_candidates AS SELECT e.task_id, e.agent_id, COUNT(*) AS event_count, SUM(CASE WHEN e.event_type tool_call THEN 1 ELSE 0 END) AS tool_calls, COUNT(DISTINCT e.state_hash) AS distinct_states, SUM(e.token_in e.token_out) AS total_tokens, MAX(CASE WHEN e.diff_lines 0 THEN 1 ELSE 0 END) AS has_diff FROM agent_event e GROUP BY e.task_id, e.agent_id HAVING COUNT(*) 20 AND COUNT(DISTINCT e.state_hash) 1 AND MAX(CASE WHEN e.diff_lines 0 THEN 1 ELSE 0 END) 0; SELECT task_id, agent_id, event_count, tool_calls, distinct_states, total_tokens FROM empty_loop_candidates ORDER BY total_tokens DESC;这段查询输出后巡检机器人就能在报告里写清楚“Agent A 在 task_1024 上调用 31 次工具、消耗 58k Token、状态哈希没有变化、无 diff建议标记为空转。”这比笼统地说“成本升高”有用得多因为它能直接定位到 Agent 和任务。还可以加一张重复调用明细按tool_name args_hash聚合-- 本地只读副本执行 SELECT agent_id, tool_name, args_hash, COUNT(*) AS repeat_count, SUM(token_in token_out) AS wasted_tokens FROM agent_event WHERE event_type tool_call GROUP BY agent_id, tool_name, args_hash HAVING COUNT(*) 5 ORDER BY wasted_tokens DESC;当repeat_count高且wasted_tokens高时说明 Agent 在重复同一个动作。常见原因包括工具返回被截断、Agent 没有保存上一次结果、上下文窗口被挤掉、或者它在等待一个永远不会出现的状态。巡检机器人要做的不是立刻杀掉任务而是先给任务打标签、降预算、转只读再通知对应 Agent 的负责人。3. 巡检机器人审计规则空转任务过滤、成本归因和来源标注有了四张表下一步是把判断逻辑写成规则。规则最好放在独立 YAML 文件里便于版本管理和审计。不要把所有判断写死在巡检机器人代码里否则每次调整阈值都要重新发布。下面是一份可落地的空转过滤规则示例version: 1 rules: - id: R1_no_state_change description: 工具调用多但状态哈希几乎不变且没有 diff when: event_count: 20 tool_calls: 8 distinct_states: 1 diff_lines: 0 action: tag: empty_loop weight: 50 budget_action: downgrade_to_readonly - id: R2_repeat_tool_args description: 同一 Agent 重复调用相同工具和参数 when: repeat_count: 5 wasted_tokens: 8000 action: tag: repeated_tool_call weight: 30 budget_action: limit_next_run - id: R3_long_wait_short_output description: 延迟很高但输出 Token 很少疑似等待或空转 when: avg_latency_ms: 45000 avg_completion_tokens: 80 action: tag: long_wait_short_output weight: 20 budget_action: alert_owner - id: R4_group_chat_without_mention description: 群聊中未被点名却持续发言 when: channel_type: group mentioned: false message_count: 3 action: tag: silent_policy_violation weight: 25 budget_action: force_silent - id: R5_cookie_over_scope description: Cookie 或登录态权限超出任务所需范围 when: permission_scope: 3 last_used_scope: ! assigned_scope action: tag: permission_overreach weight: 40 budget_action: revoke_extra_scope权重不是装饰。巡检机器人可以用加权分数决定优先级80 分以上立即进入每日审计报告顶部50 到 79 分进入观察列表50 分以下只记录不打扰。空转任务过滤不是简单删除而是先降级把写权限改为只读、限制下一次运行预算、要求负责人确认后再继续。成本归因要回答两个问题哪个 Agent 消耗 Token为什么消耗巡检机器人可以把本地 JSONL 日志汇总后调用模型生成摘要但模型只负责归纳不负责直接操作生产系统。下面是一段 Python 示例读取本地事件文件按 Agent 聚合 Token并生成审计请求import os import json from collections import defaultdict from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlhttps://taotoken.net/api ) def load_events(path): events [] with open(path, r, encodingutf-8) as f: for line in f: line line.strip() if line: events.append(json.loads(line)) return events def aggregate(events): stat defaultdict(lambda: { events: 0, tool_calls: 0, tokens: 0, states: set(), diff_lines: 0, mentioned: False, message_count: 0, }) for e in events: agent e.get(agent_id, unknown) stat[agent][events] 1 if e.get(event_type) tool_call: stat[agent][tool_calls] 1 stat[agent][tokens] e.get(token_in, 0) e.get(token_out, 0) stat[agent][states].add(e.get(state_hash)) stat[agent][diff_lines] e.get(diff_lines, 0) if e.get(channel_type) group: stat[agent][mentioned] stat[agent][mentioned] or e.get(mentioned, False) stat[agent][message_count] 1 return stat def build_prompt(stat): rows [] for agent, s in stat.items(): empty_score 0 if s[events] 20 and s[tool_calls] 8 and len(s[states]) 1 and s[diff_lines] 0: empty_score 50 if s[tokens] 20000: empty_score 20 if s[message_count] 3 and not s[mentioned]: empty_score 25 rows.append({ agent_id: agent, events: s[events], tool_calls: s[tool_calls], distinct_states: len(s[states]), tokens: s[tokens], diff_lines: s[diff_lines], group_mentioned: s[mentioned], empty_score: empty_score, }) return json.dumps(rows, ensure_asciiFalse) if __name__ __main__: events load_events(./logs/agent_events.jsonl) stat aggregate(events) prompt build_prompt(stat) resp client.chat.completions.create( modelYOUR_MODEL, messages[ { role: system, content: 你是 Agent 成本审计助手。只根据输入数据标注哪个 Agent 消耗 Token并给出空转过滤建议。不要编造字段。 }, { role: user, content: prompt } ], temperature0.2 ) print(resp.choices[0].message.content)这段脚本的关键不是“让模型写代码”而是让模型在本地审计数据上做归纳。执行前要保证TAOTOKEN_API_KEY来自独立 Key不要让巡检机器人复用主账号 Key。每个 Agent、每个巡检任务最好使用单独 Key 或至少单独预算标签这样账单才能按 Agent 归因。4. Claude Code、Codex 与 CC Switch把审计策略固化到日常编码流程巡检机器人不能只在月底跑一次。它要进入日常编码流程和 Claude Code、Codex 共用同一套供应商入口。这里最容易犯的错是把 Claude Code 的环境变量套到 Codex 上。Claude Code 使用ANTHROPIC_*Codex 使用config.toml和自己的 provider 配置不要混用。Claude Code 的settings.json可以这样配置Base URL 指向 TaoToken{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: claude-sonnet-4-5 } }保存后Claude Code 的请求会走统一入口。这里的ANTHROPIC_MODEL以控制台实际模型名为准如果后续模型名变化只需要改这一处。注意不要把ANTHROPIC_BASE_URL或ANTHROPIC_AUTH_TOKEN写进 Codex 的config.toml那会导致 Codex 读取不到 provider。Codex 使用config.toml可以按 provider 方式配置model gpt-5-codex model_provider taotoken [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY然后在本地 shell 中设置export TAOTOKEN_API_KEYYOUR_API_KEY如果你的 Codex 版本要求wire_api以本地文档为准补充wire_api chat或wire_api responses不要凭感觉填。核心原则只有两个Base URL 是https://taotoken.net/apiKey 占位符是YOUR_API_KEY。在让巡检机器人调用 API 前去 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentagent_audit_config 获取 Key如果团队多人使用给巡检机器人单独创建 Key不要和开发主账号混用。CC Switch 三件套适合管理多套配置Claude Code Profile、Codex Profile、巡检机器人 Profile。下面是一份字段示意具体字段名按你本地 CC Switch 版本映射profiles: - name: claude-code-audit tool: claude-code base_url: https://taotoken.net/api auth_env: ANTHROPIC_AUTH_TOKEN model: claude-sonnet-4-5 - name: codex-audit tool: codex base_url: https://taotoken.net/api auth_env: TAOTOKEN_API_KEY model: gpt-5-codex - name: patrol-bot tool: script base_url: https://taotoken.net/api auth_env: TAOTOKEN_API_KEY model: YOUR_MODEL三件套的意义在于隔离开发时用 Claude Code Profile 或 Codex Profile巡检时切到 patrol-bot Profile使用独立 Key 和独立预算。这样当审计报告显示某个 Agent 消耗异常时可以快速判断是开发交互导致还是巡检任务导致。再把原文的三个动作固化到流程里第一能用 API 就不要模拟点击屏幕。屏幕点击链路难审计、难回放、容易受 UI 变化影响API 调用可以记录tool_name、args_hash、state_hash成本审计才有着力点。第二用终稿和草稿做差分。每次 Agent 纠正了错误比如把错误目录改对、把重复命令去掉、把越权 Cookie 收回就把 diff 写入技能文件。示例目录可以这样组织agent-audit/ rules/ empty_loop.yaml skills/ terminal_diff.md permission_cookie.md group_chat_silent.md reports/ 2026-01-agent-cost.md第三群聊中多个 Agent 默认静默仅在被点名时发言登录 Cookie 按最小权限下发。对应到规则里就是mentioned true才允许发言assigned_scope之外的 Cookie 不注入。成本审计不是只看 Token 数它也要看 Agent 有没有在不该说话的时候说话、在不该读取的时候读取。5. 空转任务过滤实战本地日志到审计报告下面给出一条可复现的巡检链路。假设你已经把 Claude Code、Codex 和巡检机器人的事件导出为本地 JSONL每行一个事件包含task_id、agent_id、event_type、tool_name、args_hash、state_hash、token_in、token_out、diff_lines、channel_type、mentioned等字段。第一步在本地执行规则过滤。可以用 Python 读取 JSONL先做确定性判断再把摘要交给模型归纳import json from collections import defaultdict RULES { min_events: 20, min_tool_calls: 8, max_distinct_states: 1, max_diff_lines: 0, repeat_threshold: 5, group_message_threshold: 3, } def audit(path): agents defaultdict(lambda: { events: 0, tool_calls: 0, tokens: 0, states: set(), diff_lines: 0, repeat: defaultdict(int), group_messages: 0, mentioned: False, tags: set(), }) with open(path, r, encodingutf-8) as f: for line in f: e json.loads(line) agent e[agent_id] row agents[agent] row[events] 1 row[tokens] e.get(token_in, 0) e.get(token_out, 0) row[states].add(e.get(state_hash)) row[diff_lines] e.get(diff_lines, 0) if e.get(event_type) tool_call: row[tool_calls] 1 key f{e.get(tool_name)}:{e.get(args_hash)} row[repeat][key] 1 if e.get(channel_type) group: row[group_messages] 1 row[mentioned] row[mentioned] or e.get(mentioned, False) report [] for agent, row in agents.items(): if ( row[events] RULES[min_events] and row[tool_calls] RULES[min_tool_calls] and len(row[states]) RULES[max_distinct_states] and row[diff_lines] RULES[max_diff_lines] ): row[tags].add(empty_loop) for key, count in row[repeat].items(): if count RULES[repeat_threshold]: row[tags].add(repeated_tool_call) if row[group_messages] RULES[group_message_threshold] and not row[mentioned]: row[tags].add(silent_policy_violation) report.append({ agent_id: agent, events: row[events], tool_calls: row[tool_calls], distinct_states: len(row[states]), tokens: row[tokens], diff_lines: row[diff_lines], tags: sorted(row[tags]), }) report.sort(keylambda x: x[tokens], reverseTrue) return report if __name__ __main__: rows audit(./logs/agent_events.jsonl) for r in rows: print(json.dumps(r, ensure_asciiFalse))第二步把输出写成本地 Markdown 报告。报告要明确标注哪个 Agent 消耗 Token而不是只给总数# Agent 成本审计报告本地生成 ## 概览 | Agent | 事件数 | 工具调用 | 状态数 | Token | Diff | 标签 | |---|---:|---:|---:|---:|---:|---| | patrol-bot-01 | 86 | 31 | 1 | 58200 | 0 | empty_loop | | codex-audit-02 | 44 | 12 | 5 | 21500 | 120 | repeated_tool_call | | claude-runner-03 | 19 | 6 | 4 | 9800 | 340 | - | ## 空转任务明细 - task_1024patrol-bot-01 连续调用 grep/read_file 31 次state_hash 无变化无 diff消耗 58.2k Token。 - task_1057codex-audit-02 对同一补丁重复 apply_patch 7 次建议降低下一次运行预算。 - 群聊 ops-roomclaude-runner-03 未被点名发言 4 次建议切换为 mention_only。 ## 建议动作 1. 将 empty_loop 任务降级为只读冻结写权限 30 分钟。 2. 对 repeated_tool_call 任务增加 args_hash 去重缓存。 3. 对未被点名发言的 Agent 开启静默策略。 4. 将本次纠正逻辑写入 skills/下一次巡检直接复用。第三步把报告和规则文件纳入版本管理。每次误报或漏报都通过修改 YAML 阈值解决而不是在聊天里讨论。比如某个 Agent 确实需要多次 read_file 才能完成长文档分析就把distinct_states 1改成按任务类型启用而不是全局放宽。整个过程中巡检机器人只读本地导出文件。不要把 Agent 直接接到生产库上也不要用 MCP 把生产库暴露成工具。SQL 由读者在本地只读副本执行命令也由读者在本地终端执行。成本审计的价值在于先看清楚再决定是否降级、限流或回收权限。6. 把成本审计变成制度预算闸门、权限隔离与每日巡检空转任务过滤如果只靠一次脚本很快会失效。要让它变成制度需要把预算闸门、权限隔离和每日巡检串起来。预算闸门每个 Agent 有独立 Key 或独立预算标签。巡检机器人检测到empty_loop后不直接删除任务而是先执行downgrade_to_readonly把下一次运行预算减半并通知负责人。负责人确认不是误报后再恢复写权限。这样既避免空转继续烧 Token也避免误杀真实任务。权限隔离群聊 Agent 默认静默只有被点名才响应Cookie 按最小权限下发任务结束后回收。对于需要登录态的任务只注入当前任务所需的 Cookie scope不要给全站 Cookie。权限审计和成本审计要合在一起看因为很多 Token 浪费来自权限过大导致的无效探索。每日巡检可以放到本地 cron 或 CI 定时任务里但只处理本地导出日志。示例命令如下#!/usr/bin/env bash set -euo pipefail export TAOTOKEN_API_KEY${TAOTOKEN_API_KEY:-YOUR_API_KEY} python patrol_bot.py \ --input ./logs/agent_events.jsonl \ --rules ./rules/empty_loop.yaml \ --skills ./skills \ --out ./reports/agent-cost-$(date %F).md echo 审计报告已生成./reports/agent-cost-$(date %F).md每天的审计报告至少包含五个指标空转任务数、空转 Token 占比、重复工具调用率、未点名发言次数、越权 Cookie 数。持续一周后就能看出哪些 Agent 是真正的成本黑洞。很多时候问题不是模型太贵而是 Agent 被允许在无状态变化的任务里反复探索。最后把三个动作写进团队规范优先 API 调用而不是屏幕模拟终稿草稿差分后固化为技能群聊静默、点名发言、Cookie 最小权限。巡检机器人负责发现空转成本审计负责归因权限隔离负责止损。如果你还没有统一入口可以从 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentagent_audit_final 开始。准备落地时按这个路径走先到 模型对话 确认模型和计费口径再进入 Coding Plan 选择适合持续巡检的套餐然后在 API Keys 创建独立 Key占位符仍是YOUR_API_KEY最后对照 Claude Code 文档 把ANTHROPIC_BASE_URL和settings.json接好。这样巡检机器人审计的不只是账单而是每个 Agent 的真实产出。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →