Files
iomgaa 9d4d52dac5 feat(core/evolution): protocols.py + types.py 基础层 — 18 个 dataclass + 3 个 Protocol
TRM4 诊断/进化/门控数据类型迁移至 TRM5 Clean Architecture 内核。
逐字段比对 TRM4 的 eprocess.py、diagnose.py、evolve.py 保真迁移。

types.py (18 个 dataclass):
- Gate: GateParams, GateVerdict (frozen, 原样迁移)
- 诊断: SpanMetrics, SkillStepAdherence, QuestionMetrics,
  ErrorAttribution, CaseSample, SkillCasePack, SystemCasePack,
  ToolCasePack, DiagnosisResult (全部 frozen=True)
- 进化: EvolutionRecord (mutable), RejectedEdit (frozen),
  EvolutionResult (frozen, 移除 skills_version/prompts_version)
- 新增: PairResult, QuadrantClassification (块验证纯决策输出)
- 新增: DiagnosePrompts, EvolvePrompts (模板束, frozen)

protocols.py (3 个只读 Protocol):
- SkillStore, PromptStore (同步文件读取)
- RunLog (异步日志查询, 隔离 SQL)

变更理由:
- QuestionMetrics 由 TRM4 mutable 改为 frozen (一次性构造)
- ErrorAttribution 由 TRM4 mutable 改为 frozen (构造时填入全部字段)
- EvolutionResult 移除版本管理字段 (app/ 职责)

涉及算法: #5(CE-Gate), #8(诊断瀑布), #9(进化引擎)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-07-07 09:34:04 -04:00

107 lines
2.4 KiB
Python

"""core/evolution/ 子包的只读 Protocol 定义。
三个 Protocol 均为只读——core/ 返回结果 dataclass,写入由 app/ 持久化。
SkillStore / PromptStore 为同步(文件读取量小且快),RunLog 为异步
(隔离 SQLite 查询,core/ 不写 SQL)。
"""
from __future__ import annotations
from typing import Any, Protocol, runtime_checkable
@runtime_checkable
class SkillStore(Protocol):
"""版本化技能读取端口。
实现方解析 manifest 指针,core/ 不感知版本号。
"""
def read_skill(self, filename: str) -> str:
"""读取指定 skill 文件的全文内容。
参数:
filename: skill 文件名,如 'temporal-reasoning.md'。
返回:
文件全文内容。
"""
...
def list_skill_files(self) -> list[str]:
"""列出当前版本所有 skill 文件名。
返回:
文件名列表。
"""
...
@runtime_checkable
class PromptStore(Protocol):
"""版本化提示词读取端口。
覆盖 system.md 和 tool extract/verify 文件。
"""
def read_prompt(self, filename: str) -> str:
"""读取指定 prompt 文件的全文内容。
参数:
filename: prompt 文件名,如 'system.md'。
返回:
文件全文内容。
"""
...
def list_prompt_files(self) -> list[str]:
"""列出当前版本所有 prompt 文件名。
返回:
文件名列表。
"""
...
@runtime_checkable
class RunLog(Protocol):
"""实验日志查询端口。
隔离 SQLite 实现细节,core/ 不写 SQL。
"""
async def get_predictions(
self,
run_id: str,
*,
question_ids: list[str] | None = None,
) -> list[dict[str, Any]]:
"""查询指定 run 的预测记录。
参数:
run_id: 运行标识。
question_ids: 可选的题目 ID 过滤列表。
返回:
预测记录字典列表。
"""
...
async def get_traces(
self,
run_id: str,
*,
question_ids: list[str] | None = None,
) -> list[dict[str, Any]]:
"""查询指定 run 的推理轨迹。
参数:
run_id: 运行标识。
question_ids: 可选的题目 ID 过滤列表。
返回:
轨迹记录字典列表。
"""
...