Skip to content

SW-07 pipeline 策略 profile 化:重试/定向重生成/自检开关/检索 top-k(ADR-0016) - #12

Merged
randypanding merged 2 commits into
mainfrom
sw/sw-07-profile-strategy
Aug 22, 2026
Merged

SW-07 pipeline 策略 profile 化:重试/定向重生成/自检开关/检索 top-k(ADR-0016)#12
randypanding merged 2 commits into
mainfrom
sw/sw-07-profile-strategy

Conversation

@randypanding

Copy link
Copy Markdown
Owner

这个 PR 改的是哪一层?(必选其一)

  • A 资产层spec/ profiles/ brands/ cases/export/)→ 必须打标签 asset-change 并附 ADR
  • B 生成物层src/ tests/)→ 无需 ADR
  • 文档 / CI

ADR:adr/0016-pipeline-strategy-profile-sections.md(status: proposed,含 profiles/_schema.py 变更,等确认)

工单

Closes # · 工单号:SW-07(上游依赖卡,Lab 仓 docs/WORK_ORDERS.md §上游依赖卡)

问题

各 phase 重试次数、定向重生成策略、self-check 子步骤开关、检索注入条数(rerank n)是 pipeline.py/p5_dialogue.py/cli.py 里的代码常量(attempts=2range(3)"lenient"k=3)。弱/强模型需要不同重试预算,改常量就要动代码层。

改动

段.键 缺省(=原常量) 消费点
pipeline.pass_attempts 2 _retry_pass(显式 attempts 参数仍优先)
pipeline.phase_attempts 3 run_pipeline 三个相位循环(p3/p4、p5、p6)
retrieval.top_k 3 cli._make_retrievalRetrievalService.k
revise.gate_mode lenient p5 self-check 采纳策略(nsc.revise.gate.MODES
revise.self_check true 既有键(T-31),本次入 schema 正名
  • profiles/_schema.py:新增 PipelineSettings/RetrievalSettings/ReviseSettings(extra=forbid,Literal 约束 gate_mode)
  • 两个在库 profile 显式写入缺省值(可发现性),行为零变化(已用 schema 验证 + 全量测试确认)
  • 偏差记录:revise.self_check 在 main 已是 profile 可读(卡面该项已完成,仅补 schema 正名);CLI --rerank 旗标在 main 即为死参数(声明未用),未清理(超出本卡范围);eval l1 的 RetrievalService 仍用构造缺省 k=3(与 profile 缺省一致)

验收命令(贴出你本地跑通的输出)

uv run pytest tests/test_profile_strategy.py -q   # 4 passed
uv run python -c "from profiles._schema import Profile; ..."  # 两个 profile 均过 schema 验证
uv run ruff format --check . && uv run ruff check .   # All checks passed
uv run pyright   # 0 errors
make spec-guard 六项   # 全 OK
uv run pytest -m "not llm" -n auto   # 525 passed, 1 failed(test_db_export_fresh,本机未提交 cases.db 现场所致,干净 worktree 通过)

检查表

  • 测试先红后绿(4 例先对旧实现全红:ImportError/_make_retrieval 不存在等)
  • 没有在 Python 里写业务规则
  • 未新增 check 规则(不适用)
  • 没有手改 prompts/
  • 手写行数仍在预算内(src 净增 ~25 行)
  • 未改 IR
  • 未改 rubric

影响生成结果吗?

  • 否(缺省值=原常量;只有 profile 显式改参才影响,届时由 profile 版本号进缓存键)

- pipeline.pass_attempts(缺省 2)→ _retry_pass;显式 attempts 参数优先
- pipeline.phase_attempts(缺省 3)→ p3/p4、p5、p6 三个相位循环
- retrieval.top_k(缺省 3)→ cli._make_retrieval → RetrievalService.k
- revise.gate_mode(缺省 lenient)→ p5 self-check 采纳策略;
  revise.self_check 开关既有(T-31),本次入 schema 正名
- profiles/_schema.py 新增 PipelineSettings/RetrievalSettings/ReviseSettings
  (extra=forbid);两个在库 profile 显式写入缺省值,行为零变化
- 测试:tests/test_profile_strategy.py(4 例,先红后绿)
Copilot AI lite review requested due to automatic review settings August 21, 2026 20:48
@randypanding randypanding added the asset-change 改动 spec/profiles/brands,需 ADR + 人工 approve label Aug 21, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

新增的 profile 解析路径在多处对配置值直接 int(...) / 透传 mode,配置写错会抛未捕获异常绕过现有 PassFailure 重试/诊断链路,且 ADR 日期存在未来时间。

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

该 PR 将 SW-07 中“管线策略”从代码常量下沉到 profile(pipeline/retrieval/revise 三段),以便按不同模型/场景在资产层调参,同时保持缺省值与历史常量一致,实现“零行为变化”的可配置化。

Changes:

  • profiles/_schema.py 增加 PipelineSettings / RetrievalSettings / ReviseSettings 并挂到 Profile 上,约束并提供缺省值。
  • pipeline.py 的 pass/phase 重试次数、p5_dialogue.py 的 gate_mode、cli.py 的检索 top-k 改为从 profile 读取(缺省回退到原常量)。
  • 新增 tests/test_profile_strategy.py 覆盖上述配置读取与缺省回退语义,并为两个在库 profile 显式写入缺省段落。
File summaries
File Description
tests/test_profile_strategy.py 新增针对 pass_attempts/phase_attempts/gate_mode/top_k 的回归测试与缺省回退验证
src/nsc/passes/pipeline.py pass/phase 重试次数从 profile 读取,并用于 p3/p4、p5、p6 三个相位循环
src/nsc/passes/p5_dialogue.py self-check 修订采纳策略 gate_mode 从 profile 读取并用于 revisionGate
src/nsc/cli.py 将 RetrievalService 的 top-k 从 profile 读取并封装为 _make_retrieval
profiles/short_video_v1.yaml 显式写入 pipeline/retrieval/revise 三段缺省值以提升可发现性
profiles/short_drama_v1.yaml 同上:显式写入三段缺省值
profiles/_schema.py 增加三段 settings schema(extra=forbid、Literal gate_mode 等)并挂到 Profile
adr/0016-pipeline-strategy-profile-sections.md 新增 ADR-0016,说明 profile 化决策与迁移/验证
Review details

Suppressed comments (1)

src/nsc/passes/pipeline.py:91

  • _phase_attempts 同样对 profile 值做 int(...);解析失败会抛 TypeError/ValueError 并绕过 phase 重试的 PassFailure 捕获,可能导致状态未回滚且直接退出。建议把解析错误转成 PassFailure 并带上清晰诊断。
def _phase_attempts(ctx: PassContext) -> int:
    """SW-07:p3/p4、p5、p6 相位级定向重生成次数(profile.pipeline.phase_attempts,缺省 3)。"""
    return max(1, int(ctx.profile.get("pipeline", {}).get("phase_attempts", 3)))
  • Files reviewed: 8/8 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/nsc/passes/pipeline.py Outdated
Comment on lines +84 to +86
def _pass_attempts(ctx: PassContext) -> int:
"""SW-07:单 Pass 输出波动重试次数(profile.pipeline.pass_attempts,缺省 2)。"""
return max(1, int(ctx.profile.get("pipeline", {}).get("pass_attempts", 2)))

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修正(64d17ba):新增 _attempts_of(ctx, key, default) 统一读次数旋钮,pass_attempts/phase_attempts 两处共用;解析失败(TypeError/ValueError)转 PassFailure,诊断句指明 profile 键与当前值,走既有失败/快照链路而非裸崩溃。回归测试 test_bad_profile_values_fail_with_clear_errors 覆盖两个键的坏值路径。

Comment on lines 277 to 279
findings2 = _scene_findings(ctx, scene, beats, lines2, characters)
if decide(_counts(findings), _counts(findings2), "lenient"):
if decide(_counts(findings), _counts(findings2), _gate_mode(ctx)):
return lines2, out2

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修正(64d17ba):_gate_mode 先对 nsc.revise.gate.MODES 校验,非法值直接 PassFailure(None, 诊断句)——不再把 decide() 的 ValueError 留给无人捕获的编排层。schema 的 Literal 约束仍作为第一道防线(校验过的 profile 到不了这里),这道是裸 dict profile 的兜底。

Comment thread src/nsc/cli.py Outdated
Comment on lines +42 to +49
def _make_retrieval(ctx: Any) -> Any:
"""SW-07:检索服务,注入条数 top_k 读 profile.retrieval(缺省 3=原常量)。"""
from nsc.retrieval import RetrievalService

return RetrievalService(
db_path="cases/cases.db",
k=max(1, int(ctx.profile.get("retrieval", {}).get("top_k", 3))),
)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

已修正(64d17ba):_make_retrievalretrieval.top_k 的解析失败转 typer.BadParameter(消息含键名与当前值),CLI 层用户可读,不再是裸堆栈。同测试覆盖。

Copilot review(PR #12):
- _pass_attempts/_phase_attempts 对非整数/None 抛 TypeError/ValueError 击穿编排
  → 统一 _attempts_of:解析失败转 PassFailure(诊断句指明 profile 键与当前值)
- p5 gate_mode 非法时 revise.gate.decide 的 ValueError 无人捕获 → _gate_mode
  先校验 MODES,非法即 PassFailure
- cli._make_retrieval 对坏 top_k 裸堆栈 → typer.BadParameter 用户可读报错
- 回归:test_bad_profile_values_fail_with_clear_errors(4 断言齐备)
@randypanding
randypanding merged commit f215c44 into main Aug 22, 2026
10 checks passed
@randypanding
randypanding deleted the sw/sw-07-profile-strategy branch August 22, 2026 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

asset-change 改动 spec/profiles/brands,需 ADR + 人工 approve

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants