Files
AnotherReplayReader/PLAN_ai_analysis_v2.md
T
2026-09-08 18:39:04 +02:00

358 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 分析 v2 计划:上下文策略与管线重构
## 状态
- 日期:2026-08-23
- 版本:v2.2。WIP/CONTEXT/ADR 旧文档已删除;思维链回传实验单独记录在 `AI_REASONING_CONTINUATION_RESEARCH.md`
- 关联文档:[AI_REASONING_CONTINUATION_RESEARCH.md](AI_REASONING_CONTINUATION_RESEARCH.md)
## 实施状态修订(推理保护已移除)
- 实测表明:截断/修改 `reasoning_content` 并伪造 tool call 续写会影响输出质量,已取消该方案。
- 当前代码不再包含 `AiReasoningGuard``ReasoningGuardEnabled`/`ReasoningGuardTokenLimit` 设置、推理保护 UI、`ReasoningGuard` 测试或相关 E2E。
- 仍保留对模型返回的 `reasoning_content` 的流式展示与 usage 统计;但不会截断、改写、回传或让它触发额外请求。
- 解决长思考的策略改为:提高输出 token 上限 + 让模型专注更短的时间范围(段内焦点窗口),同时仍提供尽量长的切片上下文并鼓励跨时间关联。
## 实施状态修订(2026-08-24 段内焦点窗口)
- 新增「段内焦点窗口」设计:**数据层尽量宽**(整段机械切片按上下文上限提供),**注意力层聚焦窄时间窗**(每个切片再切分为若干分析窗口,每轮一个窗口作为重点)。
- 实现:`FocusPlanner`(按 token 把切片切成 1~5 个窗口,上限 5、目标 12K/窗、过小切片不细分)+ `AIAnalyze.BuildFocusWindowUserPromptV2`(强调“数据=整段、重点=窗口、主动关联窗口外/跨时间事件”)。
- 管线影响:原「每段一次分析」改为「每段逐窗口分析」;每个窗口独立会话(system+摘要+总览+整段切片+已发现事实+窗口指令),保留逐窗口的验证/修订/回查;窗口小结与机器可读声明进入已发现事实(段内窗口间共享 + 跨段累积)。
- 提示词与知识文件(`AIAnalyze` 回退路径、`knowledge_default.md``knowledge_corona.md`)已同步说明窗口机制。
- 本项未涉及上下文预算公式变化:窗口不改变可见数据,只改变每轮“重点”的粒度。
### 提示词表述修订(2026-08-25
- 主指令进一步简化为**直接指出重点时间段**:如 `请重点分析 0:30.00 至 2:00.00 时间段的操作数据`
- 窗口编号(`第 k/n 窗口`)从主指令中移除,仅保留一句次要说明("本段已按时间划分为 N 个重点时间段,当前是第 k 个"):编号是程序内部概念,模型无法从原始数据核实,而时间范围可直接映射到数据;保留编号信息有助于用户/日志关联,但不再作为指令重心。
- 知识文件与单元测试已同步(PromptBuilders 断言时间段优先、编号降级)。
## 实施状态(2026-08-20
里程碑全部完成,代码已落地并通过 149 项单元测试(`AiV2.Tests`,见 §12 M7;启用真实回放诊断时为 151 项)。
| 里程碑 | 状态 | 备注 |
| --- | --- | --- |
| M1 预算与护栏 | ✅ | `AiModel.ContextBudget`0/空 = 档位默认 160K/100K)、`AiContextBudget` 安全系数与硬护栏、设置 UI 编辑项 |
| M2 管线重构 | ✅ | 机械分段 + 对局摘要 + 总览轮 + 分段独立会话 + 已发现事实 + 总结轮;移除 `[分段列表]` 解析与旧流式状态机;提示词与知识文件已重新生成 |
| M3 回查机制 | ✅ | `[回查]` 标记、容错时间解析、切片提取、每段 3 次上限、失败降级 Info |
| M4 验证修正 | ✅ | 所有权强/弱分层与 4 条规则、施法者归属(仅 `0x1FE/0x200`)、协议记录与校验、多 JSON 块合并、move 降级、首次出兵时间线、player 映射接线 |
| M5 知识修正 | ✅ | `knowledge_units_default.json` 按 mod 加载、旧提示词副作用修复、标签体系补全与加载校验、渲染按参战阵营过滤、用户知识 JSON 覆盖 |
| M6 修订 pass | ✅ | 段内 1 次修订、修订草稿实时流式显示、完成后草稿折叠、最终正文默认展开、UI 日志提示 |
| M7 测试与评估 | ✅/部分 | 单元测试完成;A/B 对比与估算校准需真实 API 运行(见 §13) |
**实施中的取舍与遗留**
- `Data/StringHashes.xml` 是随仓库分发的本地 SDK 临时快照(约 3.5MB / 47,860 条),后续应改为可配置路径或只打包需要的 hash 子集。
- Corona 结构化知识(`knowledge_units_corona.json`)尚未编写:Corona 当前走 flat 文本(不剥离、不注入结构化条目),验证回退到启发式。
- 修订 pass 的展示采用"修订草稿实时流式 + 完成后草稿折叠、最终正文默认展开";原隐藏修订决策中的"完全缓冲"已改为"默认折叠中间草稿"。
- `Fatal` 在“所有机器可读声明块均无法解析”时产生;修订输出为空时保留原分析。
- `MissingMachineReadableClaims` 为 Warning,并与其他 Warning/WeakEvidence 一样触发一次隐藏修订;是否保留该策略待 A/B 评估。
- 测试工程 `AiV2.Tests` 通过 `ProjectReference` 引用主工程;构建时通过 `AiV2TestsBuilding=true` 跳过主工程的 DLL 移动目标。
## 实施状态修订(2026-08-22
- “重新分析”策略:除 `Info` 外,`Warning/WeakEvidence/Contradiction/Fatal` 都触发一次隐藏修订;修订后遗留问题仅记录,不循环请求。
- 预算检查改为“估算 prompt + 输出/推理余量”,并在回查/修订前重新检查;`stream` 标志尊重模型配置。
- 事实索引:编队所有权按玩家隔离;接入 `0x1F6/0x22A`;unpack 歧义规则只作用于 MCV/基地车类实体。
- 知识:`aliases/alsoProducedBy` 已解析;摘要补充协议选择与所有权证据;总览的段落描述和回查提示会传入分段指令。
- 测试:当前 `AiV2.Tests` 默认 149 项断言全部通过;启用 `ARR_E2E_REPLAY=1` 时为 151 项。
### 2026-08-22 第二轮修订
- `eventClaims/timelineClaims` 现在也会校验:不存在 UnitId、技能与事实索引冲突、协议未在任何玩家选择中观察到都会产生验证问题。
- 总结轮支持一次回查:模型可请求远处原始区间,程序在同一总结会话中追加提供。
- 机械分段超过上限时先过滤纯选择/编队事件块,压缩无效才放宽预算。
- Corona flat 文本现在也按参战阵营过滤。
- `AiV2.Tests` 的真实回放诊断改为默认跳过(设置 `ARR_E2E_REPLAY=1` 启用);UI 状态栏显示推理 token。
- 思维链回传实验:主项目不再包含 `reasoning_content` 回传、截断、UI 实验开关或 tool call 历史构造代码,未进入生产管线。
- `AiV2.Tests` 仅保留 `OpenCodeGoFakeToolCallE2e` 专用测试:默认跳过,需同时设置 `ARR_AI_E2E=1``ARR_AI_E2E_TOOL=1`
- 实验结果、推荐方案与数据表格见 `AI_REASONING_CONTINUATION_RESEARCH.md`
### 2026-08-23 推理保护实现(历史记录,后续已移除)
- 主项目已实现默认关闭、模型级配置的推理保护:累计 `reasoning_content` 达到阈值后中断流式响应,并通过研究验证的 tool call 载体请求一次续写。
- 续写只在保留推理末尾依次追加 `[INTERNAL_REASONING_TRUNCATED]` 与中文收尾句,不插入中间 checkpoint;首请求不携带 `tools`,续写请求才注入工具定义和 `tool_choice=none`
- `ChatMessage` 支持 `reasoning_content`/`tool_calls`/`tool_call_id``Result` 保留完整推理、中断/续写状态与预算/错误信息。
- UI 触发推理保护后会显示首次请求与续写请求的完整消息日志;日志默认折叠,用户可展开检查 `messages`/`tools`/`tool_choice`
- UI 改为按阶段分组:总览/各段/总结各自独立容器;修订时保留旧版本并折叠,最新版本默认展开;机器可读声明 JSON 与验证结果作为独立折叠块,不再混在正文中。
- 推理保护诊断改为在触发时通过流式事件输出,位于续写思考块之前;总览重复日志已移除。
- 成功提取机器可读声明后,UI 正文会移除 `[机器可读声明]` JSON,只在折叠块中显示一次;推理保护诊断改为“消息数变化 + 新增 assistant/tool 消息摘要”,完整续写 JSON 仍作为折叠附件。
- 总览、分段修订、分段回查和总结回查都会显示实际发送的 user prompt(默认折叠)。
- `AiV2.Tests` 新增 `ReasoningGuard` 测试套件;默认测试总计 173 项通过。
## 1. 背景与目标
应用现有 AI 分析流程为"全量日志 + LLM 分段建议 + 分段分析 + 总结",经旧文档与代码审视,存在四类问题:上下文膨胀(每轮重发全量日志)、验证层可信度(施法者/目标混淆、所有权证据缺失、解析脆弱)、知识层作用域(结构化数据无 mod 维度、提示词与验证知识漂移)、修订机制未落地。
本计划的目标:
1. 用"部分操作记录 + 结构化上下文"替代"每轮全量日志",在不明显牺牲远距离关联能力的前提下提升长录像的分析质量与成本效率。
2. 只维护一条分析管线:"短录像 = 只有一个 slice",不保留两个独立模式。
3. 上下文预算成为每模型可配置的软上限,并把长期未使用的 `ContextLength` 接进护栏。
4. 修正验证层与知识层在本会话中发现的所有问题(见第 2 节追踪表)。
5. 落地隐藏修订 pass。
## 2. 问题追踪表(第一轮审视 + 后续讨论确认)
下表汇总 2026-08-20 会话对旧文档与代码的审视结论。后续讨论(所有权分层、缓存、预算、统一管线)调整了部分原始结论,表中"处理章节"指向本文的落地位置。
| # | 问题 | 处理章节 |
| --- | --- | --- |
| P1 | 结构化单位知识无 mod 维度:`knowledge_units.json` 是全局单例,Corona 盟军数据被基础版替换(如 `AlliedBomberAircraft` vs `AlliedAntiStructureBomberAircraft`),违背"每 mod 自包含"原则 | §8.1 |
| P2 | `GetSystemPrompt` 无条件执行旧 `BuildDefaultSystemPrompt`,即使走知识文件也会弹"缺乏苏联/未知地图"MessageBox(副作用) | §8.2 |
| P3 | 事实索引把特殊能力的施法者与目标混淆(`0x201/0x232` 的 ObjectId 不一定是施法者),Contradiction 校验可能误报/漏报 | §7.2 |
| P4 | 协议(`0x24E 选择协议`)不在验证体系,evidence schema 无法表达无单位能力 | §7.3 |
| P5 | 全量日志每轮重发、对话历史只增不减,长录像易超上下文;`ContextLength` 配置了但从未使用 | §4、§5、§6 |
| P6 | 解析健壮性:`[分段列表]` 缺失导致整体失败、`ParseAITimeSpan` 抛异常、机器可读声明只解析最后一个 JSON 块(中间块静默丢失) | §7.4 |
| P7 | `move` 证据只带坐标不带 UnitId,永远无法验证,却允许撑高置信结论 | §7.5 |
| P8 | 所有权归属:原建议"只能选中自己单位"过强;修正为强/弱分层(编队≈确定,选择≈弱信号) | §7.1 |
| P9 | 标签体系漂移:JSON 出现 `land/sea/miner/scout/support/siege/bomber` 等未定义 tag`KnowledgeTag` 常量未被执行 | §8.3 |
| P10 | `PlayerFirstProductionTime` 已建未消费,"首次出兵时间线"规则(如轰炸机)未做 | §7.6 |
| P11 | 修订 pass 未接线:`RequiresRevision` 存在但未用,`Fatal` 严重度从不产生,严重度语义未统一 | §10、§7.7 |
| P12 | 验证器/解析器/事实索引是纯逻辑但无测试 | §12 M7 |
| P13 | token 估算 `bytes/2.2` 对中文偏乐观,且无真实用量校准 | §4.3 |
| P14 | flat 文本作为单一 global 条目渲染,未参战阵营的知识也全部进入提示词(token 浪费) | §8.4 |
| P15 | 提示词/知识文件写死三阶段流程(`[分段列表]` 输出要求),需与 v2 管线同步修改 | §9 |
## 3. 决策摘要
| 决策点 | 结论 |
| --- | --- |
| 上下文预算 | 每模型 `ContextBudget` 软上限,默认档位:≥1M → 160K200K~256K → 100K<200K → 只支持短录像(单 slice) |
| 模式 | 单一管线;"全量模式"取消,短录像 = 1 个 slice |
| 分段 | 机械式(按 token 预算 + 事件数,带重叠);不再由 LLM 决定边界 |
| 段内焦点窗口 | 数据层 = 整段切片(尽量长);注意力层 = 每轮一个窗口(每段最多 5 个,目标 12K/窗);窗口可跨时间关联段内其他事件 |
| 总览轮 | 保留;输入为摘要 + 分段元数据(不读全量日志);输出允许跨段描述、跨段线索、回查建议 |
| 回查机制 | 进 v1;允许模型按需请求远处原始区间 |
| 缓存 | 稳定内容前置;跨段前缀 = system+摘要+总览;段内复用 = 前缀+slice(修订/回查共用) |
| 128K 及以下 | 允许短录像(切片后为 1 个 slice 时自然工作),不承诺长录像质量 |
| 修订 pass | 按隐藏修订方案在窗口内落地,每窗口最多 1 次 |
## 4. 上下文预算策略
### 4.1 语义
- `ContextBudget` = 一次请求的总 token 软上限(prompt + 输出/推理余量)。
- 用户给出的 150K / 90K 已经是保守值;为显式容纳估算误差与输出余量,默认档位取 **160K(≥1M/ 100K200K~256K**
- 每个模型可单独覆盖(新增 `AiModel.ContextBudget`0 表示用档位默认)。
### 4.2 输出余量与切片上限
- 输出余量 = `max(2 × max_tokens, 32K)`,推理模型的 thinking token 计入输出余量。
- 切片上限由预算反推:`slice_max = ContextBudget 固定开销 − 已发现事实 − 输出余量`
- 参考值:1M 档 slice ≈ 90K256K 档 slice ≈ 40K(固定开销约 system 20K + 摘要 3K + 总览 3K + 指令 1K)。
### 4.3 估算与护栏
- 现用 `bytes / 2.2` 对中文偏乐观;切片计算统一加安全系数 ×1.2。
- 用 API 返回的真实 `usage`(已收集 `PromptTokens`)校准估算系数,可记录在设置中或仅用于诊断。
- 硬护栏:估算总用量超过 `ContextLength` 的 90% 时拒绝发起请求并提示;超过 `ContextBudget` 时警告并自动收缩 slice。
## 5. 统一管线(单一模式)
流程:预处理 → 机械分段 → 对局摘要 → 总览轮 → 分段分析轮(每段独立会话)→ 总结轮。
### 5.1 预处理
- 保留现有 `CompactLevel` 压缩逻辑。
- 长录像的切片若仍超过 slice_max(密集事件区),对切片再做一次噪声过滤(如丢弃纯选择、空选择),仍超限则按时间二次细分。
### 5.2 机械分段
- 按事件累积估计 token,达到 slice_max 即切段;相邻段重叠前一段尾部 5%~10%(或 min(10%, 2K 事件))。
- 每段最小约 2K token;边界对齐 `TimeIndexedPrefixSums` 的事件分块。
- 分段数上限(如 20);超限时提高切片压缩力度而不是无限增加段数。
- N=1 时即旧"全量模式"的特例:整份日志作为一个 slice。
### 5.3 对局摘要(确定性)
- 来源:`ReplayFactIndex` + 规则采样器,不依赖 LLM 输出,保证同一次运行内稳定。
- 内容:玩家/阵营、首次出兵时间表、打包/展开链、建造者/生产者/所有权证据、协议选择、每段时间范围与事件数、每段采样关键事件(建造/摆放/出售/技能/协议)。
- 目标 2~5K token;是跨段缓存前缀的一部分。
### 5.4 总览轮
- 输入:system + 对局摘要 + 机械分段元数据(每段时间范围、事件数、采样事件)。
- 输出(自由格式,允许跨段):
- 每段标题 + 一两句概述(以机械段为锚点,不要求逐段对齐);
- 整局走势的跨段描述;
- 值得注意的跨段线索(如"第 1 段打包基地,第 3 段才重新展开");
- 回查建议(如"第 4 段分析时可回查 1:20~1:45")。
- 不读全量原始日志;输出在同一次运行内作为稳定前缀的一部分。
- 若总览轮输出明确建议合并/调整边界,v1 忽略,仅记录为后续可选优化。
- 总览轮失败(空输出/解析异常)→ 重试 1 次,仍失败则降级为"无总览输出"直接进入分段分析轮。
### 5.5 分段分析轮
- 每段一个独立阶段,段内再按“焦点窗口”逐轮分析。窗口划分与数据范围分离:
- **数据层(不变)**:每轮都提供当前段的完整切片 `slice_i`(尽量长、不超过上下文上限),用于跨时间关联。
- **注意力层(新增)**`FocusPlanner` 把切片按 token 切成 1~5 个窗口(默认目标 12K/窗;≤24K 的切片不细分);每轮只“重点分析”一个窗口,且鼓励关联窗口外/跨时间事件。
- 消息顺序(缓存关键,稳定在前):
`system → 对局摘要 → 总览输出 → slice_i → 已发现事实(1..i-1 + 段内前窗口) → 窗口指令(含窗口时间范围/事件数)`
- 窗口指令:段标题/概述 + "请重点分析第 N 段第 k/n 窗口(起止时间),数据为整段切片,可回查远处区间"。
- 输出:自然语言分析 + `[机器可读声明]`(沿用现有 schema,见 §7.4 的解析修正)。
- 同一窗口的后续请求(修订、回查)复用同一消息列表;窗口之间独立会话,但共享已发现事实。
### 5.6 已发现事实
- 每个窗口分析完成后,由验证过的机器可读声明 + 3~5 句小结组成追加条目,每项 ≤ ~1K token。
- 窗口小结追加在消息尾部,不影响前缀缓存;既是跨段关联的主要载体,也是同一段内窗口间的关联载体。
### 5.7 回查协议(v1
- 格式:段回复末尾输出 `[回查] mm:ss~mm:ss`(可多个)。
- 程序解析后从缓存日志切出该区间,作为同一会话的追加 user 消息发回。
- 限制:每段最多 3 次;单次区间 ≤ 10K token;总回查量受预算约束。
- 解析失败/越界/超限 → 忽略并记录 Info 级 issue,不中断流程。
- 时间解析复用容错解析器(见 §7.4),不允许抛异常导致整段失败。
- 回查区间内容不进入"已发现事实"(它是临时上下文,不跨会话累积)。
### 5.8 总结轮
- 输入:system + 摘要 + 总览 + 各段分析 + 已发现事实(不含原始日志)。
- 沿用现有指令:允许跨段修正之前的分析;修正理由记录回验证层。
- 后段分析不直接改写前段结论,跨段修正统一由总结轮承担。
## 6. 缓存设计
- 前缀顺序是核心实现细节:稳定内容在前,变量内容在后,不要在稳定段中间插入变化内容。
- 两层复用:
- 跨段:`system + 摘要 + 总览输出` 对所有分段请求一致(主要命中点);
- 段内:`以上 + slice_i` 被分析、修订、回查多次复用(P5 缓存诉求的落点)。
- 系统提示本身约 20K token,通常已超过各家缓存最小前缀要求;若未来换更短的 system,需复核。
- 成本说明:缓存折扣可达 90~95%,但本方案的主要动机是质量与延迟,成本是次要收益。
## 7. 验证与事实索引修正
### 7.1 所有权证据(强/弱分层)与校验规则(P8)
- 强证据(近乎确定是己方单位):`0x1FA 创建编队` 的成员;以建造者/出兵建筑身份出现(`0x207/0x209/0x205`);维修(`0x228`)、出售(`0x20A`)、矿车指令(`0x212/0x248`);特殊能力施法者(仅 `0x1FE/0x200`,见 §7.2)。
- 弱证据(可能是点了敌方单位):`0x1F5 选择单位``0x1FB/0x1FC` 通过编队状态解析出的成员可升级为强证据。
- 注意:`0x205` 不带新单位 UnitId,不能作为所有权证据(只能做时间线检查,见 §7.6)。
- 校验规则:
1. 声称 X 属于 PlayerA 且为 `confirmed`/`highly likely`,但 X 对 A 无任何强/弱证据 → `WeakEvidence`
2. X 存在 PlayerB 的强证据而声称属于 A → `Contradiction`
3. X 仅有 PlayerB 的弱证据且对 A 无证据 → `Warning`,建议降置信度。
4. 双玩家强证据冲突(异常/作弊操作)→ `Contradiction`,提示无法判定归属。
- `unitClaims.player` 接入上述规则。
### 7.2 特殊能力归属修正(P3)
- 只对布局确凿的 `0x1FE/0x200` 记录施法者;`0x201/0x232`(及待核实的 `0x1FF`)不用于施法者校验。
- 用真实回放抽样验证各命令类型的 ObjectId 含义后再扩展。
### 7.3 协议与选择类指令(P4)
- 事实索引记录 `0x24E 选择协议`evidence schema 新增 `protocol|时间|科技名`
- 事实索引/编队状态补全:`0x1F6``0x1FA``0x1FB``0x1FC``0x22A`;维护编队号 → 成员 UnitId 的状态表。
### 7.4 机器可读声明解析健壮性(P6)
- 机器可读声明不再"只取最后一个 JSON 块":改为解析标记之后的所有 JSON 块并合并声明(重复 unitId 取后块),或至少对被忽略的块记录 Info issue。
- v2 移除 `[分段列表]` 解析(分段改机械式),消除"分段标记缺失导致整体失败"的路径。
- 时间解析统一改为容错实现(返回 null + issue,而不是抛异常),回查与段边界共用。
### 7.5 move 证据处理(P7
- 提示词注明:`move` 证据只带坐标不带 UnitId,不能单独支撑 `confirmed`/`highly likely` 结论。
- 验证器对 move 证据不做交叉校验;若高置信声明仅有 move 类证据,补发 `WeakEvidence` 提示。
### 7.6 首次出兵时间线规则(P10)
- 消费 `PlayerFirstProductionTime`:如"某 UnitId 被操作的时间早于该玩家首次生产对应单位"→ `Contradiction`;"轰炸机在首次生产轰炸机之前就被操作"→ 要求降级或解释。
- 需要结构化知识的类型 tag 映射(如 `bomber`/`aircraft`/`producedBy`)支持"哪个单位名属于哪类",随 §8.1 的 mod 拆分落地。
### 7.7 严重度语义统一(P11
- 明确 `Fatal` 的产生条件:段输出为空、机器可读声明完全不可解析,且修订后仍失败。
- `MissingMachineReadableClaims` 当前为 Warning(仅记录);是否升级为一次"修复请求"由 M6 与修订 pass 一并决定。
## 8. 知识架构修正
### 8.1 结构化数据按 mod 拆分(P1)
- `knowledge_units.json` 按 mod 拆分(如 `knowledge_corona_units.json`)或加 mod 键,与 flat 文本同作用域。
- `StripUnitSections` 只剥离"该 mod 确有结构化数据"的阵营;硬编码章节标题改为可配置/可校验。
### 8.2 旧提示词构建副作用修复(P2)
- `GetSystemPrompt` 先查知识文件,命中即走 `RenderAsPrompt`;旧 `BuildDefaultSystemPrompt` 的副作用(苏联/未知地图 MessageBox)只在 fallback 路径执行。
### 8.3 标签体系执行(P9
- 加载 `knowledge_units.json` 时校验未知 tag 并告警;补全/收敛 taxonomy`land/sea/miner/scout/support/siege/bomber` 等要么进定义、要么移除)。
- 加载告警在 Debug/设置页可见,避免静默漂移。
### 8.4 渲染过滤(P14
- flat 文本按参战阵营过滤非参战阵营章节;结构化渲染只渲染参战阵营(`RenderAsPrompt` 已有 factionNames 参数,flat 文本需要配套切分)。
### 8.5 用户知识 JSON 加载(实施遗留)
- 落地 `AnotherReplayReader.user_knowledge.json`:按 id 覆盖内置条目,加载顺序:内置 → 用户覆盖。
## 9. 提示词与知识文件更新
### 9.1 v2 流程(P15
- 三阶段流程改为:总览轮(无 `[分段列表]` 输出)→ 分段分析轮 → 总结轮。
- 同步修改 `knowledge_default.md``knowledge_corona.md``BuildDefaultSystemPrompt` 回退路径和 `tools/expand_knowledge.py` 生成的模板。
### 9.2 选择/所有权表述修正(P8)
- 修正"选择单位……这些操作的对象是玩家自己的单位":选择可能包含敌方单位(不能下达命令);加入编队几乎可确定是己方单位。
### 9.3 evidence 格式更新(P4、P7
- 补充 `protocol|时间|科技名` 类型。
- 注明 `move` 证据的验证限制(见 §7.5)。
## 10. 修订 passP11
- 窗口内执行:草稿 + 验证 issue + 相关事实 → 干净修正版;每窗口最多 1 次。
- 修订后仍 `Fatal` → 回退显示原文 + 警告(`Fatal` 条件见 §7.7)。
- 修订请求复用窗口会话(同一前缀,缓存友好)。
- UI:增加"验证器发现并修正 N 个问题"提示;修订草稿实时流式显示,完成后自动折叠,最终正文默认展开。
## 11. 设置与 UI
- `AiModel.ContextBudget`0 = 档位默认);`AIProviderSettingsControl` 增加编辑项。
- 128K 及以下模型:允许短录像(单 slice),设置页提示"长录像不保证质量"。
- 请求 Token 构成展示:system / 摘要 / 总览 / slice / 已发现事实 / 输出余量。
- 可选:回查统计(次数、命中率)与估算系数校准结果显示。
## 12. 实施步骤(里程碑)
1. **M1 预算与护栏**`ContextBudget` + 档位默认 + 估算安全系数 + 超限警告/拒绝。
2. **M2 管线重构**:机械分段 + 对局摘要 + 总览轮 + 分段独立会话;移除 `[分段列表]` 解析(P5、P6)。
3. **M3 回查机制**:标记解析(容错时间解析)、切片提取、限流、失败降级。
4. **M4 验证修正**:所有权证据与规则(§7.1)、施法者归属(§7.2)、协议与选择指令(§7.3)、JSON 解析健壮性(§7.4)、move 降级(§7.5)、首次出兵时间线(§7.6)、严重度语义(§7.7)。
5. **M5 知识修正**:mod 拆分(§8.1)、副作用修复(§8.2)、标签校验(§8.3)、渲染过滤(§8.4)、用户知识 JSON(§8.5)。
6. **M6 修订 pass**:段内修订 + 草稿流式显示 + 完成后折叠 + 最终正文默认展开(§10)。
7. **M7 测试与评估**:单元测试(解析器/验证器/事实索引/分段)+ A/B 对比(§13)。
依赖关系:M2 先于 M3;M4/M5 可与 M2 并行;M6 依赖 M2 + M4M7 覆盖全部。
完成标准(每步):`dotnet build` 通过;对应功能用手工回放验证一次;解析/验证改动附单元测试(M7 前至少保证新增逻辑可测)。
## 13. 评估方法
- 指标:验证 issue 数量与严重度分布;关键事件覆盖率(人工清单抽查);总 token/费用;耗时;回查次数与命中率;总览轮失败率。
- A/B:同一录像对比现状(全量模式)与 v2 管线,优先选短/中/长各一局。
- 校准:用真实 `usage` 修正估算系数,检查预算是否被实际超用。
## 14. 风险与开放问题
- 密集事件段可能仍超 slice 预算 → 切片压缩与二次细分是兜底。
- 总览轮质量影响后续所有段 → 摘要/采样质量需要迭代;失败降级路径见 §5.4。
- 回查滥用或格式不稳定 → 限流 + 失败降级(§5.7)。
- 修订后机器可读声明可能与正文不一致 → 修订轮要求同时重出声明并重新验证。
- 段内焦点窗口依赖 `EventSpan` 时间索引;若索引缺失(防御性回退)则单窗口分析。
- 用户在运行中修改设置导致前缀变化 → 缓存失效,仅影响本次运行。
- 开放:是否允许总览轮建议边界调整(v2 候选);`MissingMachineReadableClaims` 是否触发修复请求(§7.7)。
## 15. 本计划不涉及
- 非 AI 分析功能、其他 UI 改动、第三方库升级。