focus on intervals, and fix provider

This commit is contained in:
2026-09-08 14:44:34 +02:00
parent 579cd8e4b3
commit acad70aaac
11 changed files with 1163 additions and 286 deletions
+77 -10
View File
@@ -1,4 +1,4 @@
using AnotherReplayReader.ReplayFile;
using AnotherReplayReader.ReplayFile;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@@ -175,17 +175,18 @@ namespace AnotherReplayReader.Utils
# 输出要求
## 1. 总览阶段
触发条件:用户输入包含:""请先对整局进行总览""
- 输入中包含:对局摘要、机械分段的各段时间范围与事件数量、每段的关键事件采样
- 输入中包含:对局摘要、机械分段的各段时间范围与事件数量、每段的关键事件采样;本阶段不会获取原始操作记录
- 你的任务:
- 描述整局走势,允许跨越多个分段给出判断与线索,不要只逐段罗列
- 为每个分段给出简短标题与一句话概述,按 `#N 标题:概述` 的格式输出在 `[分段概述]` 块中(N 为分段编号)
- 指出值得跨段关联的事件(例如:第 1 段打包基地,第 3 段才重新展开)
- 如果某个分段在分析时可能需要核实远处原始记录,在对应行后另起一行写 `回查: mm:ss~mm:ss`
- 只描述对局摘要中明确支持的内容,不要展开推断摘要没有依据的整局走势
- 如果某个分段在后续分析时可能需要对局摘要之外的原始区间,在对应行后另起一行写 `回查: mm:ss~mm:ss`,程序会把它作为该段的回查建议
- 分段边界是程序预先切好的,不要自行划分或修改分段;不要输出 `[分段列表]`
## 2. 分段分析、推理阶段
触发条件:用户输入类似于:""请重点分析第N段([BEGIN]至[END]""
- 输入中包含:当前分段的原始操作记录切片、之前各段的已发现事实摘要,以及整局总览
- 输入中包含:当前分段的原始操作记录切片、之前各段的已发现事实摘要,以及整局总览
- 程序会把一个分段按时间切分为若干“分析窗口”(每轮一个窗口)。你当前分析的是其中一个窗口,但完整的分段切片仍然是你能看到的数据范围
- 你的重点任务:分析当前窗口时间范围内的主要事件与上下文;但同时应主动查看并关联窗口之外、仍在本段切片中的相关事件(例如生产、建造、打包/展开、技能释放的后续影响、部队调动)
- 如果某个远距离事件与当前分析相关,可以输出 `[回查] mm:ss~mm:ss`(每段最多 3 次)请求对应原始区间,程序会把该区间的原始记录发给你
- 选取该阶段的主要事件,以及和它们的上下文
- 也可以选择数个其他有分析价值的事件
@@ -197,7 +198,7 @@ namespace AnotherReplayReader.Utils
- 按照**推理指南**进行详细的思考与推理,列举你的推理与发现
- 输出:该阶段的各个主要事件,以及你的推理和发现
- 假如推测 UnitId 对应的单位,请在正文中自然描述,并在末尾输出机器可读声明,方便程序验证
- 最后用一行 `[小结]` 输出 2~3 句该最重要的结论,供后续分段参考
- 最后用一行 `[小结]` 输出 2~3 句该份分析最重要的结论,供后续分析窗口与后续分段参考
## 3. 最终总结阶段
触发条件:用户输入包含:""请对以上内容进行总结""
@@ -1069,9 +1070,11 @@ PlayerA: 开始出兵
public static string BuildOverviewUserPrompt(IReadOnlyList<ReplaySlice> slices)
{
var sb = new StringBuilder();
sb.AppendLine("请先对整局进行总览。");
sb.AppendLine("请基于对局摘要对分段进行总览。");
sb.AppendLine("下方是程序生成的分段元数据(分段边界由程序预先切好,不要修改)。对局摘要已在系统消息中提供。");
sb.AppendLine("请描述整局走势(允许跨分段),并为每个分段给出标题与一句话概述。");
sb.AppendLine("本阶段不会获取原始操作记录。请只根据对局摘要和分段元数据,为每个分段给出标题与一句话概述。");
sb.AppendLine("如果某段在后续分析时可能需要对局摘要之外的原始区间,请在该段后另起一行写 `回查: mm:ss~mm:ss`,程序会把它作为该段的回查建议。");
sb.AppendLine("不要展开推断对局摘要没有明确支持的内容。");
sb.AppendLine();
sb.AppendLine("[分段元数据]");
foreach (var slice in slices)
@@ -1079,7 +1082,7 @@ PlayerA: 开始出兵
sb.AppendLine($"#{(slice.Index + 1)} {MatchDigestBuilder.FormatTime(slice.Start)}~{MatchDigestBuilder.FormatTime(slice.End)} 事件数 {slice.EventCount} 约 {slice.EstimatedTokens} token");
}
sb.AppendLine();
sb.AppendLine("输出格式:先自由描述整局走势与跨段线索,然后输出 [分段概述] 块,每段一行 `#N 标题:概述`;如某段需要核实远处原始记录,在对应行后另起一行写 `回查: mm:ss~mm:ss`。");
sb.AppendLine("输出格式:直接输出 [分段概述] 块,每段一行 `#N 标题:概述`;如某段建议后续回查,在对应行后另起一行写 `回查: mm:ss~mm:ss`。不要输出整局叙述。");
return sb.ToString().Replace("\r", "");
}
@@ -1114,6 +1117,70 @@ PlayerA: 开始出兵
return instruction.Trim().Replace("\r", "");
}
/// <summary>
/// 段内焦点窗口指令:数据范围 = 整个机械分段切片(尽量长,但不超过上下文上限),
/// 分析“重点”只落在窗口时间段内;同时鼓励模型跨时间关联窗口外的背景事件。
/// </summary>
public static string BuildFocusWindowUserPromptV2(
int segmentIndex,
int totalSegments,
ReplaySlice slice,
int windowIndex,
int windowCount,
FocusWindow window,
int sliceEventCount,
int windowEventCount,
string? title,
string? description = null,
IEnumerable<string>? backqueryHints = null)
{
var beginText = segmentIndex <= 0 ? "游戏开始" : MatchDigestBuilder.FormatTime(slice.Start);
var endText = segmentIndex >= totalSegments - 1 ? "游戏结束" : MatchDigestBuilder.FormatTime(slice.End);
var windowBeginText = MatchDigestBuilder.FormatTime(window.Start);
var windowEndText = MatchDigestBuilder.FormatTime(window.End);
var titleLine = string.IsNullOrWhiteSpace(title) ? "" : $"\n段落标题:{title}";
var descriptionLine = string.IsNullOrWhiteSpace(description) ? "" : $"\n段落概述:{description}";
var hintLine = backqueryHints is { } hints && hints.Any()
? "\n总览建议可回查区间:" + string.Join("、", hints)
: "";
string windowInstruction;
string windowHeader;
if (windowCount <= 1)
{
windowInstruction =
$"请重点分析 {beginText} 至 {endText} 时间段的操作数据。";
windowHeader = "\n本段数据量适中,作为一个整体重点时间段分析。";
}
else
{
windowInstruction =
$"请重点分析 {windowBeginText} 至 {windowEndText} 时间段的操作数据。";
windowHeader =
$"\n本段已按时间划分为 {windowCount} 个重点时间段,当前是第 {windowIndex + 1} 个(后续时间段会依次分析)。";
}
var instruction = @$"
{windowInstruction}
{windowHeader}
本重点时间段约有 {windowEventCount} 条操作信息。
下方已提供第{segmentIndex + 1}段({beginText}至{endText})的完整操作记录(约 {sliceEventCount} 条)作为数据与背景。{titleLine}{descriptionLine}
{hintLine}
你可以参考输入中的对局摘要、整局总览与之前各窗口/各段的已发现事实。
你的重点任务是分析本重点时间段内的主要事件与它们的上下文,但不要局限于此时间段:
- 请主动查找并关联本时间段之外、但处于本段完整记录中的相关事件。如果当前事件与更早或更晚的事件存在关联(例如生产、建造、打包/展开、技能释放的后续影响、部队调动),请结合这些跨时间事件进行分析。
- 如果某个远距离事件与当前分析相关,可以输出`[回查] mm:ss~mm:ss`(每段最多 3 次)请求对应原始区间。
- 不要因为重点时间段短就把每一条操作都当作单独事件,也不要省略该时间段内的重要事件。
请按照[观察]、[分析]、[推理]、[进一步思考(可选)]的步骤,对本时间段内的事件进行分析和推理。
假如当前阶段存在一些较为重要的单位、而且能够推测出它们可能是什么单位,则可以列出单位的UnitId以及你对单位的推测。UnitId 推测最多 10 个,事件推测最多 5 个,时间线推测最多 3 个。
如果你列出了 UnitId 推测、关键事件推测或时间线推测,请在回答末尾附加`[机器可读声明]` JSON 代码块;如果没有相关推测,则输出空 JSON 对象。
最后用一行 `[小结]` 输出 2~3 句本重点时间段最重要的结论。
";
return instruction.Trim().Replace("\r", "");
}
public static string BuildSummaryUserPromptV2(int totalEventCount)
{
var instruction = $@"