Skill: louisecxqiu-glitch/token-use-optimizer (version 1.0.0)

--- name: token-optimizer description: > AI Agent 项目的 Token 消耗审计与系统性优化。提供四层诊断框架、六步优化 SOP、 自动化审计脚本。适用于任何使用 Rules + Memory + Knowledge + Skills 架构的 AI Agent 项目（如 CodeBuddy、Cursor、Windsurf 等）。 This skill should be used when users mention token optimization, context size reduction, prompt cost control, or AI agent operational efficiency. Triggers: token优化, token节约, token审计, 省token, 上下文膨胀, context太大, 对话成本, rules瘦身, memory清理, 知识库精简, 降低开销, token consumption, optimize tokens, reduce context, context optimization, prompt cost. --- # Token Optimizer **Purpose:** 系统性审计并优化 AI Agent 项目的 Token 消耗，降低 30%+ 固定开销。 ## Core Concept 每次 AI Agent 对话都有固定的"上下文税"——Rules、Memory、Knowledge 在每轮注入 prompt。固定开销 × 对话轮数 = 真正的消耗大头。 ``` ┌─────────────────────────────────────┐ │ 用户可见的对话内容（~40%） │ ← 你以为的消耗 ├─────────────────────────────────────┤ │ Always-on Rules / Memory / │ │ System Prompt / Knowledge / │ ← 隐性固定税 │ Skill 指令 │ └─────────────────────────────────────┘ ``` ## Four-Layer Diagnostic Framework 按 ROI 从高到低： | 层级 | 审计对象 | 预期收益 | |------|---------|---------| | **L1 Rules** | `.codebuddy/rules/*.mdc` | ~800-2,000 tokens/轮 | | **L2 Memory** | `update_memory` 条目 | ~500-1,500 tokens/轮 | | **L3 Knowledge** | 知识库文件 | ~1,000-3,000 tokens/轮 | | **L4 Behavior** | 运行时行为模式 | 变量，可省数万 tokens | → 各层详细策略与判断标准见 `references/optimization-strategies.md` ## Six-Step SOP ### Step 1: Inventory — 建立 Token 消耗基线 运行自动审计脚本建立基线： ```bash python3 scripts/token_audit.py [项目根目录] python3 scripts/token_audit.py [项目根目录] --json # JSON 格式 python3 scripts/token_audit.py [项目根目录] --knowledge-dir /path/to/knowledge # 自定义知识库路径 ``` 脚本自动扫描 Rules / Memory / Knowledge，输出每轮固定开销估算和分层诊断建议。 若需手动盘点，参考 `references/optimization-strategies.md` 中的基线计算公式。 ### Step 2: Diagnose Rules (L1) **核心原则：身份铁律 always-on，行为指南 on-demand。** 检查四类问题：重复规则 → 合并；过长规则 → 拆分；可降级规则 → 改 requestable；僵尸规则 → 删除。 → 判断标准和降级操作清单见 `references/optimization-strategies.md` §L1 ### Step 3: Diagnose Memory (L2) 清理三类冗余：已被 Rule 覆盖的 → 删除；一次性事件记录 → 删除；过时信息 → 删除。保留：行为红线、经验教训、仍有效的事实。 目标：Memory 控制在 ~15 条以内，每条不超过 3 行。 → 清理决策树和格式规范见 `references/optimization-strategies.md` §L2 ### Step 4: Diagnose Knowledge (L3) 拆分巨型文件为"精简路由表（~200行）+ 详细内容（按需加载）"。入口文件控制在 200 行以内。 → 拆分模式和"两跳"加载策略见 `references/optimization-strategies.md` §L3 ### Step 5: Optimize Runtime Behavior (L4) 五项行为优化：精准读取（offset/limit）、主动 /compact（>10轮）、subagent 分流、Skill 按需加载、知识两跳检索。 → 具体操作对照表见 `references/optimization-strategies.md` §L4 ### Step 6: Verify & Institutionalize 1. 量化对比优化前后的固定开销 2. 验证降级 Rule 的触发词能正确唤回 3. 将架构决策写入 MEMORY.md 4. 建立守护机制防止开销回弹 → 守护机制清单见 `references/optimization-strategies.md` §守护机制 ## Quick Decision Tree ``` Token 开销过高？ ├── 固定开销高 → Step 2 (Rules) / Step 3 (Memory) / Step 4 (Knowledge) ├── 变量开销高 → Step 5 (精准读取 / subagent 分流 / Skill 按需加载) └── 累计开销高 → Step 5 (主动 /compact) ``` ## Tools & References | 资源 | 路径 | 说明 | |------|------|------| | `token_audit.py` | `scripts/` | 自动扫描，输出分层诊断报告 | | `optimization-strategies.md` | `references/` | 四层诊断的完整操作手册 | | `real-world-cases.md` | `references/` | 实战优化案例（可选参考） |

path: scripts/token_audit.py
content: #!/usr/bin/env python3
"""
Token Audit Tool — AI Agent 项目 Token 消耗自动审计
=================================================
扫描 Rules、Memory、Knowledge 文件，估算每轮对话的固定 token 开销，
输出分层诊断报告和优化建议。

使用方法:
  python3 scripts/token_audit.py [项目根目录]
  python3 scripts/token_audit.py [项目根目录] --json
  python3 scripts/token_audit.py [项目根目录] --knowledge-dir /path/to/knowledge

选项:
  --json              输出 JSON 格式报告
  --knowledge-dir DIR 自定义知识库目录路径（默认自动探测常见位置）
  -h, --help          显示帮助信息
"""

import os
import sys
import json
import glob
import re
from pathlib import Path
from dataclasses import dataclass, field, asdict
from typing import Optional


# ── Token 估算常量 ──────────────────────────────────────

CHARS_PER_TOKEN_ZH = 1.3   # 中文约 1.3 字符/token
CHARS_PER_TOKEN_EN = 4.0   # 英文约 4 字符/token
MIXED_RATIO = 0.6           # 假设中英混合比（60% 中文）
SYSTEM_PROMPT_OVERHEAD = 2000  # 平台 system prompt 固定开销估算


# ── 数据结构 ──────────────────────────────────────────

@dataclass
class FileAudit:
    """单个文件的审计结果"""
    path: str
    name: str
    lines: int
    chars: int
    estimated_tokens: int
    category: str  # always-rule, requestable-rule, memory, knowledge, skill
    issues: list = field(default_factory=list)


@dataclass 
class AuditReport:
    """完整审计报告"""
    project_root: str
    always_rules: list = field(default_factory=list)
    requestable_rules: list = field(default_factory=list)
    memories: list = field(default_factory=list)
    knowledge_files: list = field(default_factory=list)
    
    # 汇总
    total_always_tokens: int = 0
    total_memory_tokens: int = 0
    total_per_round: int = 0
    total_per_10_rounds: int = 0
    
    issues: list = field(default_factory=list)
    suggestions: list = field(default_factory=list)


# ── 工具函数 ──────────────────────────────────────────

def estimate_tokens(text: str) -> int:
    """估算文本的 token 数"""
    if not text:
        return 0
    # 简单启发：统计中文字符占比
    zh_chars = len(re.findall(r'[\u4e00-\u9fff\u3000-\u303f\uff00-\uffef]', text))
    total_chars = len(text)
    if total_chars == 0:
        return 0
    zh_ratio = zh_chars / total_chars
    
    # 混合计算
    zh_tokens = zh_chars / CHARS_PER_TOKEN_ZH
    en_chars = total_chars - zh_chars
    en_tokens = en_chars / CHARS_PER_TOKEN_EN
    
    return int(zh_tokens + en_tokens)


def parse_mdc_frontmatter(content: str) -> dict:
    """解析 .mdc 文件的 frontmatter"""
    result = {'alwaysApply': False, 'description': ''}
    
    if content.startswith('---'):
        parts = content.split('---', 2)
        if len(parts) >= 3:
            frontmatter = parts[1]
            for line in frontmatter.strip().split('\n'):
                if ':' in line:
                    key, _, value = line.partition(':')
                    key = key.strip()
                    value = value.strip()
                    if key == 'alwaysApply':
                        result['alwaysApply'] = value.lower() == 'true'
                    elif key == 'description':
                        result['description'] = value
                    elif key == 'enabled':
                        result['enabled'] = value.lower() == 'true'
    
    return result


def read_file_safe(path: str) -> str:
    """安全读取文件"""
    try:
        with open(path, 'r', encoding='utf-8') as f:
            return f.read()
    except Exception as e:
        return ''


# ── 扫描函数 ──────────────────────────────────────────

def scan_rules(project_root: str) -> tuple:
    """扫描 .codebuddy/rules/ 下的所有规则文件"""
    always_rules = []
    requestable_rules = []
    
    rules_dir = os.path.join(project_root, '.codebuddy', 'rules')
    if not os.path.exists(rules_dir):
        return always_rules, requestable_rules
    
    for mdc_file in glob.glob(os.path.join(rules_dir, '**', '*.mdc'), recursive=True):
        content = read_file_safe(mdc_file)
        if not content:
            continue
        
        meta = parse_mdc_frontmatter(content)
        lines = content.count('\n') + 1
        tokens = estimate_tokens(content)
        rel_path = os.path.relpath(mdc_file, project_root)
        name = os.path.basename(mdc_file).replace('.mdc', '')
        
        issues = []
        
        # 检查：过长规则
        if lines > 150:
            issues.append(f"⚠️ 规则过长（{lines} 行 > 150 行阈值），建议拆分")
        
        # 检查：always-on 但可能可以降级
        if meta.get('alwaysApply'):
            if not meta.get('description'):
                issues.append("💡 缺少 description 字段（降级为 requestable 时必需）")
        
        audit = FileAudit(
            path=rel_path,
            name=name,
            lines=lines,
            chars=len(content),
            estimated_tokens=tokens,
            category='always-rule' if meta.get('alwaysApply') else 'requestable-rule',
            issues=issues
        )
        
        if meta.get('alwaysApply'):
            always_rules.append(audit)
        else:
            requestable_rules.append(audit)
    
    return always_rules, requestable_rules


def scan_knowledge(project_root: str, custom_knowledge_dir: Optional[str] = None) -> list:
    """扫描知识库入口文件。支持自定义知识库路径或自动探测常见位置。"""
    knowledge_files = []
    
    # 知识库路径：优先使用用户指定，否则自动探测常见位置
    if custom_knowledge_dir:
        knowledge_dirs = [os.path.abspath(custom_knowledge_dir)]
    else:
        knowledge_dirs = [
            os.path.join(project_root, 'knowledge'),
            os.path.join(project_root, 'docs', 'knowledge'),
            os.path.join(project_root, 'openclaw-workspace', 'knowledge'),
        ]
    
    # 只扫描入口文件（路由表/索引）
    entry_patterns = ['KNOWLEDGE-MAP*', 'CROSS-DOMAIN*', 'BOOK-INDEX*', 'INDEX*', 'README*']
    
    for kdir in knowledge_dirs:
        if not os.path.exists(kdir):
            continue
        
        # 先扫描入口文件
        for pattern in entry_patterns:
            for f in glob.glob(os.path.join(kdir, pattern)):
                content = read_file_safe(f)
                lines = content.count('\n') + 1
                tokens = estimate_tokens(content)
                rel_path = os.path.relpath(f, project_root)
                
                issues = []
                if lines > 300:
                    issues.append(f"⚠️ 入口文件过大（{lines} 行），建议拆分为路由表+详细文件")
                
                knowledge_files.append(FileAudit(
                    path=rel_path,
                    name=os.path.basename(f),
                    lines=lines,
                    chars=len(content),
                    estimated_tokens=tokens,
                    category='knowledge',
                    issues=issues
                ))
        
        # 统计总体规模
        all_md = glob.glob(os.path.join(kdir, '**', '*.md'), recursive=True)
        if all_md and not knowledge_files:
            total_lines = 0
            for f in all_md:
                content = read_file_safe(f)
                total_lines += content.count('\n') + 1
            knowledge_files.append(FileAudit(
                path=os.path.relpath(kdir, project_root),
                name=f"知识库总计（{len(all_md)} 个文件）",
                lines=total_lines,
                chars=0,
                estimated_tokens=0,
                category='knowledge-summary',
                issues=[f"ℹ️ 共 {len(all_md)} 个知识文件，{total_lines} 行"]
            ))
    
    return knowledge_files


def count_memories_estimate(project_root: str) -> int:
    """估算 Memory 条目的 token 消耗（无法直接读取 update_memory 内容）"""
    # Memory 条目存在 CodeBuddy 内部，无法直接扫描
    # 但可以从 MEMORY.md 和 daily logs 估算
    memory_tokens = 0
    
    memory_md = os.path.join(project_root, '.codebuddy', 'MEMORY.md')
    if os.path.exists(memory_md):
        content = read_file_safe(memory_md)
        memory_tokens += estimate_tokens(content)
    
    return memory_tokens


# ── 报告生成 ──────────────────────────────────────────

def generate_report(project_root: str, knowledge_dir: Optional[str] = None) -> AuditReport:
    """生成完整审计报告"""
    report = AuditReport(project_root=project_root)
    
    # L1: Rules
    report.always_rules, report.requestable_rules = scan_rules(project_root)
    
    # L3: Knowledge
    report.knowledge_files = scan_knowledge(project_root, knowledge_dir)
    
    # 汇总 always-on 开销
    report.total_always_tokens = sum(r.estimated_tokens for r in report.always_rules)
    
    # 估算 memory 开销（提示用户手动确认）
    memory_file_tokens = count_memories_estimate(project_root)
    report.total_memory_tokens = memory_file_tokens
    
    # 每轮固定开销
    report.total_per_round = (
        SYSTEM_PROMPT_OVERHEAD 
        + report.total_always_tokens
        + report.total_memory_tokens
    )
    report.total_per_10_rounds = report.total_per_round * 10
    
    # 生成建议
    if report.total_always_tokens > 5000:
        report.suggestions.append(
            "🔴 Always-on Rules 开销过高（>{:,} tokens），建议审查是否有规则可降级为 requestable".format(
                report.total_always_tokens
            )
        )
    
    always_count = len(report.always_rules)
    if always_count > 5:
        report.suggestions.append(
            f"🟡 Always-on Rules 数量较多（{always_count} 条），建议只保留身份铁律类规则"
        )
    
    long_rules = [r for r in report.always_rules if r.lines > 120]
    if long_rules:
        for r in long_rules:
            report.suggestions.append(
                f"🟡 规则 `{r.name}` 有 {r.lines} 行，建议拆分（核心留 rule，详细内容移到 references/）"
            )
    
    # 汇总所有 issues
    for r in report.always_rules + report.requestable_rules + report.knowledge_files:
        report.issues.extend(r.issues)
    
    return report


def print_report(report: AuditReport):
    """打印彩色报告"""
    print("\n" + "=" * 60)
    print("  🔍 Token 消耗审计报告")
    print("=" * 60)
    print(f"\n📁 项目: {report.project_root}\n")
    
    # ── L1: Rules ──
    print("─" * 40)
    print("📋 L1: Rules 层")
    print("─" * 40)
    
    print(f"\n  Always-on Rules ({len(report.always_rules)} 条):")
    for r in sorted(report.always_rules, key=lambda x: -x.estimated_tokens):
        marker = " ⚠️" if r.issues else ""
        print(f"    {r.name:<35} {r.lines:>5} 行  ~{r.estimated_tokens:>5} tokens{marker}")
    
    print(f"\n  Requestable Rules ({len(report.requestable_rules)} 条):")
    for r in report.requestable_rules:
        print(f"    {r.name:<35} {r.lines:>5} 行  (按需加载)")
    
    print(f"\n  📊 Always-on Rules 小计: ~{report.total_always_tokens:,} tokens/轮")
    
    # ── L2: Memory ──
    print(f"\n{'─' * 40}")
    print("🧠 L2: Memory 层")
    print("─" * 40)
    print(f"\n  MEMORY.md 估算: ~{report.total_memory_tokens:,} tokens")
    print("  ⚠️ update_memory 条目无法直接扫描，请手动确认条目数量")
    print("  💡 建议: Memory 条目控制在 ~15 条以内，每条不超过 3 行")
    
    # ── L3: Knowledge ──
    if report.knowledge_files:
        print(f"\n{'─' * 40}")
        print("📚 L3: Knowledge 层")
        print("─" * 40)
        for k in report.knowledge_files:
            marker = " ⚠️" if k.issues else ""
            print(f"\n    {k.name:<40} {k.lines:>5} 行  ~{k.estimated_tokens:>5} tokens{marker}")
            for issue in k.issues:
                print(f"      {issue}")
    
    # ── 汇总 ──
    print(f"\n{'=' * 60}")
    print("  📊 汇总")
    print("=" * 60)
    print(f"\n  System Prompt 固定开销:  ~{SYSTEM_PROMPT_OVERHEAD:,} tokens")
    print(f"  Always-on Rules:         ~{report.total_always_tokens:,} tokens")
    print(f"  Memory (MEMORY.md):      ~{report.total_memory_tokens:,} tokens")
    print(f"  {'─' * 35}")
    print(f"  每轮固定开销估算:        ~{report.total_per_round:,} tokens/轮")
    print(f"  10 轮对话累计:           ~{report.total_per_10_rounds:,} tokens")
    
    # ── 建议 ──
    if report.suggestions:
        print(f"\n{'─' * 40}")
        print("💡 优化建议")
        print("─" * 40)
        for s in report.suggestions:
            print(f"  {s}")
    
    if report.issues:
        print(f"\n{'─' * 40}")
        print("⚠️ 发现的问题")
        print("─" * 40)
        for issue in report.issues:
            print(f"  {issue}")
    
    print()


# ── 主入口 ──────────────────────────────────────────

def main():
    # 解析参数
    project_root = os.getcwd()
    output_json = False
    knowledge_dir = None
    
    args = sys.argv[1:]
    i = 0
    while i < len(args):
        arg = args[i]
        if arg == '--json':
            output_json = True
        elif arg == '--knowledge-dir' and i + 1 < len(args):
            i += 1
            knowledge_dir = args[i]
        elif arg == '--help' or arg == '-h':
            print(__doc__)
            sys.exit(0)
        else:
            project_root = os.path.abspath(arg)
        i += 1
    
    if not os.path.exists(project_root):
        print(f"❌ 目录不存在: {project_root}")
        sys.exit(1)
    
    # 运行审计
    report = generate_report(project_root, knowledge_dir)
    
    if output_json:
        # JSON 输出
        output = {
            'project_root': report.project_root,
            'always_rules': [asdict(r) for r in report.always_rules],
            'requestable_rules': [asdict(r) for r in report.requestable_rules],
            'knowledge_files': [asdict(r) for r in report.knowledge_files],
            'totals': {
                'always_tokens_per_round': report.total_always_tokens,
                'memory_tokens_estimate': report.total_memory_tokens,
                'total_per_round': report.total_per_round,
                'total_per_10_rounds': report.total_per_10_rounds,
            },
            'suggestions': report.suggestions,
            'issues': report.issues,
        }
        print(json.dumps(output, ensure_ascii=False, indent=2))
    else:
        print_report(report)


if __name__ == '__main__':
    main()


path: references/real-world-cases.md
content: # Token 优化实战案例

> 可选参考。展示一个真实 AI Agent 项目的完整优化过程，帮助理解四层诊断框架的实际应用。

---

## 案例概况

| 维度 | 说明 |
|------|------|
| 项目类型 | CodeBuddy IDE 中的 AI Agent 体系 |
| 架构 | Rules + Memory + Knowledge + Skills |
| 项目阶段 | 运行 3 个月，从未系统性清理 |
| 优化目标 | 降低每轮固定 Token 开销 |

## 优化前诊断

| 组件 | 数量 | 估算 tokens/轮 |
|------|------|:-------------:|
| Always-on Rules | 7 条 | ~5,500 |
| Memory 条目 | 20+ 条 | ~4,000 |
| System Prompt | — | ~2,000 |
| **合计** | | **~11,500** |

发现的六类问题：
1. 两条 Rule 内容重叠 >80%
2. 三条 Rule 并非每次对话都需要，但设为 always-on
3. Memory 与 Rule 双重覆盖同一内容
4. 存在一次性事件记录型 Memory
5. 知识库入口文件 863 行，每次全量加载
6. Rules 中内联大量示例和关联表

## 第一轮：Rules + Memory 优化

| 操作 | 手法 | 收益 |
|------|------|:----:|
| 合并重复 Rule | 删除内容已被另一条覆盖的冗余规则 | -800 tokens/轮 |
| 3 条 Rule 降级 | 从 always-on 改为 requestable，加 description 触发词 | -1,200 tokens/轮 |
| Memory 精简 | 删除 10 条（被 Rule 覆盖/一次性/过时） | -1,500 tokens/轮 |
| **小计** | | **-3,500 tokens/轮** |

## 第二轮：Knowledge + 内容瘦身

| 操作 | 手法 | 收益 |
|------|------|:----:|
| 知识库入口拆分 | 863→200 行路由表 + 按需加载的详细文件 | 知识调用 -60% |
| Rule A 瘦身 | 示例外迁 + 段落合并为 bullet（125→93 行，-26%） | -200 tokens/轮 |
| Rule B 瘦身 | 机制去重 + 合并压缩（172→119 行，-31%） | -400 tokens/轮 |
| **小计** | | **-600 tokens/轮 + 知识调用 -60%** |

## 最终结果

| 指标 | 优化前 | 优化后 | 变化 |
|------|:-----:|:-----:|:----:|
| Always-on Rules | 7 条 | 4 条 | -3 |
| Memory 条目 | 20+ 条 | ~13 条 | -7 |
| 每轮固定开销 | ~11,500 | ~8,000 | **-30%** |
| 10 轮累计 | ~115,000 | ~80,000 | **省 ~35,000** |
| 知识库入口 | 863 行 | 200 行 | -77% |

## 沉淀的核心原则

1. **身份铁律 always-on，行为指南 on-demand** — 判断 Rule 级别的第一性原理
2. **Memory 和 Rule 不重复** — 同一内容只在一处，优先放 Rule
3. **知识库"路由表 + 按需加载"** — 入口轻量，详情按需
4. **精准读取 > 全量读取** — 已知文件用 offset/limit
5. **主动 /compact > 被动溢出** — >10 轮主动压缩

## 经验教训

1. **温水煮青蛙**：每次加一条 rule/memory 都觉得无所谓，3 个月累积效应惊人。需定期审计。
2. **双重计费最隐蔽**：Memory 和 Rule 覆盖同一内容是最常见浪费，因两者由不同场景创建。
3. **降级 ≠ 删除**：Requestable rule 在需要时仍能被触发词唤回，不丢失功能。
4. **大文件拆分 ROI 最高**：800 行拆成 200 行路由表 + 按需加载，效果最显著。
5. **守护机制必须建立**：优化完不建守护，几个月后又回原点。


path: references/optimization-strategies.md
content: # Token 优化策略详解

> token-optimizer Skill 的完整操作手册。SKILL.md 负责调度，本文件负责"怎么做"。

---

## 基线计算公式

```
固定开销/轮 ≈ (always-on rules 总行数 × 1.3)
             + (memory 条目数 × 平均行数 × 1.3)
             + (system prompt 固定开销 ~2000)
```

> 1.3 是中文内容的 token/字符经验系数（英文约 1.0）。

手动盘点清单：

```
□ Always-on Rules 数量和总行数
□ Requestable Rules 数量（确认不会误触）
□ Memory 条目数量和估算 token 数
□ 知识库入口文件行数
□ 常驻 Skill 指令长度
```

---

## L1: Rules 优化策略

### Always-on vs Requestable 判断标准

**核心原则：只有"身份铁律"级别的规则才配 always-on。**

| 规则类型 | always-on？ | 理由 |
|---------|:-----------:|------|
| 身份定义（我是谁、核心行为） | ✅ | 每轮都需要 |
| 自我进化协议 | ✅ | 每次对话开头必跑 |
| 模式切换（工作/闲聊） | ✅ | 需要实时判断 |
| 任务完成通知 | ❌ | 只在完成实质任务时需要 |
| 产出物归档 | ❌ | 只在生成产出物时需要 |
| 双写同步 | ❌ | 只在写 memory 时需要 |
| 部署规则 | ❌ | 只在部署时需要 |

### 降级为 Requestable 的操作

修改 `.mdc` 文件的 frontmatter：

```yaml
---
description: >
  [规则职责一句话]。
  当需要 [触发场景] 时触发。
alwaysApply: false
---
```

**description 写法要点**：第一句说职责，第二句写触发条件（"当需要…时触发"），包含 3-5 个关键词帮助自动匹配。

### 规则合并策略

当两条规则内容重叠 >50% 时：
1. 确定主规则（内容更完整）
2. 合并另一条的独有内容
3. 删除冗余规则文件
4. 验证合并后功能完整

### 规则内容瘦身技巧

| 技巧 | 操作 | 典型收益 |
|------|------|---------|
| 示例外迁 | 详细示例移到 references/，规则只留引用 | -20~40% |
| 压缩合并 | 多个短节合并为 bullet list | -15~30% |
| 表格替代 | 用表格替代段落式描述 | -10~20% |
| 引用替代 | "详见 `XXX.md`" 替代内联长段 | -50~70%（该节） |

### 检查项汇总

| 检查项 | 判断标准 | 处理方式 |
|-------|---------|---------|
| 重复规则 | 内容重叠 >50% | 合并为一条 |
| 过长规则 | 单条 >150 行 | 拆分：核心留 rule，详情移 references/ |
| 可降级规则 | 非每次对话必需 | 改 requestable，加 description |
| 僵尸规则 | 创建后从未触发 | 评估删除或合并 |

---

## L2: Memory 优化策略

### Token 成本结构

每条 Memory 每轮注入 system prompt：
- 事实性（1 行）≈ 30-50 tokens
- 结构化经验（4 行）≈ 100-200 tokens
- 长描述（5+ 行）≈ 200-400 tokens

15 条 memory 估算：15 × 100 ≈ 1,500 tokens/轮

### 清理决策树

```
这条 Memory 还需要吗？
├── 内容已被 Rule 完整覆盖？ → YES → 删除（双重计费）
├── 一次性事件记录？ → YES → 删除（无行动价值）
├── 引用的工具/配置还存在吗？ → NO → 删除（过时）
├── 用户明确要求的红线？ → YES → 保留
├── 2+ 次试错的经验教训？ → YES → 保留（结构化格式）
└── 当前仍有效的事实？ → YES → 保留（精简为 1 句）
```

### 格式规范

**事实性 Memory**（1 句话）：
```
项目 X 的唯一运行环境路径是 ~/CodeBuddy/project-x/
```

**经验教训 Memory**（结构化 4 段）：
```
[经验] 标题
- 场景：什么情况下遇到的
- 根因：为什么会发生
- 解法：下次怎么做
- 适用范围：哪些场景通用
```

**红线**：
- ❌ 超过 5 行的 Memory → 拆分或移到 Rule/Knowledge
- ❌ 与 Rule 重复的内容
- ❌ 日志型记录 → 放 daily log

### 目标

Memory 条目控制在 ~15 条以内，每条不超过 3 行。

---

## L3: Knowledge 优化策略

### 巨型文件拆分模式

**Before**：一个 800+ 行的入口文件包含路由表 + 联想 + 索引 + 示例。

**After**：
```
入口文件.md (≤200 行) ← 纯路由表/索引
  ├── 详细内容A.md  ← 场景A时按需加载
  ├── 详细内容B.md  ← 场景B时按需加载
  └── 各域文件/*.md ← 各域详细文件按需加载
```

**拆分标准**：
- 入口文件控制在 200 行以内
- "触发条件不同"的内容块拆为独立文件
- 文件名即触发词（如 `BOOK-INDEX.md` 只在推荐书籍时加载）

### "两跳"加载模式

```
用户问题 → Step 1: 读路由表（≤200行，~300 tokens）
         → Step 2: 按路由读具体域文件（按需）
```

避免一次性加载整个知识库。

---

## L4: 运行时行为优化

### 精准读取 vs 全量读取

```python
# ❌ 全量读取 2000 行文件（~3000 tokens）
read_file("large_file.py")

# ✅ 只读需要的 50 行（~75 tokens）
read_file("large_file.py", offset=100, limit=50)
```

适用：确认文件头尾、读已知位置函数、检查配置特定字段。

### 主动 /compact

| 对话轮数 | 建议 |
|---------|------|
| < 5 轮 | 正常对话 |
| 5-10 轮 | 留意上下文大小 |
| > 10 轮 | **主动建议 /compact** |
| > 15 轮 | 强烈建议拆分新会话 |

### Subagent 分流

大规模代码搜索优先使用 `code-explorer` subagent：
- 搜索结果不进入主 agent 上下文
- 大幅减少主对话 token 消耗
- 适合：代码结构理解、跨文件搜索、大范围重构规划

### Skill 按需加载

- 不同时加载多个 Skill
- 用完的 Skill 不会自动卸载，注意上下文膨胀
- 特定步骤需要的 Skill，在该步骤再加载

---

## 优化收益计算模板

```
优化前：
  Always-on Rules:  [A] tokens/轮
  Memory:           [B] tokens/轮
  System Prompt:    ~2,000 tokens/轮
  ────────────────────────
  固定开销合计:     [A+B+2000] tokens/轮

优化后：
  Always-on Rules:  [A'] tokens/轮
  Memory:           [B'] tokens/轮
  System Prompt:    ~2,000 tokens/轮
  ────────────────────────
  固定开销合计:     [A'+B'+2000] tokens/轮

  节省:    [(A+B) - (A'+B')] tokens/轮
  节省率:  [节省/原总] × 100%
  10轮累计: [节省×10] tokens
```

---

## 守护机制：防止开销回弹

1. **Rule 创建审批**：新建 always-on rule 前先问"真的每次对话都需要？"
2. **Memory 定期清理**：每月清理过时 Memory
3. **月度 Token 审计**：运行 `token_audit.py` 检查膨胀
4. **进化协议守护**：在 self-evolution 机制中持续关注 Token 优化


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: clean | SkillSpector: clean (LOW)