docs(compare): refine compare design docs and template scope

This commit is contained in:
linshen
2026-03-21 20:43:28 +08:00
parent 4b3e18394f
commit f0c7476792
13 changed files with 2756 additions and 6 deletions

2
.gitignore vendored
View File

@@ -196,5 +196,7 @@ CLAUDE.md
.kiro
.agents/
.codex/
.codex-run/
.codex-tmp/
# BMAD (local only)
.ace-tool/

View File

@@ -0,0 +1,281 @@
# 薄 SPO UI 与停止规则架构设计
## 1. 目标
本设计解决三个架构问题:
1. `SPO` 如何在不复制 compare intelligence 的前提下支持多轮循环
2. `SPO` 的停止条件如何尽量依赖 compare evaluation 的通用输出
3. `SPO` 的运行结果如何以最小 UI 复杂度融入现有测试区
核心目标是让 `SPO` 保持为:
- 配置层
- 编排层
- 展示层
而不是新的 judge 层。
## 1.1 当前实现状态
截至 `2026-03-20`,当前代码里与本文直接相关、已经落地的能力包括:
- `compareMode`
- `snapshotRoles`
- `compareJudgements`
- `compareStopSignals`
- `compareInsights`
- compare 角色配置弹窗与手动角色修正的稳定可用版本
- compare 手工角色在槽位语义签名变化时自动失效
- 结果面板中的 compare 元信息展示
- 结果面板中的“智能重写”按钮
- 基于压缩评估结果复用 iterate 链路的最小通用重写能力
当前仍未落地:
- `SPO` 按钮
- `SPO` 配置弹窗
- `SPO` 运行态卡片
- `SPO` 多轮状态机
- `SPO` 停止规则执行
因此本文当前主要是“目标态架构文档”,不应误读为 `SPO` 运行链路已经上线。
## 2. 分层关系
```mermaid
flowchart TD
A["测试执行层\nrun variants / collect snapshots"] --> B["评估层\nGeneric Compare / Structured Compare"]
B --> C["通用重写层\nRewrite From Evaluation"]
C --> D["SPO 编排层\npreset / loop / stop / accept"]
D --> E["SPO 展示层\nbutton / modal / run card / result card / drawer"]
```
关键原则:
- compare evaluation 负责判断
- rewrite 负责改写
- SPO 负责循环与展示
## 3. 不增加 SPO 专属 LLM judge
本设计明确不建议增加一个额外的 `SPO judge` LLM 调用来决定:
- 是否继续下一轮
- 是否已经接近参考模型
- 是否改进空间很小
原因:
- 会让判断逻辑重新回到 `SPO`
- 会产生第二套难以维护的 judge 协议
- 会使 `compare evaluation``SPO` 之间再次深度耦合
推荐方式是:
- compare evaluation 输出结构化 stop signals
- `SPO` 只消费这些 signals
- 如果一轮中需要“改写后是否接受”的判断,也继续复用 compare evaluation而不是引入第二套 judge
## 4. compare evaluation 需要补充的通用输出
在保持现有对外主结果结构不变的前提下compare evaluation 内部或 metadata 层建议补充:
```ts
interface CompareStopSignals {
targetVsBaseline: 'improved' | 'flat' | 'regressed'
targetVsReferenceGap: 'none' | 'minor' | 'major'
improvementHeadroom: 'none' | 'low' | 'medium' | 'high'
overfitRisk: 'low' | 'medium' | 'high'
stopRecommendation: 'continue' | 'stop' | 'review'
stopReasons: string[]
}
```
这些字段不是 `SPO` 私有的,它们是 structured compare 的通用机器可读信号。
## 5. SPO 编排状态机
建议 `SPO` 的主状态机如下:
```mermaid
stateDiagram-v2
[*] --> idle
idle --> configuring
configuring --> running
running --> roundTesting
roundTesting --> roundComparing
roundComparing --> preRewriteStoppingCheck
preRewriteStoppingCheck --> finished: stop
preRewriteStoppingCheck --> roundRewriting: continue
roundRewriting --> roundRetesting
roundRetesting --> roundRetestComparing
roundRetestComparing --> roundAcceptedCheck
roundAcceptedCheck --> running: next round
roundAcceptedCheck --> finished: stop
running --> stopped: user stop
running --> failed: error
```
### 状态解释
- `configuring`
- 用户配置目标模型、参考模型、轮次和停止策略
- `roundTesting`
- 运行本轮 4 槽测试
- `roundComparing`
- 对当前轮开始时的工作区执行 structured compare
- `preRewriteStoppingCheck`
- 根据改写前 compare 的 stop signals 决定是否无需继续 rewrite
- `roundRewriting`
- 基于 compare evaluation 结果重写 `workspace`
- `roundRetesting`
- 对新 `workspace` 再次执行测试
- `roundRetestComparing`
- 对复测结果再次执行 structured compare
- `roundAcceptedCheck`
- 根据复测后的 structured compare 结果判断本轮是否接受为新的最佳轮
## 6. 停止规则架构
## 6.1 硬停止
必须直接结束:
- 达到最大轮次
- 测试失败
- compare 失败
- rewrite 失败
- stop signals 明确给出 `regressed`
- stop signals 明确给出高风险过拟合
## 6.2 软停止
满足以下情况可提前结束:
- `improvementHeadroom = none | low`
- `targetVsReferenceGap = none | minor`
- 连续多轮分数提升小于最小阈值
## 6.3 结果接受策略
每轮结束后,不应简单地“最后一轮覆盖前一轮”。
建议采用:
- 维护一个 `accepted best round`
- 新一轮只有在未回归且整体更优时才覆盖最佳轮
- 若新一轮回归,则保留上一最佳轮并停止或交由策略决定
### 6.4 accepted round 的判定来源
为保持 `SPO` 足够薄,`acceptedRound` 的判定不应由 `SPO` 自己发明文本规则,而应直接依赖“复测后的 structured compare”。
推荐做法:
1. 改写前 compare 只负责:
- 发现问题
- 生成 rewrite 依据
- 给出 pre-rewrite stop 判断
2. 改写并复测后,再运行一次 structured compare。
3. `roundAcceptedCheck` 仅消费这次 post-retest compare 的结果,至少检查:
- `targetVsBaseline` 不是 `regressed`
- `overfitRisk` 不是 `high`
- compare 未失败
4. 只有在满足最低安全条件后,当前轮才有资格根据 gap 收敛、summary、score 等证据覆盖上一 accepted round。
## 7. UI 架构
## 7.1 主界面最小改动
主界面只新增:
- `SPO` 按钮
- `SPO` 运行/结果卡
- 测试槽位角色 badge
不新增页面,不打断现有测试区结构。
## 7.2 详情抽屉复用现有心智模型
`SPO` 详情应采用与评估面板类似的右侧抽屉方式:
- 概览
- 轮次历史
- 单轮详情
- 停止原因
这样避免引入新的复杂导航结构。
## 7.3 最终结果展示原则
结果展示必须区分:
- 最后执行轮
- 最终采用轮
否则多轮过程中一旦后续轮回归,用户很难理解系统最终保留了什么。
## 8. 建议的数据模型
```ts
interface SpoConfig {
targetModelKey: string
referenceModelKey: string
maxRounds: number
stopMode: 'round-only' | 'smart' | 'custom'
rewriteModelKey?: string
}
interface SpoRuntimeState {
status: 'idle' | 'running' | 'completed' | 'stopped' | 'failed'
currentRound: number
acceptedRound: number | null
bestScore: number | null
stopReason?: string
rounds: SpoRoundState[]
}
interface SpoRoundState {
round: number
compareScore: number | null
accepted: boolean
stopSignals?: CompareStopSignals
acceptanceSignals?: CompareStopSignals
summary?: string
}
```
其中:
- `SpoConfig` 属于 `SPO`
- `CompareStopSignals` 属于 compare evaluation
## 9. 推荐实现顺序
### 阶段 1
- compare evaluation 增加 stop signals
- 结果面板逐步支持机器可读信号
### 阶段 2
- `SPO` 配置弹窗
- `SPO` 运行卡 / 结果卡
- `SPO` 详情抽屉
### 阶段 3
- 多轮 loop
- smart stop
- best round accept policy
## 10. 结论
最合理的架构是:
- compare evaluation 输出通用 stop signals
- rewrite 继续作为通用能力
- `SPO` 保持为极薄的 loop controller + UI wrapper
这样可以最大限度复用现有能力,同时把“为什么停、停在哪一轮、最终保留哪一轮”清晰呈现给用户。

View File

@@ -0,0 +1,406 @@
# Structured Compare 与评估结果驱动重写架构设计
## 1. 目标
本设计解决两个架构问题:
1. compare evaluation 如何在不依赖 `SPO` 的前提下支持更强的结构化判断
2. “根据评估结果自动重写 prompt”如何作为通用能力服务于所有评估面板
最终目标是形成三层架构:
- 评估协议层
- 评估增强能力层
- SPO 编排层
## 1.1 当前实现状态
本文同时描述“已经落地的当前实现”和“目标态架构”。
截至 `2026-03-20`,当前已落地:
- `CompareAnalysisHints.mode`
- `CompareAnalysisHints.snapshotRoles`
- 前端在可形成 judge plan 时自动推断 structured compare 角色
- `Structured Compare = pairwise judge + synthesis`
- pairwise judge 并发执行
- compare 结果中的:
- `metadata.compareMode`
- `metadata.snapshotRoles`
- `metadata.compareJudgements`
- `metadata.compareStopSignals`
- `metadata.compareInsights`
- `pairHighlights`
- `evidenceHighlights`
- `learnableSignals`
- `overfitWarnings`
- `progressSummary / referenceGapSummary / promptChangeSummary / stabilitySummary`
- `conflictSignals`
- 结果面板对 compare 元信息、pairwise judgements、conflict checks 与 stop signals 的展示
- `Rewrite From Evaluation` 的增强通用能力:
- 结果面板新增“智能重写”按钮
- 复用现有 iterate 模板与版本链路
- 输入只消费压缩后的 `summary / improvements / patchPlan / compareInsights / compareStopSignals / conflictSignals`
- 会进一步做去重、分层和 compare 结果压缩,形成更稳定的 rewrite brief
- 当前先落在文本工作区
- compare 配置的稳定可用交互:
- 测试区可打开 compare 角色配置弹窗
- 可查看自动推断角色
- 可手动修正角色并持久化到 session
- 多个 `workspace` 槽位时必须显式选择 `target`
- 手工指定 `target` 后自动补全其余角色
- 自动推断会收敛为单一 `baseline / reference / referenceBaseline`,其余多余候选降级为 `auxiliary`
- 当槽位语义签名变化时,旧的手工角色会自动失效
- 当前槽位语义签名已覆盖 `promptRef kind/version``modelKey``non-workspace` 槽位的 prompt 文本签名
- `workspace` 槽位的 prompt 文本变化不会直接清空手工角色,而是进入“待复核”状态
- compare 真正执行前若存在待复核角色,会打开弹窗要求重新确认
- 可查看手动 / 自动 / 已失效旧配置的来源状态
- 可预览当前会进入 `structured` 还是 `generic`
- 可预览当前可执行的核心 pairwise judge
- 会拦截多个 `target / baseline / reference / referenceBaseline` 这类会导致 structured compare 歧义的配置
- compare 结果元数据在 UI 侧已抽成共享消费模块,统一供结果面板、评估状态与智能重写消费
当前未落地:
- 更强的 `Rewrite From Evaluation` 协议与独立模板
## 2. 分层架构
```mermaid
flowchart TD
A["测试执行层\nrun variants / collect snapshots"] --> B["评估协议层\nsummary / improvements / patchPlan / score"]
B --> C["评估增强能力层\nGeneric Compare\nStructured Compare\nRewrite From Evaluation"]
C --> D["SPO 编排层\nauto preset\none round loop\nmulti-round loop"]
```
关键原则:
- `SPO` 不能直接发明新的 compare 协议
- `Structured Compare` 属于 compare evaluation 的增强模式
- `Rewrite From Evaluation` 属于通用重写能力,不应只服务于自动优化
## 3. 当前协议基础
现有 compare evaluation 输出协议已经稳定:
- `summary`
- `improvements`
- `patchPlan`
- `score`
因此本期不建议改动最终外部返回结构,而是优先增强 compare 的内部生成方式。
## 4. Compare 的两种模式
## 4.1 Generic Compare
输入特征:
- 任意数量 `snapshots`
- 无明确 target 语义
- 无结构化角色配置
当前执行方式:
- 复用当前 compare evaluation 逻辑
适用:
- 普通 compare
- 任意自由组合测试
## 4.2 Structured Compare
输入特征:
- 至少有一个 `target`
- 其他快照被自动推断或手动标记角色
执行方式:
1. 角色校验
2. 生成 pairwise judge plan
3. 执行 blind pairwise judge
4. 执行 synthesis
5. 输出现有 compare 协议
适用:
- target-centered compare
- auto iterate judge
补充说明:
- 当前代码已落地的是“真实 structured compare 内核”
- 当前 structured compare 实现是:
- 角色 hints 注入
- judge plan 生成
- 多个 blind pairwise judge 并发执行
- 独立 synthesis
- 输出 `compareMode / snapshotRoles / compareJudgements / compareStopSignals / compareInsights`
- 当前还未落地的是:
- 更细粒度的角色推断启发式与更丰富的 judge plan 组合
## 5. 结构化角色模型
建议在 compare 输入 hints 中扩展出一组中性角色,而不是硬编码 `reference` 这类业务词:
- `target`
- `baseline`
- `reference`
- `referenceBaseline`
- `replica`
- `auxiliary`
### 为什么使用中性角色
- compare evaluation 可复用
- SPO 只是其中一个角色绑定来源
- 用户手工 compare 也可以进入 structured mode
## 6. Compare 输入扩展建议
当前 `CompareAnalysisHints` 已经扩展为:
```ts
interface StructuredCompareHints {
mode?: 'generic' | 'structured'
snapshotRoles?: Record<
string,
'target' | 'baseline' | 'reference' | 'referenceBaseline' | 'replica' | 'auxiliary'
>
}
```
当前实现策略:
- 未提供 `mode``snapshotRoles` 时,走 `generic`
- 当前前端只会在可形成 judge plan 时自动推断并启用 `structured`
- 当前最小可用 judge plan 要求至少存在 `target`,并且至少有 `baseline / reference / replica` 之一
- 若只有一个 `workspace` 槽位,可自动视为 `target`
- 若有多个 `workspace` 槽位,必须由用户显式指定 `target`
-`target` 确定后,自动推断只会收敛出单一 `baseline / reference / referenceBaseline`
- 其余未进入核心 judge 的候选会被降级为 `auxiliary`
目标态建议仍然是:
- 只有角色信息足够稳定时,才启用更强的 structured compare
- 把角色选择 / 修正能力上移到 compare 配置层
这样可以避免 compare evaluation 直接依赖 `SPO` 配置对象。
## 7. Pairwise Judge Plan 生成
Structured Compare 内部应根据角色生成 judge plan而不是固定写死 A/B/C/D。
### 核心 judge
1. `target` vs `baseline`
2. `target` vs `reference`
3. `reference` vs `referenceBaseline`
### 可选 judge
4. `target` vs `replica`
### 非核心角色
- `auxiliary` 只进入 synthesis不进入核心 blind judge
- `reference` vs `replica` 目前仍属于潜在扩展项,当前实现尚未纳入 judge plan
## 8. Rewrite From Evaluation
## 8.1 设计要求
新增通用能力:
- 输入:评估结果 + 当前工作区 prompt + 可选最小证据锚点
- 输出:新的工作区 prompt 草稿
这个能力应可服务于:
- prompt-only
- result
- compare
- focus evaluation
## 8.2 能力边界
该能力应负责:
- 总结整份评估结果
- 过滤样例特化建议
- 保留原 prompt 硬约束
- 生成新的 prompt 文本
该能力不负责:
- 自动运行 compare
- 自动复测
- 自动多轮循环
这些仍属于 `SPO` 编排层。
## 8.3 Stop Signals From Compare
为了支持 `SPO` 等自动化上层,而不把停止判断重新塞回 `SPO`,建议 compare evaluation 在内部增强中补充一组机器可读的 stop signals。
建议形式:
```ts
interface CompareStopSignals {
targetVsBaseline: 'improved' | 'flat' | 'regressed'
targetVsReferenceGap: 'none' | 'minor' | 'major'
improvementHeadroom: 'none' | 'low' | 'medium' | 'high'
overfitRisk: 'low' | 'medium' | 'high'
stopRecommendation: 'continue' | 'stop' | 'review'
stopReasons: string[]
}
```
这组结构的作用是:
-`SPO` 可以直接消费 compare judgement 与 stop signals
- 避免新增 `SPO` 专属 judge LLM 调用
- 让 compare evaluation 的判断结果可复用于更多自动化功能
同时当前实现还补充了一组 `compareInsights.conflictSignals`
```ts
type CompareConflictSignal =
| 'improvementNotSupportedOnReference'
| 'improvementUnstableAcrossReplicas'
| 'regressionOutweighsCosmeticGains'
| 'sampleOverfitRiskVisible'
```
这组结构的作用是:
- 把 pairwise judge 派生出的冲突检查结果 machine-readable 化
- 避免 UI、rewrite、未来 SPO 去解析 synthesis 自然语言
- 让“继续改”“先复核”“警惕样例过拟合”这些动作建议有更稳定的底座
## 9. UI / 交互架构
## 9.1 Compare 配置弹窗
职责:
- 选择 target
- 展示自动推断角色
- 允许少量人工修正
- 预览当前会进入 `structured` 还是 `generic`
- 预览当前可执行的核心 pairwise judge
- 阻止会导致 structured compare 歧义的单例角色冲突
输出:
- compare 角色配置
该配置应存放在测试区 session 中,而不是 SPO 专属状态中。
## 9.2 结果面板动作
结果面板建议统一支持三类动作:
- `立即替换`
- `迭代优化`
- `智能重写`
其中:
- `立即替换` 对应 `patchPlan`
- `迭代优化` 对应单条 `improvement`
- `智能重写` 对应整份 `evaluation result`
## 10. SPO 的职责边界
SPO 只应负责:
- 自动预置测试槽位
- 自动生成 compare 角色配置
- 串联:
- test
- compare
- rewrite
- retest
- post-retest compare
- 管理轮次、停止条件、接受条件
- 管理运行态 UI
SPO 不应负责:
- 定义 compare 返回结构
- 定义 compare 的 blind judge 协议
- 定义 rewrite from evaluation 的通用协议
- 定义 stop signals 的 judge 逻辑
## 11. 推荐实现顺序
### 阶段 1
- compare hints 的结构化扩展
- `metadata.compareStopSignals`
- compare 结果消费侧透传
状态:已完成
### 阶段 2
- structured compare 内核
- `metadata.compareJudgements`
- stop signals / judge results 的基础展示
状态:已完成
- structured compare 已切换为 pairwise judge + synthesis
- pairwise judge 已改为并发执行
- judge 结果已透传到 compare metadata
- 结果面板基础展示已完成
### 阶段 3
- compare 配置弹窗
- role inference
- `Rewrite From Evaluation`
状态:部分完成
- role inference 已有自动推断
- compare 配置弹窗与人工角色修正已进入稳定可用版本
- 多个 `workspace` 槽位时必须显式选择 `target` 已落地
- 手工指定 `target` 后自动补全其余角色已落地
- 自动收敛为单一 `baseline / reference / referenceBaseline` 已落地,剩余候选会降级为 `auxiliary`
-`promptRef kind/version + modelKey` 变化时,手工角色失效保护已落地
- `non-workspace` 槽位的 prompt 文本变化级别失效保护已落地
- `workspace` 槽位的 prompt 变化复核机制已落地:
- 不再静默清空手工角色
- compare 执行前会强制重新确认
- compare 配置中的 structured / generic 预览、pair 预览与单例角色冲突拦截已落地
- compare insights 中的 `conflictSignals` 与结果面板中的 `conflict checks` 已落地
- 通用 `Rewrite From Evaluation` 已有最小实现:
- 由结果面板直接触发
- 复用 iterate 流程自动形成新版本
- 当前已不再是简单平铺字段,而是会把评估结果压缩成更结构化的 rewrite brief
- 当前已显式纳入 `compareStopSignals + compareInsights + conflictSignals`
- 但仍未独立成单独模板协议层
### 阶段 4
- `SPO` 按钮 / 配置弹窗 / 运行卡 / 结果卡 / 抽屉
### 阶段 5
- `SPO` 预置 structured compare
- 自动一轮 / 多轮
- stop rule / accept rule
## 12. 结论
架构上最合理的方向是:
- compare evaluation 内部增强为 `Generic + Structured`
- rewrite 能力提升为“评估结果驱动的通用智能重写”
- SPO 只在最上层做 orchestration
这样可以最大化复用 compare 与 rewrite 能力,同时将自动优化逻辑控制在最薄的一层。

View File

@@ -0,0 +1,379 @@
# 测试区自动迭代一轮
> 说明:本文记录的是最初的一轮自动迭代方案。
> 最新设计已经进一步拆分为:
> - `docs/architecture/structured-compare-and-evaluation-rewrite.md`
> - `docs/architecture/spo-thin-loop-ui-and-stop-rules.md`
>
> 因此,本文更适合作为“问题背景与早期方案说明”阅读,而不是当前唯一的实施规范。
## 1. 背景
我们已经在 `basic-system` 中拥有较完整的多槽位测试能力:
- 测试区支持 `2 / 3 / 4`
- 每列可独立选择 `version + model`
- 可统一执行 `runAllVariants`
- 对比评估链路支持基于多 `snapshot` 的证据分析
- system 模式天然具备独立的测试输入区,适合作为“固定执行场景”来验证系统提示词
因此,本期不再设计一个新的 SPO 实验台,而是把“朝目标自动迭代”的能力嵌入现有测试区。
这也更符合 prompt-optimizer 的定位:
- 优化必须建立在真实执行结果之上
- 测试、评估、改写应形成闭环
- 用户应继续围绕当前工作区进行操作,而不是切换到另一个体系
## 2. 目标
在测试区中新增一个“自动迭代”配置入口。用户只需选择:
- `目标模型`
- `参考模型`
系统就自动完成:
1. 构造 4 槽位测试预设
2. 执行一次上一版本对照测试
3. 提取目标锚点与差异证据
4. 改写当前 `workspace` 提示词
5. 再执行一次测试
6. 向用户展示本轮结果与风险提示
## 3. 设计原则
- 复用优先:尽量复用现有测试区、多槽位、对比评估与工作区写回能力
- 单轮优先V1 只做一轮,先验证闭环是否可靠
- 目标明确:始终围绕 `目标模型 / workspace` 做优化
- 参考充分:同时利用参考模型与上一版本,避免单点偏置
- 护栏先行:禁止只追求当前样例更优而破坏提示词通用性
- 输入隔离:测试输入只用于验证系统提示词行为,不应沉淀为系统规则
## 4. 范围与非目标
### 4.1 本期范围
- `basic-system`
- 测试区顶部新增自动迭代入口
- 自动生成 4 槽位预设
- 一次自动迭代闭环
- 将改写结果写回 `workspace` 草稿
- 不自动保存为新历史版本
- 优化对象限定为系统提示词
### 4.2 非目标
- 多轮无人值守自动优化
- 新建 SPO 独立页面
- 用户手工编排任意复杂实验图
- 脱离真实执行结果、仅靠目标描述进行优化
## 5. 为什么系统“知道目标是什么”
本设计不引入额外的“目标说明”表单,而是将目标识别收敛为一个结构化锚点提取过程。
目标由以下信息联合确定:
1. `目标槽位`
- 用户显式选择 `目标模型`
- 系统将 `目标模型 / workspace` 视为唯一待优化对象
2. `当前提示词中的显式约束`
- 系统角色设定
- 任务边界
- 输出格式
- 禁止事项
- 质量要求
3. `上一版本参考`
- `目标模型 / 上一版本`
- `参考模型 / 上一版本`
- 用来识别已有能力与不可退化项
4. `参考模型差异`
- `参考模型 / workspace` 相对 `目标模型 / workspace` 的优势表现
- 用来识别当前提示词在目标模型上的表达盲点
因此,“目标”不是一个额外配置文本,而是:
`目标模型 + 当前系统提示词 + 上一版本参考 + 跨模型差异证据`
这比抽象目标更贴近真实使用场景,也更适合结合我们现有测试功能。
## 6. UX 交互
### 6.1 入口位置
在测试区顶部操作栏中,新增一个与“运行全部”并列的按钮:
- `自动迭代`
该按钮位于当前测试区上下文中,避免用户切换心智模型。
### 6.2 配置弹窗
点击后弹出配置弹窗V1 保持最小可用,仅包含:
- `目标模型`
- `参考模型`
弹窗辅助说明:
- 本轮会自动生成 4 槽位预设
- 本轮只改写 `workspace`
- 改写后会自动复测
- 不会自动保存版本
弹窗主按钮建议文案:
- `生成预设并执行一轮`
### 6.3 结果反馈
一轮结束后,用户在原测试区看到新的 4 槽位结果。
同时提供一个轻量的“本轮总结”区域,至少包含:
- 学到了什么
- 改了什么
- 为什么这样改
- 潜在风险
- 是否建议保存为新版本
V1 不要求新建复杂历史面板;保持轻量即可。
## 7. 四槽位预设规则
自动迭代使用固定的 4 槽位语义:
| 槽位 | 模型 | 版本 | 角色 |
| --- | --- | --- | --- |
| A | 目标模型 | `workspace` | 主优化对象 |
| B | 目标模型 | `previous version` | 目标模型上一版本参考 |
| C | 参考模型 | `workspace` | 参考对照 |
| D | 参考模型 | `previous version` | 参考模型上一版本参考 |
### 7.1 上一版本定义
“上一版本previous version”指当前工作区在本轮自动改写之前的最近一次稳定版本
- 如果工作区基于当前历史链最新版本继续编辑,则 `previous = 当前链最新版本`
- 如果当前没有历史链,则回退为 `v0`
这里刻意不用 `v-last`,因为它很容易让人误解成“最新版本”;也不用“基线版本”,因为“基线”更像不变参照。本设计真正想表达的是“当前轮次之前的那个版本”。
如果后续要加入一个不随自动迭代轮次变化的固定对照,再单独引入“固定基线”概念。
### 7.2 为什么是这 4 个槽位
这 4 个槽位同时提供三条证据线:
1. `A vs B`
- 当前工作区在目标模型上,相比上一版本是否真的更好
2. `A vs C`
- 同一提示词在目标模型与参考模型上的差异,目标模型还缺什么
3. `C vs D`
- 参考模型在当前工作区上是否也体现出增益,帮助判断改进是否具有结构性
## 8. 一轮自动迭代编排
### 8.1 主流程
```mermaid
flowchart TD
A["用户点击 自动迭代"] --> B["选择目标模型 / 参考模型"]
B --> C["生成 4 槽位预设"]
C --> D["执行首轮 4 槽位测试"]
D --> E["提取目标锚点与差异证据"]
E --> F["生成新的 workspace 提示词草稿"]
F --> G["写回 workspace不保存版本"]
G --> H["执行第二轮 4 槽位测试"]
H --> I["展示本轮总结与风险提示"]
```
### 8.2 详细步骤
1. 校验前置条件
- 当前有可执行的测试输入
- 已配置目标模型与参考模型
- 工作区提示词非空
- 当前模式为 `basic-system`
2. 应用 4 槽位预设
- 设置列数为 4
- 覆盖对应槽位的 `version + model`
3. 执行首轮测试
- 复用 `runAllVariants`
- 产出 4 份执行快照
4. 构造自动迭代上下文包
- 见第 9 节
5. 调用自动改写链路
- 生成新的 `workspace` 提示词草稿
6. 写回工作区
- 更新当前 `workspace`
- 不生成新版本记录
7. 执行第二轮测试
- 再次运行 4 个槽位
8. 展示结果
- 输出本轮学习点、改动摘要、回归风险、是否建议采纳
## 9. 自动迭代的模型上下文构造
这是本功能设计的核心。
我们不直接把“4 个输出文本”粗暴拼接给模型,而是构造一个面向自动改写的上下文包。
### 9.1 输入结构
建议组织为以下几组信息:
1. 任务元信息
- mode: `basic-system`
- round: `1`
- targetModelKey
- referenceModelKey
- targetVariantId: `A`
2. 提示词上下文
- currentWorkspaceSystemPrompt
- previousVersionSystemPrompt
- originalPrompt (`v0`,可选)
3. 测试用例上下文
- 当前测试输入
- 用例标签
- 设置摘要
- 标注其角色为“执行场景”,而不是“可上升为系统规则的规范来源”
4. 执行快照
- A/B/C/D 各自的:
- version
- model
- prompt
- output
- reasoning
5. 差异分析输入
- A 相比 B 的提升与退化
- A 相比 C 的缺口
- C 相比 D 的参考侧新增能力
6. 约束与护栏
- 只改写 `workspace`
- 保留现有硬约束
- 不接受样例特化规则
- 证据不足时允许返回 no-op
### 9.2 目标锚点提取
在真正改写前,系统应先基于上述上下文提取一组“目标锚点”:
- 硬锚点
- 直接来自提示词文本中的强约束
- 稳定锚点
- 在上一版本中已经存在且不应退化的能力
- 机会锚点
- 参考模型在同一提示词下能做到,但目标模型当前没有稳定做到的点
- 负锚点
- 来自当前测试输入、可能诱导过拟合的具体词面规则
只有在锚点提取完成后,才进入提示词改写步骤。
### 9.3 输出要求
自动改写链路至少要返回:
- `nextWorkspacePrompt`
- `learnedAnchors`
- `appliedChanges`
- `rejectedOverfitIdeas`
- `riskNotes`
这样后续 UI 才能向用户解释“为什么改”,而不是只给出一个新提示词。
## 10. 防过拟合与回归保护
### 10.1 成功判定
不能只看“当前测试样例是否更好”,至少要同时满足:
1. `目标模型 / workspace` 相比 `目标模型 / 上一版本` 有明确改进,或至少无关键能力退化
2. `参考模型 / workspace` 不应相对 `参考模型 / 上一版本` 明显退化
3. 改动理由能抽象为结构性规则,而不是当前输入样例的字面补丁
`basic-system` 来说,这里的“结构性规则”通常表现为:
- 角色边界更清晰
- 优先级更明确
- 失败处理更稳定
- 输出约束更一致
- 冲突指令的裁决顺序更清楚
### 10.2 拒绝改写的情况
以下情况应允许系统返回“本轮不建议改写”:
- 四槽位证据差异不显著
- 目标与参考差异主要来自采样波动而不是结构问题
- 改进建议高度依赖当前测试输入中的具体值
- 改写会破坏提示词中已有的强约束
## 11. 与现有能力的衔接
### 11.1 复用现有多槽位测试区
无需重做测试区主体结构,直接使用:
- `testColumnCount`
- `testVariants`
- `runAllVariants`
- per-slot `version + model` 选择
### 11.2 复用 compare-evaluation 证据结构
现有 `compareEvaluation.ts` 已经采用:
- `testCases`
- `snapshots`
- `compareHints`
组织执行证据。
本功能可以直接复用这一思路,避免重新发明多快照比较协议。
### 11.3 复用现有工作区改写能力
自动迭代的最终落点仍然是更新 `workspace` 草稿。
也就是说:
- 它不是新增一套独立提示词存储
- 它不是单独的实验输出
- 它最终仍然服务于当前工作区编辑与后续人工保存
## 12. 建议的实现触点
- `packages/ui/src/components/basic-mode/BasicSystemWorkspace.vue`
- 自动迭代按钮
- 配置弹窗
- 本轮总结 UI
- `packages/ui/src/stores/session/useBasicSystemSession.ts`
- 自动迭代配置持久化
- 可能的最近一次执行摘要
- `packages/ui/src/composables/prompt/compareEvaluation.ts`
- 复用 snapshot 组织模式
- 新增编排文件(建议)
- `packages/ui/src/composables/prompt/autoIterateOneRound.ts`
- `packages/ui/src/composables/prompt/autoIteratePreset.ts`
## 13. V1 验收标准
- 测试区可直接打开自动迭代配置弹窗
- 用户只配置 `目标模型``参考模型`
- 系统自动生成 4 槽位预设并执行
- 自动迭代只修改系统提示词的 `workspace`
- 改写后自动复测
- UI 能展示本轮学习点、改动点、风险点
- 系统允许在证据不足时选择“不改”
- 系统不会把测试输入里的具体值直接固化进系统提示词
## 14. 后续演进
V1 跑通后,可逐步扩展:
- 支持 3 槽位简化模式
- 支持多轮自动迭代
- 引入更强的“目标锚点提取”显式展示
- 支持把一轮总结沉淀为版本注释或评审记录

View File

@@ -8,8 +8,9 @@
1. [current-spec.md](./current-spec.md)
2. [manual-acceptance.md](./manual-acceptance.md)
3. [real-api-samples/review-summary.md](./real-api-samples/review-summary.md)
4. `real-api-samples/*/rendered-messages.md`
3. [manual-test-playbook.md](./manual-test-playbook.md)
4. [real-api-samples/review-summary.md](./real-api-samples/review-summary.md)
5. `real-api-samples/*/rendered-messages.md`
## 当前目录结构
@@ -19,6 +20,9 @@
- `manual-acceptance.md`
当前手工测试入口。
如果你要自己在浏览器里点一遍,就看这份。
- `manual-test-playbook.md`
当前最适合直接照着操作的一份手测步骤文档。
如果你要逐步验证 compare 阶段功能,优先看这份。
- `real-api-samples/`
真实模型请求样例。
这是判断“现在到底发了什么给模型”的最高优先级证据。

View File

@@ -2,6 +2,7 @@
> 这是当前目录唯一推荐的总览文档。
> 如果它与 `history/` 里的旧文档冲突,应优先以本文和 `real-api-samples/` 为准。
> 本文已按当前代码实现同步到 `2026-03-20`。
## 1. 一句话先讲清
@@ -58,6 +59,64 @@
- 不再默认额外注入当前工作区全文。
- 普通 compare 和跨模型 compare 都要求先解释“已观察到的关键差异”,不能先发散到泛建议。
补充说明:
- 当前代码里compare 已经区分出两种运行模式:
- `generic`
- `structured`
- 当前 `structured` 的触发条件是:
- compare payload 可构建
- 且前端能推断出一组“可执行 judge plan”的角色
- 至少要有 `target`,并至少存在 `baseline / reference / replica` 之一
- 当前 `structured` 已落地能力:
- `CompareAnalysisHints.mode`
- `CompareAnalysisHints.snapshotRoles`
- `target / baseline / reference / referenceBaseline / replica / auxiliary` 角色语义
- 并发 `pairwise judge`
- 独立 `synthesis`
- compare 角色配置弹窗
- 自动角色推断结果展示
- 自动角色推断支持“多候选收敛”:
- 在确定 `target` 后,自动只保留一个 `baseline`
- 自动只保留一个 `reference`
- 自动只保留一个 `referenceBaseline`
- 其余候选统一降级为 `auxiliary`
- 手动角色修正与 session 持久化
- 手工指定 `target` 后自动补全其余角色
- 当存在多个 `workspace` 槽位时,不再自动猜 `target`
- 必须由用户显式确认 `target` 后,才允许进入 structured compare
- 当槽位语义签名变化时,旧的手工角色会自动失效并回退到自动推断
- 当前槽位语义签名已覆盖:
- `promptRef kind/version`
- `modelKey`
- `non-workspace` 槽位的 prompt 文本签名
- `workspace` 槽位的 prompt 文本变化不会直接清空手工角色
- 但如果用户曾确认过该角色,后续 compare 会把它标记为“待复核”,并要求用户在弹窗中重新确认后才能继续执行
- compare 配置弹窗中的手动 / 自动 / 已失效来源可视化
- compare 配置弹窗中的 structured / generic 模式预览与可执行 pair 预览
- 会导致 structured compare 歧义的单例角色冲突拦截
- 测试区顶部与槽位头部会显示 compare 角色复核提示
- compare 结果中的 `metadata.compareMode`
- compare 结果中的 `metadata.snapshotRoles`
- compare 结果中的 `metadata.compareJudgements`
- compare 结果中的 `metadata.compareStopSignals`
- compare 结果中的 `metadata.compareInsights`
- compare insights 中按 pairType 聚合的焦点结论:
- `progressSummary`
- `referenceGapSummary`
- `promptChangeSummary`
- `stabilitySummary`
- compare insights 中新增 machine-readable `conflictSignals`
- 结果面板中的 compare 决策摘要:
- 基于 `compareStopSignals + compareInsights` 生成更可执行的“下一步建议”
- 结果面板中的元信息、`pairwise judgement``compare insights``conflict checks` 展示
- 结果面板中的“智能重写”按钮
- 复用 iterate 链路的增强通用重写能力
- 重写输入会对评估结果做去重、分层与 compare 焦点压缩
- 重写输入已显式纳入 `conflictSignals`
- 当前仍未落地的,主要是上层复用能力:
- 更独立的通用智能重写协议 / 模板
## 4. 当前输入边界
### 4.1 左侧分析
@@ -111,7 +170,36 @@
- 输出
- 推理(如果有)
- 模型 / 版本信息
- 仅当当前工作区存在时才允许发起新的 compare 评估
当前已实现行为:
- compare 仍然要求存在当前工作区 prompt 作为可编辑 target
- 如果角色推断后无法形成可执行 judge plan则回退到 `generic compare`
- 如果能推断出可执行 judge plan则进入 `structured compare`
- compare 请求侧的 `compareHints` 是当前角色语义与模式的事实来源
- 当前自动角色策略是:
- 若只有一个 `workspace` 槽位,可自动把它视作 `target`
- 若有多个 `workspace` 槽位,必须显式选择 `target`
-`target` 确定后,系统会自动收敛出单一 `baseline / reference / referenceBaseline`
- 其余未进入核心 judge 的槽位会降级为 `auxiliary`
- `structured compare` 当前内部执行流程是:
- 生成 judge plan
- 并发执行多次 pairwise judge
- 基于 judge 结果做 synthesis
- compare 返回后会透传并展示:
- `compareMode`
- `snapshotRoles`
- `compareJudgements`
- `compareStopSignals`
- `compareInsights`
- 其中 `compareInsights` 已不仅是平铺列表,还包含面向业务消费的聚合焦点结论与 `conflictSignals`
计划中的下一阶段演进:
- 更细粒度的角色推断与歧义消解策略
- 当前已覆盖“多 workspace 必须显式 target”与“多候选自动收敛到单 baseline/reference/referenceBaseline”
- 目前已覆盖 `promptRef kind/version + modelKey`,以及 `non-workspace` 槽位的 prompt 文本变化触发的手工角色失效
- 基于整份 compare 结果的更强通用智能重写
当前不应再默认出现:
@@ -162,12 +250,26 @@
### 6.3 对比评估模板
- 普通 compare
- `generic compare`
- 必须先点名已观察到的关键差异。
- 第一条 improvement 必须先处理这条差异。
- 跨模型 compare
- “同提示词跨模型 compare
- 必须先解释同提示词跨模型差异暴露的误解点。
- 第一条 improvement 必须先处理这条误解点。
- `structured compare`
- 先执行多次 pairwise judge每条 judge 只看一组 pair 的测试输入与两个快照
- judge 产物会沉淀到 `metadata.compareJudgements`
- synthesis 阶段只消费角色绑定和 judge 结果,不重新展开全部原始快照
- synthesis prompt 会注入 pair 专项指导与确定性 hints显式提醒优先级、gap、stability、overfit 等信号
- 最终仍输出统一 compare 协议,并在证据足够时输出 `compareStopSignals`
- 若 synthesis 缺失 stop signals或给出比 pairwise judge 更乐观的 stop 判断core 会以 pairwise 派生信号做保守合并
补充说明:
- 当前已不是“只有单一 compare 模板收紧”的阶段。
- 当前已经落地的是“pairwise judge + synthesis + machine-readable metadata”的 structured compare。
- `compareStopSignals` 已不是单纯信任 synthesis 文本,而是有 pairwise 证据兜底与保守收敛逻辑。
- 当前还没有落地的是“更强通用智能重写协议与更细粒度角色失效策略”。
## 7. 当前已完成项
@@ -178,6 +280,42 @@
- 普通 compare 与跨模型 compare 的模板都已经收紧。
- 右侧评估入口已改为 strict workspace-only不再回退到原始提示词。
- 已有评估结果在输入失效后保留为可查看态,但重跑入口会被禁用。
- compare request / response 已支持:
- `compareMode`
- `snapshotRoles`
- `compareJudgements`
- `compareStopSignals`
- `compareInsights`
- compare insights 当前已可直接提供:
- `pairHighlights`
- `evidenceHighlights`
- `learnableSignals`
- `overfitWarnings`
- `progressSummary / referenceGapSummary / promptChangeSummary / stabilitySummary`
- `conflictSignals`
- 文本模式下已落地 structured compare 自动推断:
- `basic-user`
- `basic-system`
- `pro-variable`
- `pro-multi`
- compare 角色配置已进入稳定可用版本:
- 测试区可打开配置弹窗
- 支持查看自动推断角色
- 支持手动指定角色并持久化到 session
- 当存在多个 `workspace` 槽位时,必须显式指定 `target`
- 当用户只手工指定 `target` 时,可自动补全其余角色
- 自动推断会把多余候选收敛为单一 `baseline / reference / referenceBaseline`,其余降级为 `auxiliary`
- 支持展示当前角色来源:手动 / 自动 / 已失效旧配置
- `workspace` 手工角色在 prompt 变更后会进入“待复核”状态,而不是被静默清空
- compare 真正执行前如果存在待复核角色,会强制重新确认
- 支持预览当前会进入 `structured` 还是 `generic`
- 支持预览当前可执行的核心 pairwise judge
- 会拦截多个 `target / baseline / reference / referenceBaseline` 这类会导致 structured compare 歧义的配置
- 结果面板已可展示 compare 元信息、pairwise judgements、compare insights、conflict checks 与 stop signals。
- 结果面板已支持把 `compareStopSignals + compareInsights` 压成面向动作的 compare 决策摘要。
- 结果面板已支持基于整份评估结果的一键“智能重写”,并直接复用 iterate 版本链路。
- 智能重写当前会显式消费 `compareStopSignals + compareInsights + conflictSignals`
- compare 结果元数据在 UI 侧已统一抽成共享消费模块,避免 `useEvaluation / EvaluationPanel / rewrite` 多处漂移。
## 8. 当前剩余问题
@@ -189,6 +327,15 @@
这不是代码问题,而是资料管理问题。当前已经通过 `history/` 隔离,但历史文档本身内容没有全部重写。
### 8.3 compare 主线已闭环,剩余属于增强项
当前 compare 阶段的主线语义、角色配置、pairwise judge、结果消费与“基于评估重写”入口都已经打通。
后续如果继续演进,主要属于增强项而不是 compare 阶段未完成:
- 更稳定的多候选角色判定策略
- 基于整份评估结果的更强通用智能重写
## 9. 当前推荐阅读顺序
1. 本文

View File

@@ -0,0 +1,332 @@
# Compare 阶段手动测试操作手册
> 这份文档是“按步骤点击”的操作版。
> 目标不是覆盖所有历史验收点,而是帮助你手动验证这次 compare 阶段改造的核心功能是否真的可用。
## 1. 适用范围
本手册优先验证:
- `basic-system`
- compare evaluation
- structured compare 结果展示
- compare role config
- 基于评估结果的智能改写
- stale 旧结果可查看但不可重跑
如果这条主链通过,说明本次 compare 阶段的主干能力已经基本可接受。
## 2. 启动方式
在项目根目录执行:
```powershell
pnpm dev:fresh
```
启动后打开本地 Web 页面。
建议:
- 用无痕窗口或新浏览器 profile
- 如果你想同时看模型请求,可打开 DevTools 的 Network
## 3. 建议测试数据
### 3.1 system prompt
左侧原始提示词建议填这个:
```text
你是一个客服助手。回答用户问题时:
1. 先判断问题类型。
2. 给出简洁且有帮助的回复。
3. 不要编造物流状态。
4. 不要输出与问题无关的建议。
```
### 3.2 测试输入
右侧测试内容建议填这个:
```text
用户说:订单一周还没发货,我很着急。
```
这个案例的好处是:
- 容易看出回复结构是否更清晰
- 容易看出边界是否滑移
- 容易比较“是否过度编造物流状态”
## 4. 手测主流程
---
## 4.1 基础链路:先优化,再测试
目标:
- 验证工作区能正常产生新版本
- 验证测试区两列都能跑出结果
步骤:
1. 进入 `basic-system` 模式。
2. 左侧填入上面的 system prompt。
3. 点击优化,等待生成工作区版本。
4. 确认版本区已经显示 `v1`
5. 右侧测试区把列数切到 `2`
6. 在测试输入框里填入上面的测试输入。
7. 点击 `Run All`
通过标准:
- 原始列和工作区列都有非空输出
- 页面没有报错
- 当前工作区版本仍可见
如果失败,优先记录:
- 是否某一列没有输出
- 是否点击 `Run All` 后没有任何反应
- 是否出现模型请求错误或工作区版本异常丢失
---
## 4.2 Compare 评估:生成分数与详情
目标:
- 验证 compare evaluation 真正能跑通
- 验证右侧顶部 compare 分数能出现
步骤:
1. 完成 `4.1` 的流程。
2. 在测试区顶部点击 compare 的评估按钮。
3. 等待 compare 分数徽章出现。
4. 点击 compare 分数徽章,打开详情抽屉。
通过标准:
- compare 分数徽章出现
- 能打开详情抽屉
- 抽屉内不是空白,也不是旧式简单总结
重点观察:
- 是否能看到 compare 的整体 summary
- 是否能继续展开看更细的信息
---
## 4.3 Structured Compare检查结构化产物
目标:
- 验证当前 compare 结果不是旧的 generic compare 退化输出
- 验证 pairwise judge + synthesis 的产物已经进入 UI
步骤:
1. 完成 `4.2`
2. 在 compare 详情抽屉里,依次检查这些区块是否出现:
- `Compare Decision`
- `Compare Metadata`
- `Compare Insights`
- `Pairwise Judgements`
通过标准:
- 以上 4 个区块都可见
- `Compare Metadata` 里能看到 `Mode`
- `Mode` 显示为 `Structured``结构化`
进一步检查:
- `Snapshot Roles` 里是否出现角色信息,例如:
- `Target`
- `Baseline`
- `Reference`
- 有时还有 `Reference Baseline` / `Replica`
- `Stop Signals` 是否至少出现以下字段中的一部分:
- `targetVsBaseline`
- `targetVsReferenceGap`
- `improvementHeadroom`
- `overfitRisk`
- `stopRecommendation`
- `Pairwise Judgements` 是否是按 pair 展示,而不是一段散文式总结
如果这里通过,可以基本认为:
- structured compare 已经生效
- pairwise judge 结果已被保留下来
- synthesis 结果和派生 metadata 已经进入 UI
---
## 4.4 智能改写:从 compare 结果生成新版本
目标:
- 验证“根据评估结果智能改写工作区提示词”这条链路可用
步骤:
1. 保持 compare 详情抽屉打开。
2. 点击 `智能改写` / `Rewrite From Evaluation` 按钮。
3. 回到工作区区域,观察版本标签。
通过标准:
- 会生成一个新版本
- 版本号从 `v1` 变成 `v2`,或继续递增
- 新版本内容非空
- 新版本不是原文完全不变
建议再补做一步:
4. 再次点击测试区 `Run All`,观察新版本输出是否也能正常生成。
补充通过标准:
- 新版本能参与测试
- 不会因为智能改写后的版本而导致测试区失效
---
## 4.5 角色配置弹窗:多 workspace 场景下选择 target
目标:
- 验证当 compare 中 workspace 槽位不止一个时,不会盲猜 target
- 验证手动角色配置能真正影响 structured compare
建议场景:
- 至少 3 个槽位
- 至少 2 个槽位是 workspace prompt
- 模型可相同也可不同
步骤:
1. 把测试区配置成一个“workspace 不唯一”的场景。
2. 点击 compare 评估。
3. 如果弹出 compare role config 弹窗,继续以下步骤:
- 为一个槽位指定 `target`
- 为另一个槽位指定 `baseline`
- 如果有教师模型槽位,指定 `reference`
- 如果有教师模型旧版本槽位,指定 `referenceBaseline`
4. 点击确认。
5. 再次完成 compare。
6. 打开 compare 详情。
通过标准:
- 弹窗能正常出现
- 可以手动分配角色
- 重新 compare 后,`Snapshot Roles` 和你刚刚选的角色一致
- `Mode` 仍然是 `Structured`
如果没有弹窗,也可以手动点测试区里的 compare 配置按钮进入同样的弹窗。
---
## 4.6 Stale 结果:旧结果保留,但不可误重跑
目标:
- 验证 compare / result 在输入条件变化后仍可查看历史结果
- 但不会继续拿旧条件偷偷重跑
步骤:
1. 先完成一轮单结果评估和 compare 评估。
2. 保留已有输出不动。
3. 把右侧测试输入清空,或者改成完全不同的内容。
4. 观察已有分数徽章。
5. 点击旧分数徽章,查看详情。
6. 再尝试寻找 `re-evaluate` / 重新评估入口。
通过标准:
- 旧分数徽章仍然存在
- 徽章应表现为 stale 状态
- 旧详情仍能打开
- 重新评估入口应被禁用,不能继续发请求
这里最重要的是:
- “可查看” 和 “可重跑” 必须被区分开
---
## 4.7 空白差异不应导致 structured compare 退化
目标:
- 验证这次修复的 prompt 归一化逻辑
- 避免只因为换行/空格不同,就让 structured compare 退回 generic
建议做法:
1. 准备两个几乎相同的 prompt。
2. 只改空白格式,不改语义:
- 一个多空行
- 一个多缩进
- 或一个单行,一个多行
3. 把它们放进可 compare 的槽位场景里。
4. 再次执行 compare。
通过标准:
- `Mode` 仍然是 `Structured`
- 角色仍能被合理识别
- 不会因为纯空白差异直接退回 generic
---
## 5. 推荐你实际记录的验收结果
建议你按下面格式记一份最小结果:
```text
[通过/失败] 4.1 基础链路
[通过/失败] 4.2 Compare 评估
[通过/失败] 4.3 Structured Compare 展示
[通过/失败] 4.4 智能改写生成新版本
[通过/失败] 4.5 角色配置弹窗
[通过/失败] 4.6 Stale 旧结果
[通过/失败] 4.7 空白差异不退化
```
如果失败,建议只补这三项:
```text
模块:
步骤:
实际现象:
预期现象:
```
例如:
```text
模块basic-system / compare
步骤:点击 compare 评估后打开详情
实际现象:没有 Compare Insights只有普通 summary
预期现象:应出现 structured compare 的 metadata / insights / pairwise judgements
```
## 6. 最低通过标准
如果你时间有限,至少验证这 5 条:
1. `basic-system` 两列测试可正常运行。
2. compare 评估后详情里能看到 `Structured`
3. 详情里有 `Compare Decision / Metadata / Insights / Pairwise Judgements`
4. 点击智能改写后能生成新版本。
5. 修改测试输入后,旧结果仍可看,但不能直接重跑。
只要这 5 条都过,我会认为这次 compare 阶段已经具备提交价值。

View File

@@ -0,0 +1,62 @@
# 工作区:测试区自动迭代一轮
> 本目录记录“复用现有多槽位测试区,为目标模型引入一轮自动提示词迭代”的设计与过程。
> 本期不新建独立的 SPO/实验页面,而是在现有测试区内增加自动迭代入口与四槽位预设。
>
> 说明:目录名保留了最初的“一轮自动迭代”提法,但目录内容已经扩展为三部分:
> 1. 一轮自动迭代的早期方案
> 2. compare evaluation 的通用增强
> 3. 薄 `SPO` 的上层封装设计
## 快速入口
- 任务计划:`./task_plan.md`
- 发现与决策:`./findings.md`
- 进展日志:`./progress.md`
- 结构化对比评估与通用智能重写:`docs/architecture/structured-compare-and-evaluation-rewrite.md`
- 薄 SPOUI、交互与停止规则`docs/architecture/spo-thin-loop-ui-and-stop-rules.md`
- 实施拆分Compare Stop Signals 与薄 SPO`./implementation-split-compare-stop-signals-and-spo.md`
## 相关文档
- 架构设计:`docs/architecture/test-area-auto-iterate-one-round.md`
- 架构补充:`docs/architecture/structured-compare-and-evaluation-rewrite.md`
- SPO 架构补充:`docs/architecture/spo-thin-loop-ui-and-stop-rules.md`
- 对比评估现状:`docs/workspace/compare-evaluation-analysis/current-spec.md`
- 现有测试区版本/模型选择:`docs/workspace/test-area-version-model-selection/`
## 当前范围
- `basic-system` 优先
- 自动迭代仅做一轮
- 仅改写 `workspace` 提示词,不自动保存历史版本
- 通过 `目标模型 + 参考模型` 自动生成 4 槽位测试预设
- 四槽位中的历史参考统一称为“上一版本previous version不再使用 `v-last`
- 下一阶段的 `SPO` 设计以“薄编排层”为目标,重点是多轮循环、停止条件和结果展示,而不是新增 judge 能力
- compare evaluation 的增强方向是:
- `Generic Compare`
- `Structured Compare`
- 通用 `rewrite from evaluation`
- 通用 machine-readable `stop signals`
## 当前实现状态
- 当前仓库中,这一主题仍处于“文档设计完成、代码待按新方案重新落地”的状态。
- 此前曾尝试过一版自动迭代 demo但因为与最新的“compare 通用增强 + 薄 SPO”边界不一致已经回滚。
- 因此,本目录中的“已完成”主要指设计收口,不代表当前主干代码里已经存在可用实现。
- 当前正式设计稿统一放在 `docs/architecture/`,本目录只保留任务计划、过程记录和拆分说明,避免同主题双份文档继续漂移。
## 阅读建议
- 如果你要看“当前已实现行为”,优先阅读:
- `docs/workspace/compare-evaluation-analysis/current-spec.md`
- 如果你要看“下一阶段 compare 应如何升级”,优先阅读:
- `docs/architecture/structured-compare-and-evaluation-rewrite.md`
- 如果你要看“下一阶段 SPO 应如何保持很薄”,优先阅读:
- `docs/architecture/spo-thin-loop-ui-and-stop-rules.md`
- 如果你要看“推荐落地顺序”,优先阅读:
- `./implementation-split-compare-stop-signals-and-spo.md`
## 归档规则
- 任务完成后,将本目录归档到:`docs/archives/<id>-test-area-auto-iterate-one-round/`

View File

@@ -0,0 +1,282 @@
# 发现与决策
## 需求摘要
- 目标不是做一个新的通用 SPO 平台,而是把“朝目标自动迭代”的能力融入现有提示词优化工作流。
- 用户希望充分复用当前测试区的多槽位能力,用真实执行结果驱动自动改写,而不是只基于静态目标描述做推断。
- V1 只做一轮:
- 建立上一版本对照
- 分析差异
- 改写 `workspace`
- 重新测试
- 自动目标不是抽象的“我要更好”,而是非常具体的:
- 目标槽位:`目标模型 / workspace`
- 参考槽位:`目标模型 / 上一版本``参考模型 / workspace``参考模型 / 上一版本`
- 首期范围切到 `basic-system`,优化对象是系统提示词。
- 测试输入仅用于暴露系统提示词在执行时的行为差异,不应反向固化为提示词里的样例特化规则。
## 代码/结构发现
- 当前 `basic-system` 已经不是单纯 A/B。
- `packages/ui/src/stores/session/useBasicSystemSession.ts`
- 已有 `TestVariantId = 'a' | 'b' | 'c' | 'd'`
- 已有 `TestColumnCount = 2 | 3 | 4`
- 已有 `testVariants: TestVariantConfig[]`
- 当前测试区已具备多槽位主控能力。
- `packages/ui/src/components/basic-mode/BasicSystemWorkspace.vue`
- 已有 `testColumnCountModel`
- 已有 `activeVariantIds`
- 已有 per-slot 的版本/模型选择
- 已有 `runAllVariants`
- 已有 system 模式必填的 `testContent`
- 当前对比评估的数据结构天然适合承载多槽位证据。
- `packages/ui/src/composables/prompt/compareEvaluation.ts`
-`testCases + snapshots + compareHints` 组织执行证据
- 支持同一测试输入下的多输出对比
- 旧的 `testVariantState.ts` 仍保留 A/B 语义,但它已经不是 `basic-system` 当前测试区的主编排层。
## 目标锚点如何获得
本期不要求用户额外填写“目标说明/硬约束”。目标锚点由以下 4 类信息共同生成:
1. `目标槽位`
- 用户在弹窗中指定 `目标模型`
- 系统默认把 `目标模型 / workspace` 作为唯一优化对象
2. `提示词内显式约束`
- 从当前 `workspace` 提示词中抽取角色、任务边界、输出格式、禁忌项、工具使用规则等
3. `上一版本参考`
- 来自 `目标模型 / 上一版本``参考模型 / 上一版本`
- 用来判断哪些能力是上一版已经稳定拥有的,不能在本轮迭代里丢失
4. `跨模型差异证据`
- 来自 `参考模型 / workspace``目标模型 / workspace` 的真实输出差异
- 用来识别“同一提示词下,参考模型已经体现而目标模型尚未稳定体现”的能力
换句话说,本设计里的“意图识别”不是独立的意图分类器,而是一次面向当前测试证据的目标锚点提取。
这里的“上一版本”是产品术语,不是新的版本类型:
- UI 内部仍然会落成实际的 `v0``vN`
- 它强调的是“当前工作区在本轮迭代之前的那个版本”
- 如果后续要加入不随轮次变化的参照物,应单独命名为“固定基线”,不要与“上一版本”混用
## 模型上下文构造(核心结论)
自动迭代不应只把“4 份输出”直接拼给模型,而应构造成一个结构化上下文包:
- 任务元信息
- 当前轮次、目标模型、参考模型、目标槽位
- 提示词上下文
- 当前 `workspace` 提示词
- 上一版本提示词
- 可选 `v0` 作为原始参考
- 测试输入上下文
- 当前测试区输入内容
- 相关设置摘要
- 需要显式标注“测试输入仅作为执行场景,不是可直接抽取进系统提示词的规则来源”
- 执行证据
- 4 个槽位的 prompt/version/model/output/reasoning 快照
- 差异总结
- `目标/workspace` 相比 `目标/上一版本` 的提升/退化
- `目标/workspace` 相比 `参考/workspace` 的欠缺项
- `参考/workspace` 相比 `参考/上一版本` 的参考侧增益项
- 约束与护栏
- 只允许修改 `workspace`
- 不允许引入明显依赖当前样例输入的硬编码规则
- 若证据不足,应返回“不建议改写”
这比“给模型一个目标再让它自由改”更接近我们项目的定位,因为它建立在真实执行证据上。
## 技术决策
| 决策 | 理由 |
| --- | --- |
| 自动迭代入口放在测试区顶部 | 保持“先测试、再判断、再改写”的心智模型,不引入新页面 |
| V1 配置只暴露 `目标模型``参考模型` | 降低上手成本,避免把功能做成复杂实验编排器 |
| 自动生成 4 槽位预设 | 复用现有多槽位能力,同时天然具备目标对比、参考对比、版本回归三条证据线 |
| 使用“上一版本”替代 `v-last` 作为产品术语 | 这里要表达的是“当前轮次之前的那个版本”,它会随着自动迭代推进而变化,不适合叫基线 |
| 一轮内只改写 `workspace`,不自动保存版本 | 降低错误传播风险,保留人工确认环节 |
| 成功标准必须包含“回归未恶化”而不只是“当前样例更好” | 防止测试样例驱动的过拟合 |
## 防过拟合规则V1
- `目标模型 / workspace` 必须相对 `目标模型 / 上一版本` 有明确改进,至少不能出现关键能力退化。
- `参考模型 / workspace` 不应相对 `参考模型 / 上一版本` 出现明显退化。
- 改写理由必须能够抽象成“结构性改进”,例如:
- 指令顺序更明确
- 约束边界更清晰
- 输出结构更稳定
- 异常场景覆盖更完整
- 若建议依赖当前测试输入中的具体名词、变量值、字面样例,系统应将其归为疑似过拟合信号并拒绝采纳。
-`basic-system` 而言,自动改写只能调整系统层规则,不得把测试输入中的具体实体、字段值、案例文案上升为长期系统规则。
## 可能的实现触点
- `packages/ui/src/components/basic-mode/BasicSystemWorkspace.vue`
- 新增自动迭代按钮、配置弹窗、回合执行入口
- `packages/ui/src/stores/session/useBasicSystemSession.ts`
- 视需要持久化自动迭代配置与最近一次预设
- `packages/ui/src/composables/prompt/compareEvaluation.ts`
- 复用 `snapshot` 证据组织方式,避免重新定义执行证据格式
- 新增独立编排层(建议)
-`packages/ui/src/composables/prompt/autoIterateOneRound.ts`
- 负责预设生成、证据整形、模型调用、回写工作区与复测
## 资源
- 多槽位 session`packages/ui/src/stores/session/useBasicSystemSession.ts`
- 多槽位测试区:`packages/ui/src/components/basic-mode/BasicSystemWorkspace.vue`
- 对比评估证据构造:`packages/ui/src/composables/prompt/compareEvaluation.ts`
- 旧 A/B 状态工具:`packages/ui/src/composables/prompt/testVariantState.ts`
- 架构设计:`docs/architecture/test-area-auto-iterate-one-round.md`
## Structured Compare 与 SPO 边界补充
### 为什么不能把三组关键判断直接做成 SPO 私有逻辑
前面收敛出的三组关键判断:
- `target/workspace vs target/previous`
- `target/workspace vs reference/workspace`
- `reference/workspace vs reference/previous`
确实很适合自动优化,但它们依赖的并不是 `SPO` 这个功能名本身,而是更底层的“结构化 compare 角色”。
也就是说,它们依赖的是:
- 谁是当前要优化的 `target`
- 谁是它的 `baseline`
- 谁是可学习对象 `reference`
- 谁是 `referenceBaseline`
而不是依赖:
- 是否打开了自动迭代弹窗
- 是否走了 `targetModel + referenceModel` 的专用入口
因此,这部分能力更适合下沉为 compare evaluation 的通用增强,而不是让 `SPO` 自己维护一套平行 judge 逻辑。
### Generic Compare 与 Structured Compare 的分界
为了控制变更范围,同时不牺牲 compare 的表达力,比较合理的做法是把 compare evaluation 分为两种模式:
1. `Generic Compare`
- 适用于任意自由组合测试
- 不要求存在 `workspace`
- 不要求指定 `target`
- 延续当前更通用的 compare 行为
2. `Structured Compare`
- 至少存在一个 `workspace`
- 围绕一个明确的 `target` 做分析
- 可以在内部做更强的 pairwise blind judge 与 synthesis
这样可以避免把“围绕工作区做定向优化”的能力硬塞给所有 compare同时也避免 `SPO` 自己长出一套不可复用的 compare 内核。
### target 的识别与配置方式
为了让 compare evaluation 可以服务于更多场景,`target` 不应只来源于 `SPO` 配置。
比较稳妥的规则是:
1. 如果没有任何 `workspace` 槽位
- 不进入 `Structured Compare`
- 回退到 `Generic Compare`
2. 如果只有一个 `workspace` 槽位
- 自动将其视为 `target`
3. 如果有多个 `workspace` 槽位
- 在首次 compare 时弹窗让用户选择 `target`
- 后续将结果持久化,并在 UI 上显示角色标记
一旦 `target` 明确,其余槽位就可以根据“是否同模型 / 是否同 prompt / 是否是历史版本 / 是否是重复执行”自动推断为:
- `baseline`
- `reference`
- `referenceBaseline`
- `replica`
- `auxiliary`
这里的角色是中性的 compare 语义,不直接暴露 `reference` 这样的业务词汇,因此更容易复用到普通 compare、稳定性判断和未来的自动优化编排中。
### “根据整份评估结果智能重写”应是通用能力
这次自动迭代的实现已经证明:
- 原始证据可以很长
- 直接把所有 prompt / input / output 全量塞给 rewrite 模型,成本高且容易失焦
- compare evaluation 结果本身就是一层高价值压缩与过滤
因此,更合理的设计不是让 `SPO` 独占“智能改写”,而是让所有评估面板未来都具备一个通用动作:
- 读取整份评估结果
- 对建议做二次过滤
- 拒绝样例特化和过拟合信号
- 在保留硬约束的前提下重写当前工作区 prompt
这样一来:
- compare evaluation 的收益可以被更多入口复用
- `SPO` 只需要负责编排 `test -> compare -> rewrite -> retest`
- 变更范围更清晰,也更符合“尽量增强评估层,自动优化只做薄封装”的方向
## 薄 SPO 设计补充
### 为什么 SPO 不应再加一层专属 judge
当我们开始讨论:
- “改进空间很小是否可以停”
- “和参考模型基本一致是否可以停”
- “是否已经没有必要继续迭代”
最自然的想法,是让 `SPO` 再额外发一个专属 LLM 请求做 stop judge。
但这会带来两个问题:
1. `SPO` 会重新长出一套自己的判断内核
2. compare evaluation 与 `SPO` 的边界会再次变脏
因此,这些判断更适合被收敛为 compare evaluation 的通用 stop signals再由 `SPO` 消费。
### stop signals 应属于 compare evaluation 的通用增强
`SPO` 真正需要的是一组机器可消费的判断信号,例如:
- 当前相对上一轮是 `improved / flat / regressed`
- 当前与参考模型差距是 `major / minor / none`
- 当前改进空间是 `high / medium / low / none`
- 当前过拟合风险是 `low / medium / high`
- 系统建议 `continue / stop / review`
这些信号不仅 `SPO` 可以用,未来:
- compare 详情面板
- 评估结果驱动重写
- 其他自动化工作流
也都可以消费,因此应放在 compare evaluation 层。
### 薄 SPO 的 UI 应以“嵌入测试区”为原则
`SPO` 最终的展示不应是一个新的实验台,而应在现有测试区内最小增量地完成:
- 顶部一个 `SPO` 按钮
- 测试区内一张 `SPO` 运行卡 / 结果卡
- 右侧一个 `SPO` 详情抽屉
核心证据仍然由现有 4 槽测试结果承载。
### 必须区分“最后执行轮”和“最终采用轮”
多轮 `SPO` 下,一个很重要的发现是:
- 最后一轮不一定是最好的
- 后续轮可能开始回归或过拟合
因此系统必须显式维护一个“最终采用轮”的概念。
也就是说:
- `workspace` 应尽量保留当前已接受的最佳轮
- 后续回归轮不能直接覆盖最佳结果
- 最终 UI 必须明确告诉用户:
- 停在第几轮
- 实际采用第几轮

View File

@@ -0,0 +1,564 @@
# 实施拆分Compare Stop Signals 与薄 SPO
## 1. 目标
本文件把当前设计进一步下沉为可实施拆分,重点回答三个问题:
1. compare evaluation 需要补哪些结构化字段
2. `SPO` 运行态和持久化状态分别存什么
3. `BasicSystemWorkspace` 里具体要增加哪些 UI 组件和交互点
目标不是直接给出最终代码,而是为后续实现提供一份“按模块切分、可并行推进、边界清晰”的任务蓝图。
## 2. 总体拆分原则
### 2.1 compare evaluation 先增强,再做 SPO
推荐顺序:
1. compare evaluation 增加 structured compare 所需 hints
2. compare evaluation 增加 stop signals
3. 通用 `rewrite from evaluation` 能力落地
4. `SPO` 再作为薄编排层接入
原因:
- `SPO` 不应自己发明判断逻辑
- `SPO` 应尽量只消费 compare 的结构化结果
- `SPO` 越薄,未来越容易扩展到多模式、多入口
### 2.2 会话持久化与运行态分离
有些状态应该持久化到 session有些则不应持久化。
建议原则:
- 持久化:
- 用户配置
- 角色配置
- 最后一次结果摘要
- 不持久化:
- 当前流式中间状态
- 正在运行中的 abort controller
- 每一步 token 流
### 2.3 UI 不堆逻辑
推荐:
- 把 loop orchestration 抽到 composable
- 把 modal / card / drawer 拆成独立组件
- `BasicSystemWorkspace.vue` 只做连接层
## 3. Compare Evaluation类型层改动
当前基础类型在:
- `packages/core/src/services/evaluation/types.ts`
当前 `CompareAnalysisHints` 仍只有偏通用的布尔信息:
- `hasSharedTestCases`
- `hasSamePromptSnapshots`
- `hasCrossModelComparison`
要支持 structured compare 和 stop signals建议分两步演进。
## 3.1 第一步:扩展 CompareAnalysisHints
建议增加结构化 compare 角色信息:
```ts
export type StructuredCompareRole =
| 'target'
| 'baseline'
| 'reference'
| 'referenceBaseline'
| 'replica'
| 'auxiliary'
export interface CompareAnalysisHints {
hasSharedTestCases?: boolean
hasSamePromptSnapshots?: boolean
hasCrossModelComparison?: boolean
mode?: 'generic' | 'structured'
snapshotRoles?: Record<string, StructuredCompareRole>
}
```
这样做的好处:
- 不引入新的 request 类型
- 不破坏现有 compare 协议
- 允许 structured compare 作为 compare 的增强模式接入
## 3.2 第二步:扩展 EvaluationResponse.metadata
不建议先直接修改顶层 `EvaluationResponse` 的主字段结构。
建议先把 stop signals 放进 `metadata`,例如:
```ts
export interface CompareStopSignals {
targetVsBaseline?: 'improved' | 'flat' | 'regressed'
targetVsReferenceGap?: 'none' | 'minor' | 'major'
improvementHeadroom?: 'none' | 'low' | 'medium' | 'high'
overfitRisk?: 'low' | 'medium' | 'high'
stopRecommendation?: 'continue' | 'stop' | 'review'
stopReasons?: string[]
}
export interface EvaluationResponse {
// 现有字段保持不变
metadata?: {
model?: string
timestamp?: number
duration?: number
compareStopSignals?: CompareStopSignals
}
}
```
这样是最稳妥的第一步:
- 现有使用 `summary / improvements / patchPlan / score` 的地方几乎不用动
- 新能力可以逐步接入
- `SPO` 和结果面板可以开始消费 stop signals
## 4. Compare Evaluation构造层改动
当前 compare payload 构造在:
- `packages/ui/src/composables/prompt/compareEvaluation.ts`
建议拆成两层:
### 4.1 通用层
继续保留:
- `buildCompareEvaluationPayload`
职责:
- 规范化 testCases
- 规范化 snapshots
- 生成最基础的 compareHints
### 4.2 结构化增强层
建议新增:
- `packages/ui/src/composables/prompt/structuredCompareConfig.ts`
- `packages/ui/src/composables/prompt/buildStructuredCompareHints.ts`
职责:
- 维护 target / baseline / reference 等角色配置
- 将测试槽位映射为 `snapshotRoles`
- 产出 `CompareAnalysisHints.mode = 'structured'`
这样 `compareEvaluation.ts` 继续保持中性,而 structured compare 配置逻辑单独存在。
## 5. Compare Evaluation结果消费层改动
当前 compare 结果的主要消费位置包括:
- `packages/ui/src/composables/prompt/useEvaluationHandler.ts`
- `packages/ui/src/components/evaluation/EvaluationPanel.vue`
- `packages/ui/src/components/basic-mode/BasicSystemWorkspace.vue`
建议改动如下。
## 5.1 useEvaluationHandler
建议扩展 compare 结果暴露能力:
- 增加 `compareStopSignals` 的 computed
- 增加是否适合智能重写的 computed
- 增加是否建议停止的 computed
好处:
- `BasicSystemWorkspace` 不必直接解析 `metadata`
- 未来其他页面也能统一消费
## 5.2 EvaluationPanel
建议新增两类能力:
1. `智能重写` 按钮
2. 结构化 stop signals 展示区
stop signals 展示不必太复杂,建议只显示:
- 当前是进步 / 持平 / 回归
- 与参考差距:大 / 小 / 无
- 改进空间:高 / 中 / 低 / 无
- 过拟合风险:低 / 中 / 高
这样既便于人理解,也能验证 stop signals 是否输出稳定。
## 6. SPO状态拆分
## 6.1 应持久化到 session 的状态
建议在:
- `packages/ui/src/stores/session/useBasicSystemSession.ts`
增加以下持久化字段。
### A. `structuredCompareConfig`
用于 compare evaluation 的通用配置,而不是 SPO 私有配置。
```ts
interface StructuredCompareConfig {
targetVariantId: TestVariantId | null
snapshotRoles: Partial<Record<TestVariantId, StructuredCompareRole>>
updatedAt: number
}
```
用途:
- compare 角色配置复用
- 多次 compare 不重复弹窗
- SPO 只是其中一个预填来源
### B. `spoConfig`
```ts
interface SpoConfig {
targetModelKey: string
referenceModelKey: string
maxRounds: number
stopMode: 'round-only' | 'smart' | 'custom'
rewriteModelKey: string
customStopConfig?: {
minScoreDelta?: number
plateauPatience?: number
stopWhenGapSmall?: boolean
stopWhenHeadroomLow?: boolean
stopOnRegression?: boolean
}
}
```
用途:
- 记住用户上一次的 `SPO` 配置
- 方便快速复跑
### C. `spoLastRunSummary`
```ts
interface SpoLastRunSummary {
status: 'completed' | 'stopped' | 'failed'
currentRound: number
acceptedRound: number | null
bestScore: number | null
stopReason: string | null
overview: string
updatedAt: number
}
```
用途:
- 页面重开后仍能显示最近一次结果卡
## 6.2 不应持久化、只在运行时存在的状态
建议放在新的 composable 中,不进入 session
- `isSpoRunning`
- `currentStage`
- `abortRequested`
- `roundRecords`
- `currentRoundCompareResult`
- `currentRoundRewriteDraft`
- `currentRoundRetestResult`
原因:
- 这些状态高度临时
- 一旦刷新页面,恢复运行中循环的价值很低
- 持久化会明显增加 session 复杂度
## 7. SPO建议新增 composable
建议新增:
- `packages/ui/src/composables/prompt/useSpoLoopController.ts`
职责:
- 管理 `SPO` 配置
- 预设 4 槽位
- 应用 structured compare config
- 执行多轮 loop
- 决定 stop / accept / continue
- 产出 UI 所需的运行态摘要
建议它只接收依赖,不直接耦合模板/服务定位细节,例如:
```ts
useSpoLoopController({
session,
evaluationHandler,
runVariantsBatch,
buildRewriteInstruction,
promptService,
saveSession,
})
```
这样 `BasicSystemWorkspace.vue` 只负责把现有能力装配进去。
## 8. SPOBasicSystemWorkspace 的 UI 拆分
当前 `BasicSystemWorkspace.vue` 已经非常大,不建议再继续内联 `SPO` UI。
推荐新增以下组件:
## 8.1 `SpoConfigModal.vue`
建议路径:
- `packages/ui/src/components/testing/SpoConfigModal.vue`
职责:
- 编辑 `spoConfig`
- 预览 4 槽位预设
- 预览 structured compare 角色
- 启动 `SPO`
## 8.2 `SpoRunCard.vue`
建议路径:
- `packages/ui/src/components/testing/SpoRunCard.vue`
职责:
- 显示运行中进度
- 显示当前阶段
- 显示当前轮次
- 显示当前风险提示
- 提供 `查看详情 / 立即停止`
## 8.3 `SpoResultCard.vue`
建议路径:
- `packages/ui/src/components/testing/SpoResultCard.vue`
职责:
- 显示最终状态
- 显示最终采用轮次
- 显示停止原因
- 提供 `查看详情 / 保存版本 / 继续 1 轮 / 重新运行`
## 8.4 `SpoRunDrawer.vue`
建议路径:
- `packages/ui/src/components/testing/SpoRunDrawer.vue`
职责:
- 显示运行概览
- 显示每轮历史
- 显示选中轮次详情
## 8.5 `VariantRoleBadge.vue`
建议路径:
- `packages/ui/src/components/testing/VariantRoleBadge.vue`
职责:
- 在测试槽位头部展示:
- `Target`
- `Baseline`
- `Reference`
- `Reference Baseline`
这也能服务于非 SPO 的 structured compare 场景。
## 9. BasicSystemWorkspace最小接入点
`packages/ui/src/components/basic-mode/BasicSystemWorkspace.vue` 中,建议只增加以下接入点:
### 9.1 顶部按钮区
- 新增 `SPO` 按钮
- 点击打开 `SpoConfigModal`
### 9.2 compare 卡片下方
根据状态显示:
- 运行中:`SpoRunCard`
- 结束后:`SpoResultCard`
### 9.3 测试槽位头部
- 为每个 variant 增加 `VariantRoleBadge`
### 9.4 页面底部/根节点
- 挂载 `SpoRunDrawer`
这样 `BasicSystemWorkspace` 不直接承担复杂循环逻辑,只承担“把已有能力装配到 UI”。
## 10. 推荐文件改动清单
## 10.1 compare evaluation 通用增强
- `packages/core/src/services/evaluation/types.ts`
- 增加 `StructuredCompareRole`
- 增加 `CompareStopSignals`
- 扩展 `CompareAnalysisHints`
-`EvaluationResponse.metadata` 中增加 `compareStopSignals`
- `packages/ui/src/composables/prompt/compareEvaluation.ts`
- 支持 structured compare hints 的组装
- `packages/ui/src/composables/prompt/useEvaluationHandler.ts`
- 对外暴露 `compareStopSignals`
- `packages/ui/src/components/evaluation/EvaluationPanel.vue`
- 增加 stop signals 展示
- 增加 `智能重写` 按钮
## 10.2 structured compare 配置层
- `packages/ui/src/composables/prompt/structuredCompareConfig.ts`
- 配置类型
- 角色推断
- 角色校验
- `packages/ui/src/composables/prompt/buildStructuredCompareHints.ts`
- 将 UI 角色配置映射为 compare hints
## 10.3 SPO 编排层
- `packages/ui/src/composables/prompt/useSpoLoopController.ts`
- 多轮编排
- 停止策略
- 最佳轮接受策略
## 10.4 session 层
- `packages/ui/src/stores/session/useBasicSystemSession.ts`
- 持久化 structured compare config
- 持久化 spo config
- 持久化 spo last run summary
## 10.5 UI 组件层
- `packages/ui/src/components/testing/SpoConfigModal.vue`
- `packages/ui/src/components/testing/SpoRunCard.vue`
- `packages/ui/src/components/testing/SpoResultCard.vue`
- `packages/ui/src/components/testing/SpoRunDrawer.vue`
- `packages/ui/src/components/testing/VariantRoleBadge.vue`
## 11. 推荐实施阶段
### Phase Acompare signals
先做:
- `types.ts`
- `compareEvaluation.ts`
- `useEvaluationHandler.ts`
目标:
- structured compare hints 可以传下去
- stop signals 可以稳定被 UI 消费
### Phase B评估面板通用增强
再做:
- `EvaluationPanel.vue`
- 通用 `rewrite from evaluation`
目标:
- 先让 compare 自己变得“更可用、更可验证”
### Phase Csession 与 structured compare 配置
再做:
- `useBasicSystemSession.ts`
- `structuredCompareConfig.ts`
目标:
- compare 角色和 `SPO` 配置有可复用的状态承载
### Phase DSPO UI 壳层
再做:
- `SpoConfigModal.vue`
- `SpoRunCard.vue`
- `SpoResultCard.vue`
- `SpoRunDrawer.vue`
- `VariantRoleBadge.vue`
目标:
- UI 先落壳,不急着一次性做完完整 loop
### Phase ESPO loop controller
最后做:
- `useSpoLoopController.ts`
- `BasicSystemWorkspace.vue` 接线
目标:
- 多轮 loop 真正跑通
## 12. 风险与注意点
### 12.1 不要让 session 过重
建议不要把完整每轮详细 compare 结果都持久化进 session。
优先持久化:
- 配置
- 结果摘要
- 最终采用轮次
### 12.2 不要让 EvaluationResponse 直接大改
建议 stop signals 先进入 `metadata`,避免波及所有消费方。
### 12.3 不要在 BasicSystemWorkspace 再塞更多内联状态
当前文件已经足够大,后续新增逻辑应尽量拆到 composable 和独立组件中。
## 13. 结论
如果按最小风险实施,最合理的技术路径是:
1. 先增强 compare evaluation 的 machine-readable outputs
2. 再落通用 rewrite from evaluation
3. 再引入 structured compare config
4. 最后做薄 `SPO` 的 loop 与 UI 壳
这样能最大化复用现有能力,同时把复杂度控制在最小范围内。

View File

@@ -0,0 +1,158 @@
# 进展日志
## 会话2026-03-19
### 需求收口(已完成)
- 明确本次需求不是“再做一个独立的 prompt optimizer studio”。
- 明确要把 SPO 风格的“朝目标自动对齐”能力,嵌入现有测试区工作流。
- 明确 V1 优先做“一轮自动迭代”,而不是多轮 autonomous loop。
- 明确自动配置项收敛为:
- `目标模型`
- `参考模型`
### 方案收敛(已完成)
- 确认复用现有多槽位测试区,而不是新建页面。
- 确认自动生成 4 槽位预设:
- `目标模型 / workspace`
- `目标模型 / 上一版本`
- `参考模型 / workspace`
- `参考模型 / 上一版本`
- 确认优化对象始终是 `目标模型 / workspace`
- 确认 `workspace` 代表当前工作区草稿,“上一版本”代表当前轮次之前的最近稳定版本。
- 确认 `v-last` 与“基线”都不够精确文档改用“上一版本previous version”。
- 确认首期实现范围切换为 `basic-system`,聚焦系统提示词优化。
- 确认测试输入只用于暴露系统提示词行为,不得成为样例特化规则来源。
### 文档产出(已完成)
- 新增工作区设计目录:`docs/workspace/test-area-auto-iterate-one-round/`
- 新增架构文档:`docs/architecture/test-area-auto-iterate-one-round.md`
- 文档重点覆盖:
- 交互入口
- 4 槽位预设
- 一轮执行编排
- 目标锚点提取
- 模型上下文构造
- 防过拟合规则
### 当前状态
- 设计已收口,尚未开始代码实现。
## 会话2026-03-19结构化对比评估补充
### 新增设计决策(已完成)
- 明确 compare evaluation 不应直接依赖 `SPO` 配置,而应依赖一组中性的结构化 compare 角色语义。
- 明确 compare evaluation 需要分为:
- `Generic Compare`
- `Structured Compare`
- 明确 `Structured Compare` 的角色模型为:
- `target`
- `baseline`
- `reference`
- `referenceBaseline`
- `replica`
- `auxiliary`
- 明确“根据整份评估结果自动重写 prompt”应作为通用能力服务于所有评估面板而不是仅服务于自动优化。
### 文档产出(已完成)
- 新增架构补充:
- `docs/architecture/structured-compare-and-evaluation-rewrite.md`
### 当前状态
- compare evaluation 的增强方向已收口为:
- 结构化 compare
- 评估结果驱动的通用智能重写
- 自动迭代的正式实现尚未按该设计落地。
- `SPO` 的后续职责被明确收敛为“上层编排”,不再承载 compare 与 rewrite 的底层智能。
## 会话2026-03-19薄 SPO UI 与停止规则补充)
### 新增设计决策(已完成)
- 明确 `SPO` 不增加专属 judge LLM 调用,继续复用 compare evaluation 的判断结果。
- 明确 `SPO` 的停止条件应优先依赖 compare evaluation 输出的通用 stop signals而不是额外再做一层文本判断。
- 明确 `SPO` 主界面不新建页面,而是以:
- 顶部 `SPO` 按钮
- 测试区 `SPO` 运行卡 / 结果卡
- 右侧 `SPO` 详情抽屉
的方式嵌入现有测试区。
- 明确多轮过程中要区分:
- `最后执行轮`
- `最终采用轮`
### 文档产出(已完成)
- 新增架构补充:
- `docs/architecture/spo-thin-loop-ui-and-stop-rules.md`
### 当前状态
- compare evaluation 的设计边界进一步清晰:
- 负责 structured compare、stop signals、通用智能重写
- `SPO` 的设计边界进一步清晰:
- 负责按钮、弹窗、循环、停止、结果展示
## 会话2026-03-19实施拆分补充
### 新增设计决策(已完成)
- 明确 compare stop signals 第一阶段建议先落在 `EvaluationResponse.metadata`,避免大范围破坏现有消费方。
- 明确 structured compare config 与 `SPO` config 应分离:
- 前者属于 compare 通用能力
- 后者属于 `SPO` 薄编排层
- 明确 `SPO` 的运行中状态不应全部持久化到 session应与可恢复配置拆开。
- 明确 `BasicSystemWorkspace.vue` 应只保留最小接线职责,复杂 UI 与循环逻辑应拆出。
### 文档产出(已完成)
- 新增实施拆分文档:
- `docs/workspace/test-area-auto-iterate-one-round/implementation-split-compare-stop-signals-and-spo.md`
### 当前状态
- 下一步已经可以按模块推进实现:
- compare types / payload / signals
- evaluation panel 通用增强
- session 状态扩展
- `SPO` UI 壳层
- `SPO` loop controller
## 会话2026-03-19文档整理与口径统一
### 新增整理结论(已完成)
- 确认当前仓库里只有文档设计,先前偏离最新方案的 `SPO` 小 demo 已经回滚。
- 确认 compare evaluation 的“当前已实现行为”和“下一阶段目标设计”必须分开描述,避免把设计稿写成现状。
- 确认 `acceptedRound` 的依据应来自“复测后的 structured compare 结果”,而不是 `SPO` 自己额外发明 judge。
- 确认推荐落地顺序统一为:
- compare types / signals
- 评估面板通用增强 + rewrite from evaluation
- structured compare config
- `SPO` UI 壳层
- `SPO` loop controller
- 确认 `teacher model` 术语在当前设计中统一收敛为 `reference model`;较早的一轮方案文档只保留必要的历史说明。
### 文档更新(已完成)
- 更新目录说明与当前状态:
- `docs/workspace/test-area-auto-iterate-one-round/README.md`
- `docs/workspace/test-area-auto-iterate-one-round/task_plan.md`
- `docs/workspace/test-area-auto-iterate-one-round/progress.md`
- 更新 compare 当前规范与下一阶段设计边界:
- `docs/workspace/compare-evaluation-analysis/current-spec.md`
- `docs/architecture/structured-compare-and-evaluation-rewrite.md`
- 更新 `SPO` 停止规则与 accepted round 依据:
- `docs/architecture/structured-compare-and-evaluation-rewrite.md`
- `docs/architecture/spo-thin-loop-ui-and-stop-rules.md`
### 当前状态
- 文档口径已基本统一。
- compare evaluation 与薄 `SPO` 的边界更清晰。
- 代码实现仍待按更新后的设计重新推进。

View File

@@ -0,0 +1,133 @@
# 任务计划:测试区自动迭代一轮
## 目标
在当前 `basic-system` 工作区右侧测试区中,新增一个“自动迭代”入口,让用户只需选择:
- `目标模型`
- `参考模型`
系统就能自动生成 4 槽位对比预设,并完成一次完整的自动迭代闭环:
1. 用同一组测试输入运行 4 个槽位
2. 分析 `目标/workspace` 与其他 3 个参考槽位的差异
3. 提取可迁移的目标锚点与改进方向
4. 仅改写当前 `workspace` 提示词
5. 重新执行 4 槽位测试,展示一轮后的结果
## 当前阶段
Phase 8实施拆分与落地顺序设计完成等待按新方案重新实现
## 阶段与状态
### Phase 1需求收口与方案边界已完成
- [x] 明确不做独立 SPO 实验页,优先复用现有测试区
- [x] 明确 V1 只做“自动迭代一轮”,不是多轮自动代理
- [x] 明确核心配置仅保留 `目标模型``参考模型`
- [x] 明确自动形成 4 槽位预设,而不是要求用户手工逐列配置
### Phase 2现状调研与能力映射已完成
- [x] 确认当前 `basic-system` 已支持 2/3/4 列测试布局
- [x] 确认当前 session 已持久化 `testVariants`
- [x] 确认当前对比评估链路已支持多 `snapshot` 输入
- [x] 确认现有通用 A/B 状态工具不是本次主入口,主入口在 `BasicSystemWorkspace`
### Phase 3交互与架构设计已完成
- [x] 设计测试区顶部的“自动迭代”按钮与配置弹窗
- [x] 设计 4 槽位自动预设规则
- [x] 设计一轮自动迭代的编排流程
- [x] 设计防过拟合与回归保护规则
- [x] 输出相关设计文档
### Phase 4实现准备已完成
- [x] 明确 session 中是否持久化自动迭代配置
- [x] 抽离自动迭代编排逻辑,避免继续膨胀 `BasicSystemWorkspace.vue`
- [x] 定义“本轮总结”数据结构,用于展示本轮学习点、改动点、风险点
- [x] 对接现有迭代/改写链路,确保只写回 `workspace`
### Phase 5实现与验证未开始先前试验实现已回滚
- [ ] 测试区顶部接入自动迭代入口
- [ ] 完成 4 槽位预设生成
- [ ] 完成首轮执行、对比评估、智能重写、复测闭环
- [ ] 补充针对 `basic-system` 的验证用例
- [ ] 浏览器手工验证 2/3/4 列、空历史链、模型缺失、执行失败等场景
- [ ] 浏览器手工验证“测试输入变化时不产生样例特化规则”的约束场景
### Phase 6Structured Compare 与通用智能重写(已完成设计)
- [x] 明确 compare evaluation 应拆分为 `Generic Compare``Structured Compare`
- [x] 明确 `target / baseline / reference / referenceBaseline / replica / auxiliary` 角色模型
- [x] 明确 compare evaluation 只依赖结构化角色语义,不直接依赖 SPO 设置
- [x] 明确“根据整份评估结果自动重写”应作为通用能力,而不是 SPO 私有能力
- [x] 输出工作区设计补充文档
- [x] 输出架构设计补充文档
### Phase 7薄 SPO 的 UI / 停止规则 / 多轮编排(已完成设计)
- [x] 明确 `SPO` 只负责 preset、loop、stop 和结果展示
- [x] 明确不增加 `SPO` 专属 judge LLM 调用
- [x] 明确停止条件优先依赖 compare evaluation 的通用 stop signals
- [x] 设计 `SPO` 按钮、设置弹窗、运行卡、结果卡、详情抽屉
- [x] 设计 `最终采用轮次``最后执行轮次` 的区分规则
- [x] 输出工作区设计补充文档
- [x] 输出架构设计补充文档
### Phase 8实施拆分与落地顺序已完成设计
- [x] 明确 compare stop signals 的类型扩展位置
- [x] 明确 structured compare config 与 SPO config 的状态边界
- [x] 明确 session 持久化状态与运行时状态的拆分
- [x] 明确 `BasicSystemWorkspace` 的最小接入点
- [x] 明确推荐新增的 composable 与 UI 组件列表
- [x] 输出实施拆分文档
## 当前实现状态补充
- 当前主干代码里还没有按本目录最新设计落地的自动迭代实现。
- 先前试做过一版 V1 demo但因为
- compare intelligence 与 `SPO` 编排耦合过深
- “根据评估结果智能重写”没有真正下沉为通用能力
- 停止条件与 accepted round 依据没有设计完整
所以已回滚,后续会按最新设计重新实现。
- 当前 compare evaluation 的外部返回结构在下一阶段仍建议保持不变:
- `summary`
- `improvements`
- `patchPlan`
- `score`
- 下一阶段的重点不是继续堆叠 `SPO` 专属逻辑,而是把 compare evaluation 的通用增强收口为:
- `Generic Compare / Structured Compare`
- 基于整份评估结果的通用智能重写
- 面向 `SPO` 与其他自动化入口通用可消费的 stop signals
- 一套可按阶段落地的实施拆分
- 已达成的循环抽象是:
1. 运行测试
2. 对比评估
3. 根据评估结果智能改进
4. 继续执行测试
其中多轮 `SPO` 的 accept / stop 判定以后续的 compare 通用增强为准。
## 目标验收标准(待实现)
- 用户可以在测试区内打开自动迭代弹窗,不需要跳转新页面
- 用户只配置 `目标模型``参考模型`,系统自动生成 4 槽位
- 自动迭代明确以 `目标模型 / workspace` 为优化对象
- 自动迭代只改动工作区草稿,不直接覆盖历史版本
- 一轮结束后,用户能看到新的 `workspace` 结果与“上一版本”、参考模型的对比
- 本轮结论中必须包含防过拟合说明,不能只以单次测试分数提升作为成功标准
- 本轮结论必须明确说明“改动针对系统提示词结构,而不是针对当前测试输入内容打补丁”
## 关键决策(摘要)
- 复用现有测试区与多槽位能力,不新增独立实验台。
- 将“目标识别”收敛为“目标槽位 + 提示词内显式约束 + 差异证据”的组合锚点,而不是额外要求用户填写目标说明。
- 历史参考统一称为“上一版本previous version它在实现上对应当前工作区本轮改写前的最近稳定版本若不存在则退化为 `v0`
- 自动改写只写回 `workspace`,历史链仍由用户决定是否保存,降低误操作成本。
- 首期聚焦 `basic-system`,优化对象是系统提示词,而不是测试输入内容。
- compare evaluation 的未来增强方向是 `Structured Compare`,其角色依赖于结构化 compare 语义,而不是硬绑定 `SPO`
- “根据评估结果智能重写”应下沉为所有评估面板共用的基础能力,`SPO` 只负责调用与编排。

View File

@@ -3,7 +3,7 @@ import type { TemplateMetadata } from '@prompt-optimizer/core'
export type TemplateManagerTemplateType = Exclude<
TemplateMetadata['templateType'],
'contextSystemOptimize' | 'evaluation'
'contextSystemOptimize' | 'evaluation' | 'variable-extraction' | 'variable-value-generation'
>
export interface TemplateManagerHooks {