Files
prompt-optimizer/docs/workspace/prompt-data-standardization/01-提示词数据格式标准化设计.md

20 KiB
Raw Blame History

提示词标准化设计

1. 设计目标

本设计建立项目内部的通用提示词模型,用来统一工作区、收藏、优化历史、测试结果、外部导入、图像提示词等场景。

目标不是先改某一个收藏字段,而是先定义稳定的领域语言:

  1. 一个提示词资产是什么。
  2. 一个工作区会话是什么。
  3. 一条优化链是什么。
  4. 一次测试运行和一个可复现示例有什么区别。
  5. basic / pro / image 三类模式如何用同一套结构表达。
  6. FavoritePrompt、旧 PromptRecordChain、旧 session/v1/* 如何兼容到新模型。

本文先描述标准领域模型和目标语义;当前已经落地的实现边界见 2.3,不要求一次性替换现有存储和 UI。


2. 核心结论

2.1 模型分层

PromptAsset
  ├─ PromptContentVersion[]       // 长期资产正文版本
  └─ PromptExample[]              // 长期可复现示例

PromptSession
  ├─ assetBinding?                // 最多绑定一个资产
  ├─ draft                        // 当前工作区草稿
  ├─ PromptOptimizationChain      // 有且只有一条主优化链
  └─ PromptTestRunSet[]           // 会话内测试运行

PromptOptimizationChain
  ├─ root                         // 原始提示词
  └─ records[]                    // 优化/迭代输出,可为空

2.2 关键不变量

  • 一个 session 有且只有一条主 PromptOptimizationChain
  • 一个 session 最多绑定一个 PromptAsset
  • 一个 asset 可以被多个 session 打开、派生或继续编辑。
  • optimization chain 可以是 root-only只有原始提示词没有任何优化结果。
  • 原始提示词可以直接测试,测试结果属于 session test run。
  • 点击“优化”创建新的 session 和新的 optimization chain。
  • 点击“迭代/继续优化”追加到当前 session 的当前 chain。
  • 资产正文版本链只记录用户明确保存的资产正文,不自动等于优化历史。
  • 测试运行不是资产示例;只有用户明确保存测试结果时,才转成 PromptExample

2.3 当前落地状态2026-05-02

截至 2026-05-02标准模型已经进入“底层模型、兼容适配层、收藏资产写入、示例保存、来源坐标和媒体资产维护已落地显式多 session 产品形态尚未落地”的阶段:

  • @prompt-optimizer/core 已新增并导出 services/prompt-model,包含 mode、content、favorite、history、session、example 等纯类型和转换函数。
  • FavoritePrompt 仍是收藏服务的持久化容器;metadata.promptAsset 是标准资产快照;metadata.reproducibility 是用户可编辑的变量/示例草稿;metadata.gardenSnapshot 只读保留来源快照。
  • 普通工作区保存收藏只保存正文和变量定义,不再自动生成 workspace-current 示例。
  • 测试结果只有在用户点击“保存为示例”时,才从 PromptTestRun 转成 PromptExample / reproducibility example。
  • 现有 session/v1/* 仍作为隐式 session 使用,但已经能携带 assetBindingorigin,并通过 useSessionManager.getPromptSession() / hydrated session 投影到标准 PromptSession
  • 从收藏或 PromptAsset 应用到工作区时,会写入隐式 session 的来源和资产版本绑定;重新优化、分析、清空内容时会清理旧绑定。
  • 工作区保存、测试结果保存和更新已有收藏都通过显式保存目标面板确认;已有来源坐标只用于默认选择目标,不代表可以静默写回旧收藏。
  • 保存测试结果为示例时,示例绑定提示词资产 / 收藏;basedOnVersionId 和来源坐标只用于追溯,不要求当前 workspace 正文与目标资产当前正文严格一致。
  • 收藏创建 / 编辑会通过 FavoriteManager 刷新 metadata.promptAsset;显式更新正文时,正文变化会创建新的 content version只追加示例时不会修改正文版本链。
  • pro-conversation 在标准层使用 messages;当前 UI 仍复用既有 pro-multi store key并已支持把收藏中的 messages 恢复为多消息会话。文本拼接只作为兼容降级。
  • 导入导出和媒体资产清理已经扫描 metadata.promptAsset、当前 reproducibility、Garden snapshot 和 legacy 结构中的图片引用。

仍未落地的部分:

  • 用户可见的“新建 / 切换 / 关闭 session”入口和多 session 列表。
  • 独立的资产正文版本管理 UI例如版本差异、冲突提示、手动切换 / 合并策略。
  • 测试结果示例的更完整批量管理体验;单个测试结果保存和追加语义已落地,批量选择多个结果保存为多个 example 尚未落地。
  • 收藏详情来源分区、Garden 来源展示层级、完整会话消息可视化编辑体验仍需单独设计。
  • 当前没有未关闭的 active Trellis 任务承接这些后续项;需要继续推进时应先拆分新的 Trellis 任务。

3. 模式标准化

新模型只使用以下模式:

type PromptModeKey =
  | 'basic-system'
  | 'basic-user'
  | 'pro-variable'
  | 'pro-conversation'
  | 'image-text2image'
  | 'image-image2image'
  | 'image-multiimage'

3.1 PromptContract

type PromptContract =
  | BasicPromptContract
  | ProPromptContract
  | ImagePromptContract

type BasicPromptContract = {
  family: 'basic'
  modeKey: 'basic-system' | 'basic-user'
  subMode: 'system' | 'user'
  variables: PromptVariable[]
  inputs?: PromptInputSlot[]
  outputs?: PromptOutputSpec[]
}

type ProPromptContract = {
  family: 'pro'
  modeKey: 'pro-variable' | 'pro-conversation'
  subMode: 'variable' | 'conversation'
  variables: PromptVariable[]
  inputs?: PromptInputSlot[]
  outputs?: PromptOutputSpec[]
}

type ImagePromptContract = {
  family: 'image'
  modeKey: 'image-text2image' | 'image-image2image' | 'image-multiimage'
  subMode: 'text2image' | 'image2image' | 'multiimage'
  variables: PromptVariable[]
  inputs?: PromptInputSlot[]
  outputs?: PromptOutputSpec[]
}

3.2 历史字段映射

历史结构 标准结构
functionMode=basic, optimizationMode=system basic-system
functionMode=basic, optimizationMode=user basic-user
functionMode=context, optimizationMode=user pro-variable
functionMode=context, optimizationMode=system pro-conversation
functionMode=image, imageSubMode=text2image image-text2image
functionMode=image, imageSubMode=image2image image-image2image
functionMode=image, imageSubMode=multiimage image-multiimage

context 只保留在 legacy adapter 中,新领域模型不再使用它。


4. 通用内容结构

4.1 PromptContent

type PromptContent =
  | {
      kind: 'text'
      text: string
    }
  | {
      kind: 'messages'
      messages: ConversationMessage[]
    }
  | {
      kind: 'image-prompt'
      text: string
    }

说明:

  • basic 和多数 image 模式先使用 textimage-prompt
  • pro-conversation 使用 messages,避免把多消息会话压成单字符串。
  • FavoritePrompt.content 映射为 PromptContent.kind = 'text'

4.2 变量、输入、输出

type PromptVariable = {
  name: string
  description?: string
  type?: 'string' | 'number' | 'boolean' | 'enum'
  required: boolean
  defaultValue?: string
  options?: string[]
}

type PromptInputSlot = {
  id: string
  type: 'text' | 'messages' | 'image' | 'images' | 'variables' | 'custom'
  label?: string
  required?: boolean
  description?: string
  accepts?: string[]
  metadata?: Record<string, unknown>
}

type PromptOutputSpec = {
  id: string
  kind: 'text' | 'message' | 'image' | 'images' | 'json' | 'custom'
  label?: string
  description?: string
  metadata?: Record<string, unknown>
}

约束:

  • 变量定义属于 contract。
  • 变量值属于运行输入或示例输入。
  • defaultValue 是模板级默认值,不等于某次运行时用户填入的变量值。
  • 图片输入输出统一通过 PromptImageRef 引用。

4.3 PromptImageRef

type PromptImageRef =
  | { kind: 'url'; url: string }
  | { kind: 'asset'; assetId: string }

持久化结构优先使用 kind: 'asset'kind: 'url' 只作为外部来源或兜底引用。metadata 中不应长期保存 inline base64 / data URL。


5. PromptAsset

PromptAsset 是长期提示词资产。收藏只是资产的一个入口。

type PromptAsset = {
  schemaVersion: 'prompt-model/v1'

  id: string
  title: string
  description?: string
  tags: string[]
  category?: string

  contract: PromptContract

  currentVersionId: string
  versions: PromptContentVersion[]

  examples: PromptExample[]
  source?: PromptSourceRef
  createdAt: number
  updatedAt: number
  metadata?: Record<string, unknown>
}

type PromptContentVersion = {
  id: string
  version: number
  content: PromptContent
  createdAt: number
  updatedAt?: number
  source?: PromptSourceRef
  metadata?: Record<string, unknown>
}

约束:

  • asset 是长期结构session 是运行态结构。
  • versions 只追踪资产正文演化。
  • 测试输入、变量值、模型输出、reasoning 不进入正文版本链。
  • 旧收藏没有版本链时normalize 层可以合成一个只读初始版本。

5.1 PromptExample

type PromptExample = {
  id: string
  title?: string
  description?: string
  basedOnVersionId: string

  input: PromptRunInput
  output?: PromptRunOutput
  metadata?: Record<string, unknown>
}

type PromptRunInput = {
  text?: string
  messages?: ConversationMessage[]
  parameters?: Record<string, string>
  images?: PromptImageRef[]
  metadata?: Record<string, unknown>
}

type PromptRunOutput = {
  text?: string
  images?: PromptImageRef[]
  metadata?: Record<string, unknown>
}

约束:

  • example 是长期可复现示例,不是一次临时测试运行。
  • basedOnVersionId 是兼容当前模型的来源 / revision 线索,不表示示例必须绑定到当前资产正文版本,也不能作为追加示例前的正文一致性门禁。
  • example 可以记录输入输出,但不参与资产正文版本链。

6. PromptSession

PromptSession 是工作区运行态。一个 session 可以还没有保存为 asset也可以绑定到一个 asset。

type PromptSession = {
  schemaVersion: 'prompt-model/v1'
  id: string
  title?: string

  modeKey: PromptModeKey
  lifecycle: 'implicit' | 'active' | 'background' | 'closed' | 'archived'
  createdAt: number
  updatedAt: number

  assetBinding?: PromptAssetBinding
  draft?: PromptAssetDraft
  optimization: PromptOptimizationChain
  testRuns: PromptTestRunSet[]

  origin?: PromptSessionOrigin
  ui?: Record<string, unknown>
  metadata?: Record<string, unknown>
}

type PromptAssetBinding = {
  assetId: string
  versionId?: string
  status?: 'linked' | 'forked' | 'detached'
}

type PromptAssetDraft = {
  title?: string
  description?: string
  content: PromptContent
  variables?: PromptVariable[]
  metadata?: Record<string, unknown>
}

type PromptSessionOrigin =
  | { kind: 'blank'; id?: string; metadata?: Record<string, unknown> }
  | { kind: 'workspace'; id?: string; metadata?: Record<string, unknown> }
  | { kind: 'asset'; id?: string; metadata?: Record<string, unknown> }
  | { kind: 'favorite'; id?: string; metadata?: Record<string, unknown> }
  | { kind: 'history'; id?: string; metadata?: Record<string, unknown> }
  | { kind: 'garden'; id?: string; metadata?: Record<string, unknown> }
  | { kind: 'import'; id?: string; metadata?: Record<string, unknown> }
  | { kind: 'external'; id?: string; metadata?: Record<string, unknown> }

约束:

  • assetBinding 为空表示未保存草稿。
  • 一个 session 最多绑定一个 asset。
  • 保存/收藏后session 继续存在,只是绑定到持久化 asset。
  • 清空工作区应视为创建新 session而不是原地覆盖旧 session。

6.1 PromptSessionRegistry

type PromptSessionRegistry = {
  schemaVersion: 'prompt-model/v1'
  activeSessionId?: string
  activeSessionIdByMode: Partial<Record<PromptModeKey, string>>
  sessions: PromptSessionSummary[]
  updatedAt: number
  metadata?: Record<string, unknown>
}

type PromptSessionSummary = {
  id: string
  modeKey: PromptModeKey
  title?: string
  lifecycle: 'implicit' | 'active' | 'background' | 'closed' | 'archived'
  updatedAt: number
  assetBinding?: PromptAssetBinding
  origin?: PromptSessionOrigin
  metadata?: Record<string, unknown>
}

说明:

  • registry 管理“有哪些会话”和“当前激活哪个会话”。
  • activeSessionIdByMode 保留当前产品“每个模式切回来能恢复上次状态”的体验。
  • 当前 session/v1/{modeKey} 可以先映射成 implicit session例如 implicit:basic-system

当前实现说明:

  • 产品层暂未暴露 session registry UI用户仍感知为现有工作区和模式切换。
  • 7 个现有子模式 session store 已增加内部 assetBinding / origin,用于记录“当前工作区来自哪个收藏 / 资产版本”。
  • PromptSessionRegistry 当前主要是标准投影能力,不是新的持久化多会话主存储。
  • pro-conversation 的显式 session 生命周期以后再设计;当前只在标准投影和收藏应用层映射到 pro-multi

7. PromptOptimizationChain

PromptOptimizationChain 是 session 内的优化链。

type PromptOptimizationChain = {
  id: string
  modeKey: PromptModeKey
  root: PromptRootSnapshot
  records: PromptOptimizationRecord[]
  currentRecordId?: string
  target?: PromptOptimizationTarget
  legacyPromptRecordChainId?: string
  metadata?: Record<string, unknown>
}

type PromptRootSnapshot = {
  id: string
  content: PromptContent
  createdAt: number
  sourceRecordId?: string
  metadata?: Record<string, unknown>
}

type PromptOptimizationRecord = {
  id: string
  type: PromptRecordType
  version: number
  input: PromptContent
  output: PromptContent
  previousRecordId?: string
  modelKey: string
  modelName?: string
  templateId?: string
  iterationNote?: string
  createdAt: number
  sourceRecordId?: string
  metadata?: Record<string, unknown>
}

type PromptOptimizationTarget =
  | { kind: 'prompt'; id?: string; label?: string; metadata?: Record<string, unknown> }
  | { kind: 'message'; id?: string; role?: string; label?: string; metadata?: Record<string, unknown> }
  | { kind: 'image-prompt'; id?: string; label?: string; metadata?: Record<string, unknown> }
  | { kind: 'custom'; id?: string; label?: string; metadata?: Record<string, unknown> }

约束:

  • chain 必须有 root。
  • records 可以为空。
  • root-only chain 可以直接用于测试和保存。
  • 点击“优化”创建新的 session 和新的 chain。
  • 点击“迭代/继续优化”向当前 chain 追加 iterate record。
  • PromptRecordChain 只作为兼容来源,可适配为 PromptOptimizationChain

8. PromptTestRun

PromptTestRun 是 session 中的一次测试运行。

type PromptTestRunSet = {
  id: string
  createdAt: number
  updatedAt?: number
  runs: PromptTestRun[]
  metadata?: Record<string, unknown>
}

type PromptTestRun = {
  id: string
  revision: PromptRevisionRef
  input: PromptRunInput
  output?: PromptRunOutput
  status: 'success' | 'error'
  modelKey?: string
  modelName?: string
  createdAt: number
  durationMs?: number
  error?: string
  metadata?: Record<string, unknown>
}

type PromptRevisionRef =
  | { kind: 'root'; chainId: string }
  | { kind: 'record'; chainId: string; recordId: string; version?: number }
  | { kind: 'workspace'; sessionId?: string }
  | { kind: 'asset-version'; assetId: string; versionId: string }

说明:

  • 测试原始提示词时,revision.kind = 'root'
  • 测试某次优化/迭代结果时,revision.kind = 'record'
  • 测试当前编辑器未保存内容时,revision.kind = 'workspace'
  • 多列测试形成一个 PromptTestRunSet
  • 用户保存测试结果时,才从 PromptTestRun 转成 PromptExample

9. 外部来源

type ExternalSourceSnapshot = {
  provider: 'prompt-garden' | 'manual-import' | string
  externalId?: string
  importedAt: string
  raw?: Record<string, unknown>
}

约束:

  • Prompt Garden 只是外部来源之一。
  • 外部来源快照只用于追溯,不是内部主模型。
  • 编辑、保存、追加示例时,只更新内部 asset/session不反写外部 raw snapshot。

10. 操作语义

本节描述目标语义。当前产品阶段采用“无感 session”

  • 不新增用户可见的新建、切换、关闭 session 入口。
  • 从收藏 / PromptAsset 加载工作区时,记录 assetBindingorigin
  • workspace 测试仍标记为 revision.kind = 'workspace';如果工作区来自某个 asset/version则把绑定信息放在 run/example metadata 中,而不是把它伪装成不可变 asset version 测试。
  • 保存测试结果为示例时,通过 reproducibilityDraft 走收藏保存链路,不在 UI 表单里手写 metadata.promptAsset
  • 测试结果保存为示例时,目标是提示词资产 / 收藏;来源坐标只用于默认选择和追溯,不要求当前 workspace 正文与目标资产当前版本正文严格一致。
操作 标准语义
新建会话 创建新的 session、draft 和 root-only chain
点击优化 创建新的 session 和 chainroot 为点击时的原始提示词,成功后追加第一条 optimize record
点击迭代 在当前 session 的当前 chain 中追加 iterate record
测试原始提示词 生成 revision.kind = root 的 test run
测试优化结果 生成 revision.kind = record 的 test run
保存资产 从 session draft、root 或 record 生成 asset/content version
保存测试结果 从 test run 生成 asset example
打开资产 优先恢复绑定该 asset 的 session没有则从 asset 创建 session
从历史继续 从 legacy history chain/record 创建 session
关闭会话 归档/丢弃运行态,不删除已保存 asset

11. 兼容策略

11.1 FavoritePrompt

当前 FavoritePrompt 继续作为持久化容器和兼容入口。

FavoritePrompt {
  content: string
  functionMode: 'basic' | 'context' | 'image'
  optimizationMode?: 'system' | 'user'
  imageSubMode?: 'text2image' | 'image2image' | 'multiimage'
  metadata?: {
    promptAsset?: PromptAsset
    reproducibility?: unknown
    gardenSnapshot?: unknown
    variables?: unknown
    examples?: unknown
    [key: string]: unknown
  }
}

读取优先级:

  1. metadata.promptAsset
  2. 当前可复现 metadata
  3. Garden / external source snapshot
  4. legacy metadata variables/examples
  5. FavoritePrompt 基础字段

写入原则:

  • 新结构优先写 metadata.promptAsset
  • FavoritePrompt.content 保留为正文文本 fallback。
  • legacy 字段只读兼容,除非执行显式迁移。
  • 不把内部结构写回 Garden raw snapshot。

11.2 PromptRecordChain

PromptRecordChain 可适配到 PromptOptimizationChain

  • chain.versions[0].originalPromptroot.content
  • 每个 PromptRecordPromptOptimizationRecord
  • record.idrecord.id
  • record.previousIdpreviousRecordId
  • record.optimizedPromptoptimizedContent
  • record.metadatametadata

但目标模型不再要求 chain 必须有优化输出。root-only 是合法状态。

11.3 session/v1

session/v1/{modeKey} 可先作为 implicit session

  • session/v1/basic-systemimplicit:basic-system
  • session/v1/basic-userimplicit:basic-user
  • session/v1/pro-variableimplicit:pro-variable
  • session/v1/pro-multiimplicit:pro-conversation
  • session/v1/image-* → 对应 image implicit session

第一阶段可以先做 normalize不必立刻替换 Pinia store。

当前实现已经在这些 implicit session 中持久化内部 assetBinding / origin。它们只用于来源坐标和 revision metadata不代表用户已经有显式 session 管理功能。


12. 设计约束

  1. 新模型使用 basic | pro | image,不使用旧 context
  2. basic 只有 system | user 子模式。
  3. pro 只有 variable | conversation 子模式。
  4. 一个 session 有且只有一条主 optimization chain。
  5. 一个 session 最多绑定一个 asset。
  6. asset 可以被多个 session 派生或继续编辑。
  7. root-only chain 是合法状态。
  8. test run 属于 sessionexample 属于 asset。
  9. content version 只记录资产正文演化。
  10. 变量定义属于 contract变量值属于 run/example input。
  11. 外部来源是 source snapshot不是内部主模型。
  12. 持久化 metadata 不应包含 inline image data URL。