RiftCoach 是一个基于 Riot 公开赛后数据的英雄联盟复盘与训练助手。项目坚持“程序计算事实、知识库提供解释依据、模型负责组织表达、独立评测决定是否发布”的设计原则。
当前版本包含 RiftCoach 独立领域核心、质量门控 Harness、可靠 Tool Runtime、RAG v1、受限
AgentRuntime、PostgreSQL 异步任务基座、玩家身份绑定,以及 owner-scoped Conversation/Message
foundation、typed Memory、Training Plan/Progress、Memory-aware Context/terminal turns 和 owner lifecycle/
export。阶段 6 Session/Memory V1 已由 cbc7cbd / Actions 32408101770 完成最终 exact-SHA 公共闭环。
Stage 7 标准 MCP 与动态 Meta V1 已由 fac6fe0 / Actions 32484257736 完成最终公共闭环:RiftCoach
既能通过标准 MCP 调用受限 OP.GG lane-meta,也能被官方 MCP SDK 经 stdio 调用。项目没有直接合并
EchoMind 或 AGI-Saber;正式 Auth/RSO、SSE/前端、Riot+OP.GG 精确版本融合与阶段 8 恢复/Multi-Agent
仍未实现。
如果你想理解这些能力怎样一步步搭建、对应哪些源码/测试、面试时怎样准确表述,请从 学习与工程证据索引 开始。项目执行位置仍以 当前执行状态 为唯一事实源。
当前数据分工:
- Riot API:账号、对局详情与时间线事实;
- MatchAnalyzer:补刀、经济、伤害、视野、参团率与死亡时间等确定性指标;
- Data Dragon:英雄、装备、符文和召唤师技能的官方静态中文映射;
- OP.GG MCP:受限 lane-meta 当前快照,固定 partial provenance,不覆盖 Riot 官方事实;
- 本地 RAG v1:混合召回、来源过滤、引用证据、拒答和独立保留集门禁;
- 智谱 GLM:依据事实与检索证据生成教练式中文报告;
- 独立评测:检查数字忠实度、证据边界与过度推断,并支持受限修订和再评测。
领域输出使用版本化的 Player Summary Schema v1.0。短局会保留明细但不计入聚合,Timeline 缺失会显式记录状态而不会被伪装成零事件。
Riot ID
→ 最近对局与时间线
→ 确定性指标汇总
→ Data Dragon 静态映射
→ Markdown 统计报告
→ 本地知识检索
→ GLM 教练式草稿
→ 独立事实评测
→ 受限修订与再评测
→ 通过后发布
RiftCoach 只分析已经结束的公开赛后数据,不提供实时对局辅助,不读取客户端内存,不追踪隐藏敌方信息,也不自动操作游戏。
动态 Meta 已通过标准 MCP 接入受限 OP.GG lane-meta 当前快照,并以 partial provenance 与 Riot 玩家事实 严格分层。精确 patch/source freshness、全部 OP.GG 工具,以及 Riot 官方版本/静态/patch 与 OP.GG 的 多源 join 尚未实现。
要求 Python 3.11 或更高版本。
py -3.11 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"复制 .env.example 为 .env,填写本地 Riot API 与智谱 GLM 配置。不要提交 .env。
仓库现在包含一个显式依赖注入的 FastAPI Adapter:app.api.main:create_app(...),以及
PostgreSQL durable task、owner-scoped 查询、POST 202 入队、独立 polling Worker 的控制面合同。
HTTP 层不直接选择 Skill、拼 Prompt 或调用 Provider。6A-6 已为这个基座补齐默认关闭 CORS、
日志/Secret 脱敏、有限容量、terminal delete 的隐藏与补偿、retention 和安全指标。6A-7 又完成
API+Worker+PostgreSQL packaging、真实 Worker composition 和 no-I/O Linux smoke;提交 adf53e5 / Actions
32146760003 的 pytest、真实 PostgreSQL 与 Linux packaging 三个 job 已完成 exact-SHA 公共验证。
这些能力仍不等于正式公网鉴权/HTTPS、SSE 或自动 lease/reclaim。Session/Memory V1 已在后续 6B 闭环, 但真实外部 Worker 组合与 Docker/Compose 控制面已通过公共 CI,但仍不能称为正式公网部署;PostgreSQL job 继续是 task 并发与生命周期语义的阻塞证据,Linux smoke 也不证明模型报告质量。
仓库还包含 POST /player-links 与 GET /player-links/{link_task_id}。POST 只把外服 Riot ID、routing
region 和关系角色作为持久化 intent 入队并快速返回;独立 Player Link Worker 才会在数据库事务外调用
Account-V1,随后用一个 PostgreSQL 短事务收敛稳定 PUUID subject、当前 Riot ID alias、owner
relationship 和 Link terminal。API 响应不会返回完整 PUUID,查询始终受 trusted owner 作用域限制。
先做不调用 Riot API 的 composition 检查:
python -m scripts.run_player_link_worker --worker-id player-link-worker-1 --check只学习 Player Link 时,填入本地 RIOT_API_KEY 后可显式只启动 API 与 Link Worker,避免同时启动需要
模型 Provider 配置的 review Worker:
docker compose --profile runtime up --build api player-link-worker若改用 docker compose --profile runtime up --build 启动完整 runtime profile,还必须同时配置当前
LLM Provider/Model/Key;后文的完整 review Worker preflight 仍然适用。服务 ready 后,可在本机固定开发
owner 下创建绑定 intent:
$body = @{
riot_id = "<GAME_NAME>#<TAG_LINE>"
routing_region = "asia"
relationship_role = "self"
} | ConvertTo-Json
$link = Invoke-RestMethod `
-Method Post `
-Uri http://localhost:8000/player-links `
-ContentType application/json `
-Body $body
Invoke-RestMethod `
-Method Get `
-Uri ("http://localhost:8000" + $link.link)这里只能证明 Riot ID 能解析为一个外服 PUUID;relationship_role=self 是 owner 的声明,不是 Riot
账号控制权证明。当前没有正式 Auth/RSO,因此不能创建 rso_verified,也不能把本地 fixed owner
配置冒充公网多用户鉴权。
当 Link 查询已经是 succeeded 时,可以用返回的 relationship_id 创建固定玩家主体的 Conversation,
再追加第一条 user Message。公共请求没有 owner、PUUID、subject、role 或 source 字段:
$linkState = Invoke-RestMethod `
-Method Get `
-Uri ("http://localhost:8000" + $link.link)
$conversationBody = @{
relationship_id = $linkState.relationship_id
} | ConvertTo-Json
$conversation = Invoke-RestMethod `
-Method Post `
-Uri http://localhost:8000/conversations `
-Headers @{ "Idempotency-Key" = "local-conversation-1" } `
-ContentType application/json `
-Body $conversationBody
Invoke-RestMethod `
-Method Post `
-Uri ("http://localhost:8000/conversations/{0}/messages" -f `
$conversation.conversation_id) `
-ContentType application/json `
-Body (@{ content = "请复盘我最近的状态" } | ConvertTo-Json)Conversation/Message foundation 本身不会因追加消息自动触发 Agent。后续 6B-4 至 6B-9 已在独立接口上 完成 Conversation-bound Review identity、Memory Candidate 写入门和 typed Preference/Profile/Review Memory、Training Plan/Progress、Memory-aware Context、terminal Assistant 与 lifecycle/export。terminal Assistant 仍只在可信 succeeded Task、publication 与 final Artifact 全部匹配时由内部 writer 追加,不能由 客户端直接伪造。
长期写入采用两层模型:Candidate 保存来源、权限、确认和审计;通过 accept 后,typed materializer 才在 同一 PostgreSQL 事务中写入 Preference、Player Profile 或 Review Memory,并用 expected-version、 supersede chain、advisory lock、partial unique 和 trigger 防止静默覆盖。只读查询入口为:
GET /memory/preferences
GET /memory/players/{relationship_id}/profile
GET /memory/players/{relationship_id}/reviews
GET /memory/players/{relationship_id}/training-plan
GET /memory/players/{relationship_id}/training-progress
GET /owner-data/export
POST /owner-data/deletions
POST /owner-data/deletions/{marker_id}/retry
6B-6 typed Memory 由 5531c81 / Actions 32387026797 公共闭环;6B-7 Plan/Progress 为
f6d8922/32397290175,6B-8 Context/terminal turns 为 aacc11a/32403187972。6B-9 最终
cbc7cbd/32408101770 的公共 pytest 为 1490 passed, 116 skipped, 1 warning, 110 subtests passed,
真实 PostgreSQL 为 164 passed, 1 warning;Linux package schema 1.6 执行 bounded export、
conversation-only delete 和 Preference/Plan 存续断言,外部 Riot/Provider 调用为 0。这仍不等于账号所有权
已验证、备份副本已擦除、公网鉴权/部署或真实模型质量已经完成。
Dockerfile 只包含运行所需的 Python 应用、migration、Skill、Prompt Program、RAG 文档和两个启动脚本,
使用非 root 用户运行;.env、本地 cache/run、测试、报告和实验资产不会进入镜像。Compose 的启动依赖是:
PostgreSQL healthy
→ migrate 一次性升级到 Alembic head
→ FastAPI ready
→ production Worker 或 no-I/O smoke
先运行不需要 Riot/模型 Key 的 Linux 控制面 smoke:
docker compose --project-name riftcoach-packaging-smoke `
--profile smoke up --build --detach --wait --wait-timeout 120 api
docker compose --project-name riftcoach-packaging-smoke `
--profile smoke run --rm --no-deps smoke
docker compose --project-name riftcoach-packaging-smoke `
--profile smoke down -v --remove-orphans这个 smoke 会通过 HTTP 创建一条合成 task,由独立诊断 Worker 真实 claim,并故意在不访问 Riot/Provider
的前提下写入安全的 failed/worker_execution_failed;随后以 Fake Account Resolver 完成 Player Link,
再用该 relationship 创建 Conversation、追加并复读第 1 条 user Message。它证明 package、migration、API、
PostgreSQL、claim、终态回写和 Conversation/Message 接线;不证明 Coach 报告质量或真实 Riot/Provider。
成功的 Application/Runtime/Harness/Artifact 链由离线产品纵向测试单独证明。固定的 Compose project name
会把 smoke 的网络和数据卷与普通本地运行隔离;脚本本身也只接受 Compose/本机 API 与 PostgreSQL host。
不要省略 project name,否则诊断 Worker 可能接触同一 Compose project 中已有的 queued task。
运行真实本地 Worker 前,先在 .env 填入 Riot 与当前 Zhipu 产品基线配置,再执行完整预检:
python -m scripts.run_review_worker --worker-id worker-1 --check
docker compose --profile runtime up --build--check 会验证数据库连接与 Alembic head、Data Dragon、本地 RAG、Skill/Prompt drift、Riot/Provider
配置与构造合同、Artifact 目录,然后在 claim 前退出;它不会额外付费调用模型,也不把“构造成功”冒充
Riot/Provider 凭据或领域质量已经在线验证。缺任一配置只返回 allowlisted 安全码,不会把 queued task
提前变成 running。
当前 Compose 使用显式 local fixed owner,仅供本机演示;它不是公网 Auth。不要把端口 8000 直接暴露到公网。
构建近期对局汇总:
python scripts\build_player_summary.py --riot-id "<GAME_NAME>#<TAG_LINE>" --count 10 --queue 420生成确定性报告和 Coach 草稿:
python scripts\generate_markdown_report.py --input data\cache\player_summary_<GAME_NAME>_<TAG_LINE>.json
python scripts\generate_llm_coach_report.py --summary data\cache\player_summary_<GAME_NAME>_<TAG_LINE>.json --rag-top-k 5执行评测与受限修订:
python scripts\evaluate_coach_report.py --summary data\cache\player_summary_<GAME_NAME>_<TAG_LINE>.json
python scripts\revise_coach_report.py --report reports\riftcoach_coach_report_<GAME_NAME>_<TAG_LINE>.md阶段 2 将原先需要人工串联的“检索、生成、评测、受限修订、再评测、发布”组织为确定性状态机。Harness 负责执行顺序、修订预算、Artifact 留存和发布门控;模型只能产生候选内容,不能自行决定报告是否发布。
先使用 --dry-run 验证本地闭环。该模式会执行真实的 Summary 校验、本地 RAG、状态机、文件型 Run Store、哈希登记和发布过程,但使用确定性 Fake 替代收费的模型生成、评测和修订调用:
python scripts\run_review_harness.py `
--summary data\cache\player_summary_<GAME_NAME>_<TAG_LINE>.json `
--deterministic-report reports\riftcoach_report_<GAME_NAME>_<TAG_LINE>.md `
--run-id local_dry_run `
--dry-run确认 dry-run 后,移除 --dry-run 执行真实 GLM 质量闭环:
python scripts\run_review_harness.py `
--summary data\cache\player_summary_<GAME_NAME>_<TAG_LINE>.json `
--deterministic-report reports\riftcoach_report_<GAME_NAME>_<TAG_LINE>.md `
--publish-score-threshold 85 `
--max-revisions 1每次运行默认写入 data/runs/<run_id>/,其中保存输入、RAG 证据、草稿、每轮评测、修订稿、最终报告和带 SHA-256 的 manifest.json。未通过质量门控的 Coach 草稿不会成为最终报告;失败时默认发布确定性报告并标记为 degraded,也可以通过 --no-deterministic-fallback 改为拒绝发布。
阶段 3 已为模型、RAG、Riot API 和 Data Dragon 建立统一的 Provider / Tool 契约与适配器。Harness 的生成、评测和修订不再访问具体 SDK 的 choices 结构,而是统一调用 llm.chat;检索统一调用 knowledge.search。Runtime 负责 Schema、有限重试、缓存、三态熔断、fallback 和运行指标,Harness 继续只负责任务级状态与发布门控。现有数据构建脚本暂时保持兼容,后续入口可以逐步改用已经注册的 Riot API 与 Data Dragon 工具。
不需要真实玩家数据或模型密钥的完整合成示例:
python scripts\run_review_harness.py `
--summary examples\fixtures\player_summary_demo.json `
--deterministic-report examples\fixtures\deterministic_report_demo.md `
--run-id harness_v1_demo `
--dry-run状态机、Artifact 目录、故障降级和表述边界详见 Harness v1 使用与原理。Provider、Tool Runtime、EchoMind 迁移边界和 MCP 区别详见 Provider 与 Tool Runtime 使用说明。
知识文档位于 data/rag_docs/。当前实现按 Markdown 标题切块,使用适配中文的词元与双字组合进行本地相关性检索,不依赖向量数据库或外部 Embedding 服务。
python scripts\query_rag.py "输局视野分和经济下降应该怎么复盘" --top-k 3阶段 4 RAG v1 已完成并进入维护:包括结构化 Markdown 元数据、父子块索引、BM25、可替换 Embedding 接口、确定性 hashing embedding 基线、RRF 混合召回、证据门控、来源多样性、版本/位置/有效期过滤、冲突处理和 chunk 级 Harness 引用。当前八题开发集结果为 Recall@K 1.0、MRR 1.0、nDCG@K 1.0、无答案误召回率 0.0;阶段 4M 另有独立保留集门禁。
这组问题也参与了初始阈值校准,因此结果只证明当前开发基线可复现,不是独立泛化证明;hashing embedding 也不等同于语义语言模型。独立保留集、abstain 与引用支持门禁详见 RAG 4M 独立评测门禁以及 RAG v1 现状审计与检索基线。
阶段 5A 建立了 Provider-neutral 的最小受限 Agent Loop:模型只能通过结构化
ToolCall 请求白名单工具,Runtime 返回 ToolObservation,循环受迭代次数、
工具次数和停止原因约束。它已用 Fake Provider 和真实 knowledge.search 工具验证,
生产 Zhipu Adapter 的最小结构化输出与 Tool Calling 协议已经真实准入;但 GLM-5.2
在一次 recent-form 领域切片中没有形成可交付给 Agent 的统一响应,因此真实领域能力
仍未准入,不能把低层协议通过写成 Coach Agent 已上线。
阶段 5B 建立 manifest.yaml + SKILL.md + Pydantic I/O Skill Contract;Catalog
现在包含 recent-form-review 与 single-match-review 两个真实用户 Skill。单局
合同复用 Player Summary v1.0,并要求目标 match ID 唯一;短局可以审查,Timeline
缺失保持显式未知。阶段 5C-1 至 5C-4 已完成 Router 请求与决策合同、严格 Catalog、
声明式确定性匹配,以及拒绝/排除否决/多候选歧义验收。5C-5 已建立双 Skill
development 与独立 holdout;5C-6 依据唯一设备语义 Bad Case 决定 V1 暂缓 LLM
Router fallback:
用户表达 + 可用 Skill 路由元数据
→ 检查每个候选的必需信号组与排除信号
→ selected / rejected / ambiguous
→ 稳定原因码与可解释证据
Router 只选择工作流,不执行 Skill、Tool、Harness 或模型。两个真实候选已有近期、 单局、混合范围歧义、裸 ID 拒绝和域外边界单测。当前开发集为 23/23;规则冻结后的 独立 holdout 为 11/12,唯一失败已原样保留且没有反向调规则。
5D 已把 Skill/Context、AgentLoop、ToolRuntime、本地 RAG 和唯一 ReviewHarness 组合为
受限执行链。5D-7 Batch A/B 建立分层领域评测和 Prompt/Context 语义身份;Batch C 又用
Scripted Provider 在零外部调用下执行 7 个 development 场景,真实验证工具、事实、
引用、用户/RAG 注入与发布门禁。其中一个“评测器漏判注入”场景被实际发布,再由分层
评测标为 unsafe_publication。这证明离线实验接线和故障识别,不证明任何真实模型的
领域质量或通用抗注入能力。原理与边界见
Agent Loop v1、Skill Contract v1
、单局 Skill Contract
、Router 拒绝与歧义验收
和 5D-7 Batch C 可执行评测设计。
Batch D 入口审计进一步确认:当前事实 Evaluator 没有看到用户原话、实际 RAG 证据和
信任标签,不能靠增加一个枚举或硬编码 canary 就声称解决 Prompt Injection。项目已用
ADR-0016
冻结兼容迁移:保留 coach_evaluation@1.0.0 历史复现,下一步离线实现 1.1.0 安全
评测合同与不可修订的发布阻断;独立 held-out 和有限真实 Provider 比较必须等新合同与
实验身份冻结后才能进入。该设计尚不是已完成的注入防护或真实模型准入。
python -m pytest -qPull Request 和推送到默认分支时,GitHub Actions 会在 Python 3.11 环境重复执行同一测试命令。 CI 还会检查项目治理状态连续性、阶段 4M 独立 RAG 保留集、真实 PostgreSQL 事务/并发,以及不读取 Riot/Provider Key 的 Linux Docker/Compose package smoke。
- 代码主体:独立 RiftCoach 仓库;
- 应用架构参考:EchoMind 的 Tool、Session、Memory、Monitor 与 Evaluation 思想;
- 高级运行时参考:AGI-Saber 的 Context Builder、父子块检索、DAG、取消、快照与恢复;
- 可靠执行参考:Sea-Mult-Agent 的 Artifact 契约、确定性控制面、预算、租约与事件历史;
- 三个参考项目均按能力迁移,不直接换皮、切换技术栈或整体合并。
完整阶段路线见 docs/roadmap.md,重要决策见 docs/adr。
reports/:本地生成报告和评测中间产物,默认不提交;examples/sample_coach_report.md:使用合成数据编写的公开展示样例;data/cache/:Riot API 本地缓存,默认不提交。
- 仓库不包含 Riot API Key、LLM API Key、
.env或本地缓存; - 公开示例使用合成标识和简化数据,不对应真实玩家;
- 用户自行查询的数据只保存在本地运行目录,除非用户主动选择其他存储方式;
- Riot、League of Legends 及相关商标归 Riot Games 所有。本项目与 Riot Games 没有隶属或背书关系;
- 安全问题请按照 SECURITY.md 说明私下报告。
本项目采用 MIT License 开源。