codex wip

This commit is contained in:
2026-07-06 18:36:39 +02:00
parent 2ada187ae0
commit 645189f21c
9 changed files with 829 additions and 10 deletions
+67 -3
View File
@@ -17,13 +17,51 @@ namespace AnotherReplayReader.Utils
{
internal sealed class AIAnalyze
{
public static string GetSystemPrompt(Replay replay, ImmutableSortedDictionary<int, Player> players)
public static string GetSystemPrompt(
Replay replay,
ImmutableSortedDictionary<int, Player> players,
AiPromptSettings? promptSettings = null)
{
var defaultPrompt = BuildDefaultSystemPrompt(replay, players);
return ComposeSystemPrompt(defaultPrompt, promptSettings);
}
public static string ComposeSystemPrompt(string defaultPrompt, AiPromptSettings? promptSettings)
{
var customSystemPrompt = promptSettings?.CustomSystemPrompt ?? string.Empty;
if (promptSettings?.UseCustomSystemPrompt == true
&& !string.IsNullOrWhiteSpace(customSystemPrompt))
{
defaultPrompt = customSystemPrompt;
}
var additionalRules = promptSettings?.AdditionalRules ?? string.Empty;
if (!string.IsNullOrWhiteSpace(additionalRules))
{
defaultPrompt = defaultPrompt.TrimEnd()
+ "\n\n# 用户自定义补充规则\n"
+ additionalRules.Trim();
}
return defaultPrompt.Replace("\r", "");
}
public static string BuildDefaultSystemPrompt(Replay replay, ImmutableSortedDictionary<int, Player> players)
{
var generalDescriptions = @"
你是一位 RTS 游戏数据分析师,你擅长从大量数据中发现有趣的规律和细节。
用户则是一位玩家,用户会向你提供玩家操作记录,你要对其进行分析。
# 核心原则
- 你只能根据用户提供的操作记录、玩家信息、下方游戏规则和明确给出的背景知识进行分析。
- 不要使用现实世界常识或其他 RTS 游戏常识覆盖这里的游戏设定。例如:步兵、直升机、建筑水陆摆放、运输能力、两栖能力都必须以这里的规则和单位描述为准。
- 不确定时必须保留多个候选,不要为了让解说流畅而过早下定论。
- 对 UnitId、单位类型、战术意图的判断必须区分证据等级:确定、高度可能、可能、待确认、已排除。
- 每个关键推理都应当包含支持证据;如果存在会推翻该推理的反证,也要主动指出。
- 如果某个技能或行为可以对应多个单位,先列出候选,并说明还需要哪些后续迹象才能确认。
- 对已经被操作记录直接否定的判断必须修正或放弃,不要坚持原结论。
# 输入格式
## 用户初始输入
- 玩家信息
@@ -83,11 +121,36 @@ namespace AnotherReplayReader.Utils
- 也可以重点关注PlayerTech、英雄、工程师
- 按照**推理指南**进行详细的思考与推理,列举你的推理与发现
- 输出:该阶段的各个主要事件,以及你的推理和发现
- 假如推测 UnitId 对应的单位,请在正文中自然描述,并在末尾输出机器可读声明,方便程序验证
## 3. 最终总结阶段
触发条件:用户输入包含:""请对以上内容进行总结""
- 输出:所有分析的总结,以及这次对局的完整介绍
# 机器可读声明
仅限于:分段分析阶段(第2阶段)
如果你对 UnitId、关键事件或时间线做出了可验证推测,请在回答末尾附加下面格式。
必须先输出一行`[机器可读声明]`,然后输出一个 JSON 代码块:
[机器可读声明]
```json
{
""unitClaims"": [
{
""unitId"": 123,
""player"": ""PlayerA"",
""claim"": ""AlliedMCV"",
""evidenceLevel"": ""possible"",
""evidence"": [""8:30 使用 SpecialPower_UnpackReplaceSelf""],
""alternatives"": [""AlliedMiner 展开后的指挥中心""],
""needsConfirmation"": [""是否曾使用 SpecialPower_PackReplaceSelf"", ""后续是否作为建造者出现""]
}
],
""eventClaims"": [],
""timelineClaims"": []
}
```
如果没有可验证推测,可以输出空数组。不要在 JSON 里写注释。
# 推理指南
推理需要分成多个阶段
1. 观察
@@ -953,6 +1016,7 @@ PlayerA: 开始出兵
请按照按照[观察]、[分析]、[推理]、[进一步思考(可选)]的步骤,对各个事件进行分析和推理。
假如当前阶段存在一些较为重要的单位、而且能够推测出它们可能是什么单位,则可以列出单位的UnitId以及你对单位的推测
如果你列出了 UnitId 推测、关键事件推测或时间线推测,请在回答末尾附加`[机器可读声明]` JSON 代码块;如果没有相关推测,则输出空数组。
";
return instruction.Trim().Replace("\r", "");
}
@@ -1273,8 +1337,8 @@ PlayerA: 开始出兵
result.ReasoningTokens = GetIntegerProperty(usage, "reasoning_tokens") ?? result.ReasoningTokens;
}
// 提取 usage(如果存在)
if (doc.RootElement.TryGetProperty("error", out var error) && usage.ValueKind == JsonValueKind.Object)
// 提取 error(如果存在)
if (doc.RootElement.TryGetProperty("error", out var error) && error.ValueKind == JsonValueKind.Object)
{
if (error.TryGetProperty("message", out var message))
{