-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Problem Statement
注:下述内容不全是vibe出来的,我查账查日志 看了一整天了hh。。优化建议我也去社区学习查看过,算得上是最佳实践之一,还算靠谱,实际细节优化可以继续向Claude opus求证。但不排除对项目理解有误的情况,那就是我的锅
另外”始终提取0个模式“这个问题确实很大,我看有人反馈过了
问题描述
在两个活跃群(高峰期 10-20 条/分钟)的真实部署场景下,用户对话 Token 占比仅约 2%,后台自学习任务消耗了约 98% 的 API 费用,即使qwen3.5这样便宜的API能在四个小时内消耗约 ¥70。通过日志分析和代码审阅,费用主要来自三个后台功能:
| 功能 | 占费用比重 | 核心瓶颈 |
|---|---|---|
黑话挖掘 jargon_miner |
~70% | 单批 20 候选词 × 每词最多 3 次 LLM 调用,且输出未限长 |
话题检测 enhanced_interaction |
~25% | 每条消息触发 1 次 LLM 调用,无节流 |
| 社交关系上下文注入 | ~3% | 每次主对话注入多维上下文,持续增加 input token |
| (不完全准确) |
详细费用归因
1. 黑话挖掘(最大消耗源)
调用放大链条: 每累积 10 条消息触发 mine_jargon() → extract_candidates() 单批可产出 20 个候选词 → 每个候选词在达到出现阈值 [3,6,10,20,40,60,100] 时触发三步推断法(最多 3 次 LLM 调用)。
实测数据(11 分钟窗口):
jargon_miner日志条目:172 次(110 INFO + 62 WARN/解析失败)- 批量提取:16 批 × 20 候选词 = 320 次单词判断
- 62 次"推断解析失败"——LLM 生成了完整响应但格式不合规,纯浪费
Output Token 失控的根因: 三步推断法未对 max_tokens 做限制。"识别黑话"的解释(infer_meaning Step 1)每次输出 300-600 个汉字(≈600-1200 tokens),而实际只需要一句话的含义摘要。这导致账单中 output/input 比达到约 15:1。
2. 话题检测(第二大消耗源)
_detect_topic_change() 在 message_count >= 3 后对每条消息发起 1 次 filter_chat_completion 调用(enhanced_interaction.py:196-214)。11 分钟内触发 162 次。输出虽短(2-4 字话题名),但累积调用量巨大。
3. 解析失败的隐性浪费
三步推断法使用 JSON 输出格式,但未配置 response_format/json_mode。LLM 返回非法 JSON → 解析失败 → 调用白白付费。11 分钟内 62 次解析失败,按每次平均 800 output tokens 估算 ≈ 49,600 tokens 纯浪费。
优化建议
🔴 P0:立即见效(预估降低 60-70% 费用)
1. 为黑话推断添加 max_tokens 限制
# jargon_miner.py - infer_meaning() 的 3 次调用
# 建议 Step1/Step2: max_tokens=150, Step3: max_tokens=100
# 含义摘要不需要超过 50 个汉字当前"识别黑话"单次输出 600-1200 tokens,限制后降至 150 tokens,单项节省 75-85%。
2. 话题检测添加采样/节流机制
# enhanced_interaction.py - _detect_topic_change()
# 方案 A:每 N 条消息检测一次(建议 N=5)
# 方案 B:添加冷却时间(建议 30 秒)
# 方案 C:仅在消息内容变化度(如简单关键词重叠率)超阈值时才调 LLM从每条消息 1 次 → 每 5 条 1 次,单项节省 80%。
3. 强制 JSON 输出格式
# 对所有期望 JSON 返回的调用,添加:
# response_format={"type": "json_object"}(如模型支持)
# 或在 prompt 末尾追加:"Only output valid JSON, no other text."
# 并添加 1 次重试(而非静默丢弃)消除解析失败的纯浪费(当前约占总费用 5-8%)。
🟡 P1:架构级优化(预估再降 15-20%)
4. 黑话候选词去重与合并
当前同一批内 20 个候选词各自独立调用 LLM。建议:
- 合并为 1 次批量判断调用(prompt 中列出所有候选词 + 上下文,要求批量返回 JSON 数组)
- 单批 20 词从 20×3=60 次调用 → 3 次调用,降低 95%
5. 话题检测改用本地方案
2-4 字的话题名完全可以用 TF-IDF / 关键词提取(类似 jieba.analyse.extract_tags)实现,精度略低但 0 Token 消耗。仅在检测到显著话题切换时才用 LLM 精炼。
6. 社交上下文注入预算控制
SocialContextInjector.format_complete_context() 注入的多维上下文(心理状态、情绪、好感度、社交网络、表达风格、行为指导)每次主对话都完整附加。建议:
- 设置注入内容总 token 上限(如 500 tokens)
- 按重要性优先级截断
- 对无变化的维度跳过注入(与上次 diff)
🟢 P2:可选配置项
7. 暴露费用相关参数为用户可配置项
jargon_mining:
enabled: true
batch_size: 10 # 当前硬编码
max_candidates_per_batch: 20 # 建议可调,默认改为 5
inference_max_tokens: 150 # 新增
topic_detection:
enabled: true
sample_rate: 5 # 每 N 条消息检测一次
cooldown_seconds: 30 # 冷却时间环境信息
- 部署:2 个 QQ 群(日常活跃,高峰 10-20 msg/min)
- 模型:qwen3.5plus,输入0.8输出4.8,仅比deepseek输出贵一块八
- 插件版本:最新 main 分支
- 日均 API 费用:约 ¥70(其中用户实际对话仅占 ~¥1.4)
复现方式
将插件默认配置部署到任意活跃群(>5 msg/min),观察 24 小时 API 用量。后台任务的 Token 消耗将远超前台对话。
Proposed Solution
省钱
Alternatives Considered
No response
Feature Scope
Learning System (学习系统)
Additional Context
No response