# AI VOC 洞察生命周期审计 > 审计范围:`E:\workspace\Saas-voc` 前端与 `E:\workspace\server\saas-voc-server` 后端。 > 审计对象:反馈收件箱、AI VOC 洞察、行动创建面板、`SaasPlatformService`、后端 `AnalysisRun` / `Action` 路由与本地仓储。 > 审计时间:2026-08-06 ## 1. 结论摘要 当前系统已经形成一条可运行的 VOC 工作流: ```text 真实评价 -> 证据准备与筛选 -> AI 结构化洞察 / deterministic 规则摘要 -> 用户查看原始证据并提交行动表单 -> ActionItem 进入行动中心 ``` 其中,证据回跳、证据 ID 校验、`needs_validation` 标记、AnalysisRun 持久化状态和 Action 创建审计已经具备。当前的“人工确认”由用户查看洞察后主动打开并提交“创建行动项”面板来体现,但还不是一个可查询、可审计、可阻断后续动作的独立业务状态。 因此当前实现适合表达“生成结果并由人决定是否转行动”,还不适合表达完整的“洞察发布、行动执行、效果验证、结果回流”闭环。 ## 2. 当前已实现的证据到行动链路 ### 2.1 证据进入分析上下文 `ai-voc-insight` 通过 `AiVocInsightService.prepare(...)` 对数据集中的有效评价进行准备: - 按本品、竞品或全部范围筛选; - 按负向、中性或正向倾向筛选; - 按样本上限截取输入; - 为每条评价生成稳定的证据 ID,并保留评价正文、商品、来源、评分、日期和主题; - 生成样本量、来源分布、情感分布和主题分布,作为分析输入审计信息。 `feedback-inbox` 提供同一类评价的队列和详情视图。详情页保留原始评价正文、主题判断、同类样本量、来源类型、置信表达和处理建议;证据链接通过 `reviewId` 回到收件箱详情。 ### 2.2 AnalysisRun 记录生成过程 点击生成后,前端先调用: ```text POST /workspaces/:workspaceId/analyses ``` 请求类型为 `analysisType: voc_insight`,目标为当前 workspace,并把筛选条件、输入证据 ID、主题统计、样本数和来源/情感统计写入 `input`。后端创建记录时状态为 `pending`,接口返回 `202`。 随后前端用: ```text PATCH /workspaces/:workspaceId/analyses/:id ``` 把运行推进到 `processing`,生成结束后再写入 `result`、`evidenceCount`、终态和时间戳。后端上下文能力明确声明 `analysisExecution: false`,所以当前 AnalysisRun 是生成过程的持久化记录,实际 AI 执行仍由前端调用 AI 网关完成。 ### 2.3 AI 结果形成结构化洞察 AI 输入携带 `evidenceId`,提示约束要求每条洞察引用输入中的真实 ID,并输出: - 发现、用户未满足需求和建议动作; - 严重程度、置信度和机会状态; - `evidenceIds`、`evidenceCount` 和验证指标; - 风险与后续追问。 AI 返回结果会再次解析和归一化:未知证据 ID 会被过滤,没有有效证据引用的洞察会被丢弃;如果没有可验证洞察、请求超时或网关异常,则从同一输入生成 deterministic 规则摘要并明确标记为待验证。前端展示引用数量和每个证据 ID,并可跳回 `feedback-inbox` 查看原始评价。 ### 2.4 人工确认与行动创建 当前 UI 的人工决策路径是: 1. 用户在洞察卡片中查看发现、用户需求、机会状态、风险、验证指标和引用证据; 2. 用户点击“创建行动项”,打开 `action-create-panel`; 3. 面板预填洞察标题和描述,描述包含洞察发现、建议动作、验证指标和 AI 路径的证据 ID; 4. 用户可以修改标题、描述、优先级、负责人和截止日期; 5. 用户提交表单后调用: ```text POST /workspaces/:workspaceId/actions ``` 6. 后端要求 `action:write` 权限,校验负责人是 workspace 内的 active 成员,创建 `ActionItem`,初始状态默认为 `open`,并记录 `action.created` 审计事件。 `feedback-inbox` 也能从单条反馈直接创建行动草稿,并把原始反馈和主题上下文带入面板。前端用本地 `createdActionIds` 防止当前页面重复点击,但该集合不是后端关联关系。 需要特别区分:页面文案中的“已确认”与正式确认状态不是同一件事。当前没有 `confirmedBy`、`confirmedAt`、确认意见或洞察决策接口;用户提交 ActionItem 可以视作一次显式的人为转行动决定,但这次决定没有作为独立记录保存。 ## 3. AnalysisRun 状态语义 后端 `AnalysisRun` 的状态转移和字段约束如下: | 状态 | 语义 | 当前进入方式 | 关键约束 | | --- | --- | --- | --- | | `pending` | 请求已创建,等待生成开始 | `POST /analyses` 创建后的初始状态 | 没有结果,未开始处理 | | `processing` | 生成正在进行 | 前端 PATCH 状态;若未提供 `startedAt`,后端自动补时间 | 只能从 `pending` 进入;前端负责实际生成 | | `completed` | AI 结果完整完成 | AI 结果成功解析并写入 | 必须有 `result`;终态不可再次 PATCH | | `partial` | 有结果但需要人工复核,当前主要用于 deterministic fallback | 规则摘要写入结果 | 必须有 `result`;终态不可再次 PATCH | | `failed` | 本次生成没有可用结果 | AI 请求、解析或持久化流程报告失败 | 必须有非空 `errorSummary`;终态不可再次 PATCH | | `cancelled` | 运行被取消 | 后端允许从 `pending` 或 `processing` 取消 | 当前没有前端取消控件;终态不可再次 PATCH | 允许的状态转移是: ```text pending -> processing | cancelled | failed processing -> completed | partial | failed | cancelled completed -> terminal partial -> terminal failed -> terminal cancelled -> terminal ``` 后端还会自动补齐:进入 `processing` 时的 `startedAt`,以及进入任意终态时的 `completedAt`。GET 列表支持按状态筛选和游标分页;前端只恢复 `voc_insight`、当前 workspace 且状态为 `completed` 或 `partial` 并且有结果的运行。 当前 `local-platform.repository` 使用进程内数组保存 AnalysisRun 和 ActionItem,服务重启后记录会丢失;Parse REST / Postgres 仓储具备持久化实现。该差异必须在本地演示和验收环境中明确标注。 ## 4. AI 与 deterministic fallback 的区别 ### AI 模式 - AI 网关状态为已配置时,由 `AiVocInsightService.generate(...)` 调用 `AiAnalysisService.streamAnalysis(...)`; - 输出要求为结构化 JSON,并经过 JSON 提取、字段归一化和证据 ID 校验; - 结果 `mode` 为 `ai`,前端将 AnalysisRun 写成 `completed`; - AI 可以输出 `supported`、`partially_supported`、`needs_validation` 或 `not_supported`,但最终仍需人工判断; - 生成内容只能把当前输入评价当作事实证据,不得凭空补充销量、金额、比例或原话。 ### deterministic fallback 模式 当 AI 网关未配置,或 AI 请求、解析发生异常时,系统按固定主题规则聚合当前证据: - 以主题分组并生成规则摘要; - 每条摘要保留可回溯的证据 ID; - 所有机会状态设为 `needs_validation`; - 同时给出样本外推风险和后续补证问题; - 结果 `mode` 为 `deterministic`,前端将 AnalysisRun 写成 `partial`,并提示人工复核后再转行动。 deterministic fallback 是可解释的可用性降级,属于规则层信号;主题命中仍需人工复核,尚不足以表达总体问题率或已确认机会。 ## 5. 三条业务不变量 以下三条不变量是当前链路必须保持的业务契约。现状中的“已实现”与“仍需补强”分别列出,避免把 UI 行为误当成后端保证。 ### 不变量一:证据 ID 必须可回溯 **规则:** 每条洞察的 `evidenceIds` 必须是本次分析上下文 `evidence[].id` 的子集;每个引用都能回到反馈收件箱的原始评价;`evidenceCount` 和覆盖率只能基于实际引用 ID 计算。 **现状:** AI 提示词要求真实 ID,结果归一化会过滤未知 ID,并丢弃没有有效引用的洞察;规则摘要也保留真实 ID。前端提供引用链接和证据回跳。 **缺口:** ActionItem 没有 `analysisId`、`insightId` 或 `evidenceIds` 字段。AI 创建行动时证据 ID 会进入描述文本,收件箱直接创建行动时主要带入原始反馈文本,因此数据库层还没有强引用约束。 ### 不变量二:`needs_validation` 与已确认机会保持区分 **规则:** 样本不足、规则降级、主题边界不确定或证据覆盖不足的洞察必须保持 `needs_validation`;此状态只触发补证、人工复核或带验证指标的草稿,正式发布前需要显式确认。 **现状:** deterministic 结果统一使用 `needs_validation`;AI 缺失或非法机会状态时归一化默认使用 `needs_validation`;结果页展示“待验证”标签和验证指标。 **缺口:** 当前 `openAction(...)` 没有根据 `opportunityStatus` 阻断操作,用户仍可以直接为 `needs_validation` 洞察创建 ActionItem;后端也没有对结果内容或样本阈值做服务端校验。 ### 不变量三:行动前必须有可审计的人工确认 **规则:** 只有用户查看了证据并明确确认洞察成立、确认验证目标和行动责任后,才允许创建可执行行动;确认人、时间、决策和意见必须可查询,并写入审计。 **现状:** 创建行动前必须经过用户点击和表单提交;后端用 `action:write` 权限保护创建接口,并记录 `action.created`。这能阻止纯展示状态自动创建行动。 **缺口:** 当前没有独立的确认 API 或确认字段,尚未区分“确认”“驳回”“需要补充证据”;也缺少用户完成证据审阅的可验证记录。行动创建本身是隐式确认,且对 `needs_validation` 没有统一阻断。 ## 6. 尚缺的闭环能力 ### 6.1 行动效果回流 当前 `ActionItem` 只有执行状态、负责人、优先级、截止时间和完成时间,没有以下对象或字段: - 关联的 `analysisRunId`、`insightId`、`evidenceIds`; - 行动目标、验证指标、基线值、目标值和观测窗口; - 执行后的观测值、效果结论、验证人和验证时间; - “有效、部分有效、无效、未测量”等效果状态; - 从效果结果回写洞察置信度、机会状态或下一轮 AnalysisRun 的机制。 所以当前链路止于“行动已创建/执行状态变化”,还没有“行动是否解决了用户问题”的证据闭环。 ### 6.2 洞察发布生命周期 AnalysisRun 的 `completed` / `partial` 是计算运行状态,不是洞察的业务发布状态。当前不存在独立 Insight 实体或版本对象,也没有: ```text draft -> confirmed -> published -> archived ``` 所需的发布人、发布时间、版本号、确认意见、归档原因、回滚关系和跨页面可见性策略。当前历史列表只能恢复有结果的 AnalysisRun,尚未表达某条洞察是否已被正式发布给产品、运营或管理层。 ## 7. 下一轮验收标准 ### P0:形成可审计、可阻断的闭环 1. **洞察与证据强关联** - Given 一次 `voc_insight` AnalysisRun,When 结果保存,Then 每条洞察只能引用该运行输入中的证据 ID,服务端拒绝未知 ID、空引用和跨运行引用。 - Given 从洞察创建行动,Then ActionItem 至少保存 `analysisRunId`、`insightId` 和去重后的 `evidenceIds`,页面仍可从行动跳回原始评价。 2. **人工确认成为显式门槛** - Given 洞察状态为 `needs_validation` 或 deterministic fallback,When 用户未提交确认,Then创建行动请求被 UI 和 API 双重阻断。 - Given 用户完成证据审阅,Then可提交 `confirmed`、`rejected` 或 `needs_more_evidence` 决策,并保存 `confirmedBy`、`confirmedAt`、确认说明及审计事件。 - Given 洞察已经确认,Then 创建行动必须携带确认记录 ID;确认记录不可被静默覆盖。 3. **AnalysisRun 执行契约稳定** - Given 同一生成请求发生刷新、重试或网络延迟,Then 应保持单一有效运行和单次终态写入;运行完成后只允许一次终态提交。 - Given AI 成功,Then状态为 `completed` 且 `result` 可恢复;Given deterministic fallback,Then状态为 `partial` 且结果中明确 `mode: deterministic` 和 `needs_validation`。 - Given 生成失败,Then状态为 `failed` 且有可读 `errorSummary`;终态之后的 PATCH 必须被拒绝。 4. **行动效果可回流** - Given ActionItem 被标记完成,Then必须有验证指标、观测窗口和效果记录,或明确记录“未测量”的原因。 - Given 效果记录提交,Then可以按行动、洞察、主题和时间范围查询,并生成下一轮分析的输入。 ### P1:建立洞察资产的发布与运营能力 1. **独立洞察发布生命周期** - Given AnalysisRun 产生结果,Then生成一个带版本号的洞察草稿,而不是直接把运行结果当作发布资产。 - Only confirmed 洞察可进入 `published`;已发布版本不可被原地覆盖,修改必须生成新版本。 - Given 洞察归档,Then保留归档人、归档时间、原因和历史版本,并能恢复指定版本。 2. **历史、行动和效果一体化视图** - 可按洞察查看证据、确认记录、关联行动、执行状态和效果结果; - 可按主题查看多次 AnalysisRun 的趋势,区分 AI、规则降级和人工修订版本; - 页面刷新、跨页面跳转和权限变化后,仍能恢复同一洞察上下文。 3. **质量与回归评估** - 为证据引用正确率、`needs_validation` 识别率、人工确认通过率、行动完成率和效果回流完整率建立可重复测试; - AI 输出和 deterministic fallback 使用同一套 schema 校验、引用校验和审计断言; - 对低样本、无证据、未知证据 ID、网关超时、重复提交和终态修改建立自动化验收用例。 ## 8. 审计依据 - 前端:`src/modules/feedback-inbox/feedback-inbox.component.ts`、`feedback-inbox.component.html`; - 前端:`src/modules/ai-voc-insight/ai-voc-insight.component.ts`、`ai-voc-insight.component.html`、`ai-voc-insight.service.ts`、`ai-voc-insight.models.ts`; - 前端:`src/modules/shared/components/action-create-panel/action-create-panel.component.ts`、`action-create-panel.component.html`; - 前端:`src/app/core/services/saas-platform.service.ts`; - 后端:`src/modules/saas-platform/domain.ts`、`routes.ts`、`local-platform.repository.ts`; - 后端:`src/modules/saas-platform/parse-rest-voc.repository.ts`、`postgres-platform.repository.ts` 中 AnalysisRun / Action 的持久化实现。