整体重构梳理:分析、评估与多测试对比评估
这份文档不是在补充某个局部细节,而是把这次讨论整体收成一个新框架。 核心目的只有一个:以后不要再把左侧“分析”和右侧“评估”当成同一种结构的不同变体。
状态说明(2026-03-14): 这份文档的核心边界定义仍然有效,但其中部分“接下来要做”的内容,当前代码已经落地了一部分。 最新实现状态请优先参考:
current-analysis-feature-map.mdprogress.md进一步说明:
- 文本 workspace 的
result / compare / prompt-*主语义已经基本落地。- 文中凡是把“当前实现”写成 A/B only、
original / optimized、或“单结果评估只覆盖 A/B”的段落,应理解为前期问题背景,而不是当前代码事实。- 当前真正还没完全收口的,主要是 compare 结构还没有继续演进到
inputs[] + variants[],以及 image 模式右侧评估链路。
1. 最终结论
当前功能在产品表面上都叫“分析 / 评估”,但从结构上看,后续应该明确拆成 3 类并列能力:
- 分析(analysis)
- 单结果评估(single evaluation)
- 对比评估(compare evaluation)
它们不是一个大接口的 3 个小分支,而是:
- 分析:看“设计对象本身”
- 单结果评估:看“一次执行结果”
- 对比评估:看“多次执行结果之间的关系”
这点在“评估要升级成支持多个测试变体”之后会更加明显。
1.1 当前主任务(收敛版)
基于最新讨论,这轮主任务可以收成下面 3 条:
- 明确区分“分析”和“评估”的语义、结构与 UI 文案。
- 矫正分析功能,默认不准引用右侧测试内容和变量实例值。
- 重构评估功能,使其基于测试快照支持单结果评估与多测试对比评估,不再依赖左侧“优化前/优化后”的版本语义。
再补一个实现原则:
- 评估基于测试快照,修改统一面向左侧当前工作区;无法应用就跳过,不建立版本绑定关系。
2. 为什么现在必须拆开
在旧模型里,大家容易把它们混在一起,是因为:
- compare 当时还只有 A/B 两列
- 右侧评估的输入结构还比较扁平
- 左侧分析和右侧评估都复用了同一套
EvaluationType话语体系
但如果评估真的要支持:
- 2/3/4 个测试列
- 每列不同模型
- 每列不同版本
- 输入去重
- 多输出统一对比
那右侧评估天然就会长成“测试变体集合”的结构。
而左侧分析不会。
左侧分析更像:
- 当前 prompt 是什么
- 原始参考内容是什么
- 当前上下文是什么
- 当前变量设计是什么
- 当前迭代要求是什么
右侧评估更像:
- 这次实际用了哪段 prompt 快照
- 这次实际跑了什么输入
- 用了什么模型
- 产出了什么输出
右侧对比评估更像:
- 这些测试变体之间,谁共享输入
- 谁模型不同
- 谁版本不同
- 哪些输出更好
所以从这一步开始,再把“分析”和“评估”强行塞回同一请求结构里,成本会越来越高。
3. 新的总体边界
后续建议用下面这套边界统一全局。
3.1 分析
分析回答的是:
- 这个 prompt / context 本身设计得好不好?
- 变量设计是否清晰?
- 结构是否合理?
- 当前修改方向是否符合迭代目标?
分析默认应具有这些特点:
- 不依赖测试输出
- 不默认依赖右侧测试样本值
- 更接近“设计态检查”
分析应该主要消费:
- 当前 prompt / message / context 文本
- 原始参考文本
- 变量 schema
- 会话结构
- 迭代要求
3.2 单结果评估
单结果评估回答的是:
- 这一次测试跑出来的结果好不好?
- 这次输入和输出是否匹配?
单结果评估默认应具有这些特点:
- 依赖一个真实测试输出
- 关注“输入 + 输出”的效果
- 更接近“执行态评估”
单结果评估应该主要消费:
- 一次测试时实际使用的 prompt 快照
- 一次实际测试输入
- 一个模型
- 一个输出结果
3.3 对比评估
对比评估回答的是:
- 多个测试变体之间谁更好?
- 差异来自提示词、模型,还是执行输入?
- 哪些变体共享输入,哪些不是?
对比评估默认应具有这些特点:
- 依赖多个真实测试输出
- 关注“变体之间的关系”
- 更接近“实验对比”
对比评估应该主要消费:
- 去重后的输入列表
- 多个测试变体
- 每个变体的模型、输入引用、输出
4. 一个更清楚的三层输入模型
为了避免后面再把“测试文本”“变量值”“prompt 结构”“输出结果”混在一起,建议先把输入分成 3 层。
4.1 设计态输入
这层输入是给分析用的,典型包括:
- prompt / message / context 正文
- 原始版本
- 变量名、变量来源、是否缺失
- 会话结构
- 迭代要求
它回答的是:
- 你设计了什么
4.2 执行态输入
这层输入是给评估用的,典型包括:
- 测试文本
- 当前变量实例值
- 当前模型
- 当前工具配置
- 渲染后的最终输入
它回答的是:
- 你实际拿什么去跑了
4.3 执行态输出
这层输入是评估和对比评估都要看的,典型包括:
- 文本输出
- reasoning
- 图像结果摘要
它回答的是:
- 跑出来了什么
映射起来就是:
- 分析:主要看设计态输入
- 单结果评估:看执行态输入 + 执行态输出
- 对比评估:看多个执行态输入来源 + 多个执行态输出
5. 为什么“变量值默认进入分析”应该被纠正
这是这次梳理里一个很重要的新结论。
当前 context-user 左侧分析会带:
variablesrawPromptresolvedPrompt
这说明当前实现确实会把变量实例值喂给左侧分析。
但这更像历史实现结果,不适合直接固化成目标设计。
原因是:
- 左侧分析应该优先看模板设计,而不是某次样本值
- 样本值属于测试执行上下文,更适合进入右侧评估
- 如果默认把样本值塞给分析,分析结论会过度依赖当前测试态
更合理的边界是:
- 默认分析:看变量 schema,不看变量实例值
- 诊断分析:必要时显式带变量实例值
- 评估 / 对比评估:正常带变量实例值
也就是说:
- “变量语义”属于分析
- “变量样本值”默认属于评估
6. 结构上应该怎么拆
从接口角度,建议后续至少拆成 3 类请求。
6.1 PromptAnalysisRequest
它代表左侧分析。
export interface PromptAnalysisRequest {
type: 'prompt-only' | 'prompt-iterate'
target: {
mode: 'basic-user' | 'basic-system' | 'context-user' | 'context-system' | 'image'
original?: string
current: string
}
context?: {
conversation?: unknown
variableSchema?: Array<{
name: string
source: 'predefined' | 'global' | 'temporary'
required?: boolean
}>
}
iterateRequirement?: string
}
关键点:
- 不带测试输出
- 不默认带变量实例值
6.2 SingleTestEvaluationRequest
它代表右侧单列评估。
export interface SingleTestEvaluationRequest {
type: 'single'
snapshot: {
id: 'a' | 'b' | 'c' | 'd'
label: string
model: {
key: string
providerId?: string
modelId?: string
}
prompt: {
mode: string
content: string
}
executionInput: {
mode: string
summary: string
body: string
}
output: {
kind: 'text' | 'image'
content: string
reasoning?: string
}
}
}
关键点:
- 一个请求只评估一个真实测试快照
- 不需要知道它是“优化前”还是“优化后”
- 结构中心是
snapshot
6.3 MultiVariantCompareEvaluationRequest
它代表右侧多测试对比评估。
export interface MultiVariantCompareEvaluationRequest {
type: 'compare'
inputs: Array<{
id: string
fingerprint: string
mode: string
title: string
summary: string
body: string
}>
variants: Array<{
id: 'a' | 'b' | 'c' | 'd'
label: string
model: {
key: string
providerId?: string
modelId?: string
}
inputId: string
output: {
kind: 'text' | 'image'
content: string
reasoning?: string
}
}>
}
关键点:
- 结构中心不再是
original/optimized - 而是
inputs[] + variants[]
7. 这三类能力为什么不该强行共用一套 builder
可以共用一些底层能力,但不应共用同一层业务 builder。
可以共用的
- 模板路由
- LLM 调用
- JSON 解析
- 评分结果结构
不该强行共用的
- 输入归一化
- summarizer
- 领域对象
原因是:
- 分析看的是设计态对象
- 单结果评估看的是单次执行
- 对比评估看的是多次执行关系
所以更合理的方向是:
analysis/*evaluation/*compare/*
而不是继续把三者都塞进一个“泛 evaluation builder”。
8. 对当前代码意味着什么
这套新框架落到当前项目,意味着几件事。
8.1 左侧分析链路要收紧
- 继续保留
prompt-only/prompt-iterate - 但默认只吃设计态输入
- 不默认吃右侧测试样本值
8.2 右侧单列评估链路要从 A/B 特权里走出来
这个小节描述的是重构前的问题背景:当时 original / optimized 只挂在 A/B 上。
后续如果真的支持多测试,应该理解成:
- 每个测试快照都可以被单独评估
也就是说,今天的:
originaloptimized
更像是“历史 UI 触发语义”,不是未来最稳定的领域模型。
8.3 compare 链路要从二元语义改成多变体语义
这是这次改造最核心的一块:
- 从
original/optimized - 走向
variants + deduped inputs
8.4 useEvaluationHandler 后续更像协调层,不应继续承担全部抽象
后面它更适合做:
- 路由
- 状态衔接
- 结果持久化
而不是自己既处理分析、又处理单结果评估、又处理多结果对比评估的全部输入建模。
8.5 评估结果不做版本绑定,只统一回写左侧当前工作区
这里建议刻意保持简单:
- 评估时记录的是测试快照,不是版本分支身份
- 应用建议时,统一尝试作用到左侧当前工作区
- 如果因为左侧内容已经变化而无法自动应用,就直接跳过
这样做的目的是:
- 保持评估语义正确
- 同时避免把系统推向复杂的版本绑定 / 版本回放设计
9. 推荐的实现顺序
如果按“风险最小”的方式推进,建议顺序是:
- 先统一领域语言,明确分析 / 单结果评估 / 对比评估三层
- 再把 compare request 改成多变体结构
- 再把单结果评估从 A/B 特殊逻辑中抽出来
- 最后收紧分析输入,只保留设计态默认输入
这个顺序的好处是:
- 最先解决最影响认知的问题
- compare 抽象先对齐多测试目标
- analysis 与 evaluation 的边界最后再收口,不会一开始改得太散
10. 一句话版本
如果要把这次整体梳理收成一句话,可以直接用这句:
- 分析看设计,评估看一次执行,对比评估看多次执行之间的关系。
再补一句更具体的:
- 多测试一旦成立,评估就天然是“变体集合”结构,而分析仍然是“对象快照”结构。
这就是为什么后续这两者应该越拆越清楚,而不是继续揉在一起。
Source: docs/workspace/compare-evaluation-analysis/history/overall-reframing.md