本节摘要:会议式协作的开销主要不在单次调用,而在轮次累积。本节给一场会议立三本账——轮次账、调用账、token 账,教你从日志算出每本账,再给出三个命中率最高的优化手段:议题分层、记忆瘦身、验收前置。读完你能对任何一份日志说出"钱花在哪、哪轮最亏"。
本节承接 4.2:跑通了,开始算账。会议效率审计的对象不是模型速度——模型快慢你控制不了——而是会务浪费:重复装载的上下文、可并行却串行的议题、不产生信息增量的表态轮次。这些才是你能优化的部分。
轮次是第一账本。从日志数出三类轮次:生产轮次(产生新信息:工具调用、计算、写作)、表态轮次(纯验收与确认)、循环轮次(同一议题反复出现)。健康会议的生产轮次应占六成以上;循环轮次超过两成,必有议题粒度或验收标准的问题。
def audit_turns(log_lines: list) -> dict: """轮次账:把日志轮次分类统计。 log_lines: 每项形如 '轮次07|浏览器专家|T2受阻...' 的日志行""" from collections import defaultdict counter = defaultdict(int) for line in log_lines: text = line.split("|", 2)[-1] if any(k in text for k in ("受阻", "重试", "再次尝试")): counter["循环轮次"] += 1 elif any(k in text for k in ("验收", "确认", "达标")): counter["表态轮次"] += 1 else: counter["生产轮次"] += 1 total = sum(counter.values()) loop_ratio = counter["循环轮次"] / max(total, 1) verdict = ("循环占比过高,先查议题粒度" if loop_ratio > 0.2 else "轮次结构健康") return {**dict(counter), "总轮次": total, "诊断": verdict} # 输出: # audit_turns(["轮次01|主持人|议题转写", "轮次02|主持人|派单", # "轮次03|浏览器专家|T2受阻,重试", "轮次04|浏览器专家|再次尝试失败", # "轮次05|主持人|验收达标"]) # -> {'循环轮次': 2, '表态轮次': 1, '生产轮次': 2, '总轮次': 5, # '诊断': '循环占比过高,先查议题粒度'}
第二账本按工具与模型分别计数。工具调用的开销在真实副作用(浏览器会话、执行时长),模型调用的开销在 token。分别计数后,优化目标会自己浮出来——比如"搜索调用 22 次,其中 9 次是同义改写重查"。
第三账本看每轮上下文的构成。方法是把每轮送入模型的文本按来源分桶:系统提示词、议题卡、历史对话、工具回报、召回记忆。多数会议里,工具回报是头号房客(整页网页文本动辄数千字),其次是历史对话。
def token_basket(turn_payloads: list) -> dict: """token 账:按来源分桶估算上下文构成。 turn_payloads: 每项 {'来源': ..., '字符数': ...}""" from collections import defaultdict basket = defaultdict(int) for p in turn_payloads: basket[p["来源"]] += p["字符数"] total = sum(basket.values()) top = max(basket, key=basket.get) return {"分桶": dict(basket), "总量": total, "头号房客": f"{top}(占 {basket[top]*100//max(total,1)}%)"} # 输出: # token_basket([{'来源': '系统提示词', '字符数': 800}, # {'来源': '历史对话', '字符数': 4200}, # {'来源': '工具回报', '字符数': 9600}, # {'来源': '召回记忆', '字符数': 900}]) # -> {'分桶': {'系统提示词': 800, '历史对话': 4200, '工具回报': 9600, '召回记忆': 900}, # '总量': 15500, '头号房客': '工具回报(占 61%)'}
4.2 案例里已经验证过:把串行巨单按依赖分层(2.4 的分层算法)后,轮次降四成。这是零成本优化——不改任何配置,只改议题卡的组织方式。
工具回报是头号房客,但原始回报又必须完整(演算席的算式不能删)。解法是分层入史:入上下文的是摘要,入任务记忆的是全文。主持人需要细节时,按 2.5 的检索记忆取回,而不是永远背着全文跑。
def slim_tool_report(full_text: str, keep_fields: set) -> str: """工具回报瘦身:上下文只留验收必需字段。 full_text: 完整回报;keep_fields: 本轮验收必需的字段名""" kept, dropped = [], 0 for line in full_text.split("\n"): if any(f in line for f in keep_fields): kept.append(line) else: dropped += 1 kept.append(f"[略去 {dropped} 行过程明细,全文已存任务记忆]") return "\n".join(kept) # 输出(节选): # slim_tool_report("价格1: 99元/月\n价格2: 299元/月\n网页导航过程...30行", # {"价格"}) # -> '价格1: 99元/月\n价格2: 299元/月\n[略去 30 行过程明细,全文已存任务记忆]'
循环轮次的最大来源是"做完才发现不合格"。验收标准写在议题卡里(2.4 四要素法)后,专家开工时就知道终点的样子,返工率显著下降。给一个量化视角:一次返工至少两轮(退回加重做),议题卡多写二十字,可能省下四轮。
def optimize_priority(audit: dict) -> list: """按审计结果给出优化动作的优先级排序。""" actions = [] if audit.get("循环轮次", 0) > audit.get("生产轮次", 1) * 0.3: actions.append("P0 验收前置:重写议题卡的标准字段") if "工具回报" in audit.get("头号房客", ""): actions.append("P1 记忆瘦身:工具回报摘要入史") if audit.get("串行议题"): actions.append("P2 议题分层:按依赖并行下发") return actions or ["无高优先级优化项"] # 输出: # optimize_priority({"循环轮次": 5, "生产轮次": 10, "头号房客": "工具回报"}) # -> ['P0 验收前置:重写议题卡的标准字段', 'P1 记忆瘦身:工具回报摘要入史']
两条反直觉的边界,帮你省下无效的折腾:
💡 关键直觉:会议开销的公式是"轮次 × 每轮上下文体量"。优化手段千千万,都落在"减轮次"或"减体量"两个因子上;对着日志找到最肥的那个因子,就找到了你的最大优化项。
背景:贯穿案例完整任务首轮跑完,三本账如下——轮次账 23 轮(循环 6、表态 5、生产 12);调用账显示浏览器会话 7 次、搜索 9 次;token 账显示工具回报占 61%。操作:第一轮优化上 P0(验收前置,重写两张议题卡的标准字段)与 P2(议题分层),复跑得 16 轮,循环轮次归 1;第二轮上 P1(回报瘦身),单轮上下文体量降四成,全任务 token 总量从基准的约 1.6 倍降到 0.9 倍。结果:同样质量的纪要,开销近乎减半。解读:注意优化顺序——先消灭返工(减轮次),再瘦身(减体量),顺序反了则瘦身的效果被返工吃掉。
变式:若你的任务对延迟敏感(用户在等结果),把"轮次"换成"墙钟时间"做主账本:并行议题的收益不变,表态轮次可适当合并(两三个验收并成一轮表态),但每轮的验收范围要写明。