From e179abd0e5983f86a24aef08d202db338a0bf97a Mon Sep 17 00:00:00 2001 From: MerCry Date: Mon, 2 Mar 2026 22:14:02 +0800 Subject: [PATCH] spec: add metadata-governance module specification [AC-IDSMETA-13~22] --- .../data-decomposition-methodology.md | 214 ++++ spec/intent-driven-script/design.md | 792 ++++++++++++ .../requirements-metadata-governance.md | 202 +++ spec/intent-driven-script/requirements.md | 421 ++++++ spec/intent-driven-script/scope.md | 118 ++ spec/intent-driven-script/tasks.md | 1126 +++++++++++++++++ spec/metadata-governance/design.md | 104 ++ spec/metadata-governance/openapi.deps.yaml | 48 + .../metadata-governance/openapi.provider.yaml | 329 +++++ spec/metadata-governance/requirements.md | 87 ++ spec/metadata-governance/scope.md | 20 + spec/metadata-governance/tasks.md | 41 + 12 files changed, 3502 insertions(+) create mode 100644 spec/intent-driven-script/data-decomposition-methodology.md create mode 100644 spec/intent-driven-script/design.md create mode 100644 spec/intent-driven-script/requirements-metadata-governance.md create mode 100644 spec/intent-driven-script/requirements.md create mode 100644 spec/intent-driven-script/scope.md create mode 100644 spec/intent-driven-script/tasks.md create mode 100644 spec/metadata-governance/design.md create mode 100644 spec/metadata-governance/openapi.deps.yaml create mode 100644 spec/metadata-governance/openapi.provider.yaml create mode 100644 spec/metadata-governance/requirements.md create mode 100644 spec/metadata-governance/scope.md create mode 100644 spec/metadata-governance/tasks.md diff --git a/spec/intent-driven-script/data-decomposition-methodology.md b/spec/intent-driven-script/data-decomposition-methodology.md new file mode 100644 index 0000000..86c2dff --- /dev/null +++ b/spec/intent-driven-script/data-decomposition-methodology.md @@ -0,0 +1,214 @@ +# 多知识库与数据拆解方法论(用于 Intent-Driven Script 系统) + +## 1. 当前落地建议(先执行) + +### 1.1 建议创建的知识库数量与定位 +建议先建 **4 个核心知识库 + 1 个兜底库(可选)**: + +1. **KB_PRODUCT(product)课程产品库** + - 放什么:课程模块、年级适配、学科能力点、学习路径、阶段价值 + - 不放什么:退款政策、隐私条款、运营口径说明 + +2. **KB_PARENT_COMM(script/general)家长沟通素材库** + - 放什么:家长痛点表达、共情语料、自然过渡语、解释型话术素材 + - 不放什么:硬规则、流程跳转条件 + +3. **KB_FAQ(faq)高频问答库** + - 放什么:价格、班型、课时、上课形式、效果周期等标准问答 + - 不放什么:长篇教育理念、复杂诊断内容 + +4. **KB_POLICY(policy)合规与边界库** + - 放什么:承诺边界、敏感词、隐私说明、不可承诺清单 + - 不放什么:销售话术素材 + +5. **KB_GENERAL(general,可选)兜底知识库** + - 放什么:跨场景通识内容、无法明确归属但需保留的信息 + - 不放什么:高频关键知识(应尽量归入前 4 库) + +--- + +### 1.2 标签(metadata)统一规范 +为保证多库检索稳定,所有文档建议统一至少包含以下 metadata: + +- `grade`: `7|8|9|all` +- `subject`: `chinese|math|english|physics|chemistry|all` +- `scene`: `pain_point|transition|module_intro|faq|policy|closing` +- `flow_step`: `step1|step2|step3|step4|step5|none` +- `intent_type`: `ask_grade|ask_weak_point|module_recommend|next_action|faq_answer|compliance` +- `audience`: `parent|student|all` +- `priority`: `1-10` +- `version`: 语义版本,如 `v1.0.0` +- `status`: `draft|active|deprecated` +- `source`: 数据来源(运营、教研、历史会话等) + +建议附加字段: +- `keywords`: 关键词数组 +- `effective_from` / `effective_to`: 生效周期 +- `owner`: 责任人或团队 + +--- + +### 1.3 检索路由(必须配置) +采用“**意图命中 -> 指定库检索 -> metadata 过滤**”,避免全库盲检索。 + +示例: +- 课程咨询/薄弱点诊断 -> `KB_PRODUCT + KB_PARENT_COMM`,过滤 `grade + subject + flow_step` +- 价格/班型问答 -> `KB_FAQ` +- 效果承诺/隐私/敏感问题 -> `KB_POLICY` +- 无法命中 -> `KB_GENERAL` 兜底 + +--- + +## 2. 数据拆解方法论(给另一个 AI 上下文使用) + +## 2.1 方法目标 +把“原始业务文本/用户话术”稳定拆成以下四类输出: +1. 录入哪个知识库(KB) +2. 是否需要新增意图规则(Intent Rule) +3. 是否进入现有话术流程步骤(Step1-5) +4. 是否必须新建话术流程(New Flow) + +--- + +## 2.2 四层判定框架(L1-L4) + +### L1:内容性质判定(事实 vs 动作) +- 若是“事实、说明、经验、解释” -> 优先 KB +- 若是“出现这句话系统要动作” -> Intent Rule + +### L2:交互形态判定(单轮 vs 多轮) +- 单轮问答可完成 -> FAQ/Fixed/RAG +- 需持续收集槽位并推进 -> Script Flow + +### L3:流程复用判定(旧流程 vs 新流程) +满足以下任一项,建议新建 Flow: +- 业务目标变化(诊断变成转化/挽回/投诉) +- 槽位集合变化(年级+薄弱点变成预算+时间) +- 语气/合规策略显著不同 + +### L4:可执行性判定(是否能被系统消费) +必须结构化到可执行字段: +- 文档:title/content/metadata +- 意图:keywords/patterns/response_type/priority +- 流程步骤:intent/constraints/fallback/expected_variables + +--- + +## 2.3 标准拆解流程(7 步) + +1. **提取实体与槽位** + - 年级、学科、能力点、痛点、目标、约束 +2. **识别触发表达** + - 用户会怎么说(口语化表达) +3. **判断归属层级** + - KB / Intent / Existing Flow / New Flow +4. **拆分原子片段** + - 每段只承载 1 个核心含义,便于检索 +5. **生成 metadata** + - grade/subject/scene/flow_step/intent_type/priority +6. **生成可落库对象** + - API 对象:KB 文档、Intent 规则、Flow Step 配置 +7. **冲突检查** + - 重复意图、优先级冲突、跨库污染、口径冲突 + +--- + +## 2.4 输出模板(给另一个 AI 的固定格式) + +让另一个 AI 严格按下列结构输出: + +```markdown +## A. 归类结论 +- 主归类:KB / Intent / Existing Flow / New Flow +- 次归类:... +- 是否需要新建流程:是/否 + +## B. 理由 +- 业务理由:... +- 技术理由:... + +## C. 落库建议 +### C1. Knowledge Base +- kb_type: ... +- title: ... +- content_chunks: [...] +- metadata: {...} + +### C2. Intent Rules(如需要) +- name: ... +- keywords: [...] +- patterns: [...] +- response_type: fixed|rag|flow|transfer +- priority: ... + +### C3. Script Flow(如需要) +- flow_id/name: ... +- step_no: ... +- script_mode: fixed|flexible|template +- intent: ... +- constraints: [...] +- fallback: ... +- expected_variables: [...] + +## D. 风险与冲突 +- potential_conflicts: [...] +- mitigation: [...] +``` + +--- + +## 2.5 质量门禁(Quality Gate) +每条拆解结果上线前需通过: + +1. **可路由**:意图命中后有明确 response_type +2. **可检索**:metadata 完整(至少 6 个核心字段) +3. **可执行**:Flow 步骤有 fallback +4. **不冲突**:优先级与已有规则不打架 +5. **可维护**:owner、version、status 明确 + +--- + +## 2.6 你当前 5 步流程的映射建议 + +- Step1(确认年级) + - 主要依赖:`KB_PARENT_COMM`(礼貌提问素材) +- Step2(年级特点+过渡) + - 主要依赖:`KB_PRODUCT + KB_PARENT_COMM` +- Step3(确认薄弱点) + - 主要依赖:`KB_PARENT_COMM`(示例化引导) +- Step4(模块介绍+综合价值) + - 主要依赖:`KB_PRODUCT` +- Step5(下一步建议) + - 主要依赖:`KB_PARENT_COMM + KB_FAQ` + +--- + +## 3. 给另一个 AI 的指令模板(可直接复制) + +```text +你是“中台数据拆解器”。 +目标:将输入内容拆成可录入的 Knowledge Base / Intent Rules / Script Flow 配置。 + +请按以下步骤执行: +1) 提取实体:年级、学科、能力点、痛点、目标、约束。 +2) 判断主归类(四选一):KB / Intent / Existing Flow / New Flow。 +3) 若归类为 KB,输出:kb_type、title、chunk 切分、metadata。 +4) 若归类为 Intent,输出:keywords、patterns、response_type、priority。 +5) 若归类为 Existing Flow,输出:对应 step_no、script_mode、intent、constraints、fallback。 +6) 若需要 New Flow,说明触发条件、目标、槽位、成功标准。 +7) 输出风险与冲突检查。 + +输出必须使用固定结构:A归类结论、B理由、C落库建议、D风险与冲突。 +禁止输出泛泛建议,必须给出可直接调用 API 的字段。 +``` + +--- + +## 4. 迭代策略 + +- 第 1 周:先按 4 库上线,跑真实会话 +- 第 2 周:统计命中率、误召回率、fallback 率 +- 第 3 周:仅在“高干扰场景”再拆细分库(如按学科拆) +- 每周:清理 `deprecated` 文档,升级 `version` + +> 原则:先用 metadata 和路由提升质量,再考虑扩大知识库数量。 \ No newline at end of file diff --git a/spec/intent-driven-script/design.md b/spec/intent-driven-script/design.md new file mode 100644 index 0000000..2c28be2 --- /dev/null +++ b/spec/intent-driven-script/design.md @@ -0,0 +1,792 @@ +# 意图驱动话术流程 - 设计文档 + +## 1. 架构概览 + +### 1.1 系统架构图 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 前端配置界面 │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ 模式选择器 │ │ 意图配置表单 │ │ 约束管理器 │ │ +│ └──────────────┘ └──────────────┘ └──────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ HTTP API + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ 后端 API 层 │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ ScriptFlowService (CRUD) │ │ +│ └──────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ FlowEngine (执行引擎) │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ start() / advance() │ │ +│ │ ↓ │ │ +│ │ _generate_step_content() ← 核心扩展点 │ │ +│ │ ├─ fixed: 返回 content │ │ +│ │ ├─ flexible: 调用 ScriptGenerator │ │ +│ │ └─ template: 调用 TemplateEngine │ │ +│ └──────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ┌───────────────┼───────────────┐ + ▼ ▼ ▼ + ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ + │ScriptGenerator│ │TemplateEngine│ │ Orchestrator │ + │ (新增) │ │ (新增) │ │ (LLM调用) │ + └──────────────┘ └──────────────┘ └──────────────┘ +``` + +### 1.2 数据流图 + +``` +用户配置流程 + │ + ├─ 选择 script_mode + │ ├─ fixed: 配置 content + │ ├─ flexible: 配置 intent + constraints + │ └─ template: 配置 content (模板) + │ + ▼ +保存到数据库 (ScriptFlow.steps JSON) + │ + ▼ +执行时加载流程 + │ + ├─ FlowEngine.start() / advance() + │ │ + │ ├─ 获取当前步骤配置 + │ │ + │ ├─ 调用 _generate_step_content() + │ │ │ + │ │ ├─ fixed: 直接返回 content + │ │ │ + │ │ ├─ flexible: + │ │ │ ├─ 构建 Prompt (intent + constraints + history) + │ │ │ ├─ 调用 LLM 生成话术 + │ │ │ └─ 失败时返回 fallback (content) + │ │ │ + │ │ └─ template: + │ │ ├─ 解析模板变量 + │ │ ├─ 调用 LLM 生成变量值 + │ │ └─ 替换模板占位符 + │ │ + │ └─ 返回生成的话术 + │ + ▼ +返回给用户 +``` + +--- + +## 2. 核心模块设计 + +### 2.1 后端:话术生成引擎 + +#### 2.1.1 FlowEngine 扩展 + +**文件位置**: `ai-service/app/services/flow/engine.py` + +**新增方法**: + +```python +async def _generate_step_content( + self, + step: dict, + context: dict, + history: list[dict] +) -> str: + """ + [AC-IDS-03] 根据步骤配置生成话术内容 + + Args: + step: 步骤配置 (包含 script_mode, intent, constraints 等) + context: 会话上下文 (从 FlowInstance.context 获取) + history: 对话历史 (最近 N 轮) + + Returns: + 生成的话术文本 + """ + script_mode = step.get("script_mode", "fixed") + + if script_mode == "fixed": + return step.get("content", "") + + elif script_mode == "flexible": + return await self._generate_flexible_script(step, context, history) + + elif script_mode == "template": + return await self._generate_template_script(step, context, history) + + else: + logger.warning(f"Unknown script_mode: {script_mode}, fallback to fixed") + return step.get("content", "") +``` + +**修改方法**: + +```python +async def start( + self, + tenant_id: str, + session_id: str, + flow_id: uuid.UUID, +) -> tuple[FlowInstance | None, str | None]: + """ + [AC-IDS-05] 修改:启动流程时生成首步话术 + """ + # ... 现有逻辑 ... + + first_step = flow.steps[0] + + # 修改:调用话术生成引擎 + history = await self._get_conversation_history(tenant_id, session_id, limit=3) + first_content = await self._generate_step_content( + first_step, + instance.context, + history + ) + + return instance, first_content +``` + +#### 2.1.2 ScriptGenerator (新增模块) + +**文件位置**: `ai-service/app/services/flow/script_generator.py` + +**职责**: 灵活模式的话术生成逻辑 + +```python +class ScriptGenerator: + """ + [AC-IDS-04] 灵活模式话术生成器 + """ + + def __init__(self, orchestrator): + self._orchestrator = orchestrator + + async def generate( + self, + intent: str, + intent_description: str | None, + constraints: list[str], + context: dict, + history: list[dict], + fallback: str + ) -> str: + """ + 生成灵活话术 + + Args: + intent: 步骤意图 + intent_description: 意图详细说明 + constraints: 话术约束条件 + context: 会话上下文 + history: 对话历史 + fallback: 失败时的 fallback 话术 + + Returns: + 生成的话术文本 + """ + try: + prompt = self._build_prompt( + intent, intent_description, constraints, context, history + ) + + # 调用 LLM,设置 2 秒超时 + response = await asyncio.wait_for( + self._orchestrator.generate(prompt), + timeout=2.0 + ) + + return response.strip() + + except asyncio.TimeoutError: + logger.warning(f"[AC-IDS-05] Script generation timeout, use fallback") + return fallback + + except Exception as e: + logger.error(f"[AC-IDS-05] Script generation failed: {e}, use fallback") + return fallback + + def _build_prompt( + self, + intent: str, + intent_description: str | None, + constraints: list[str], + context: dict, + history: list[dict] + ) -> str: + """ + [AC-IDS-04] 构建 LLM Prompt + """ + prompt_parts = [ + "你是一个客服对话系统,当前需要执行以下步骤:", + "", + f"【步骤目标】{intent}" + ] + + if intent_description: + prompt_parts.append(f"【详细说明】{intent_description}") + + if constraints: + prompt_parts.append("【约束条件】") + for c in constraints: + prompt_parts.append(f"- {c}") + + if history: + prompt_parts.append("") + prompt_parts.append("【对话历史】") + for msg in history[-3:]: # 最近 3 轮 + role = "用户" if msg["role"] == "user" else "客服" + prompt_parts.append(f"{role}: {msg['content']}") + + if context.get("inputs"): + prompt_parts.append("") + prompt_parts.append("【已收集信息】") + for inp in context["inputs"]: + prompt_parts.append(f"- {inp}") + + prompt_parts.extend([ + "", + "请生成一句符合目标和约束的话术(不超过50字)。", + "只返回话术内容,不要解释。" + ]) + + return "\n".join(prompt_parts) +``` + +#### 2.1.3 TemplateEngine (新增模块) + +**文件位置**: `ai-service/app/services/flow/template_engine.py` + +**职责**: 模板模式的变量填充逻辑 + +```python +import re + +class TemplateEngine: + """ + [AC-IDS-06] 模板话术引擎 + """ + + VARIABLE_PATTERN = re.compile(r'\{(\w+)\}') + + def __init__(self, orchestrator): + self._orchestrator = orchestrator + + async def fill_template( + self, + template: str, + context: dict, + history: list[dict] + ) -> str: + """ + 填充模板变量 + + Args: + template: 话术模板(包含 {变量名} 占位符) + context: 会话上下文 + history: 对话历史 + + Returns: + 填充后的话术 + """ + # 提取模板中的变量 + variables = self.VARIABLE_PATTERN.findall(template) + + if not variables: + return template + + # 为每个变量生成值 + variable_values = {} + for var in variables: + value = await self._generate_variable_value(var, context, history) + variable_values[var] = value + + # 替换模板中的占位符 + result = template + for var, value in variable_values.items(): + result = result.replace(f"{{{var}}}", value) + + return result + + async def _generate_variable_value( + self, + variable_name: str, + context: dict, + history: list[dict] + ) -> str: + """ + 为单个变量生成值 + """ + # 先尝试从上下文中获取 + if variable_name in context: + return str(context[variable_name]) + + # 否则调用 LLM 生成 + prompt = f""" + 根据对话历史,为变量 "{variable_name}" 生成合适的值。 + + 对话历史: + {self._format_history(history[-3:])} + + 只返回变量值,不要解释。 + """ + + try: + response = await asyncio.wait_for( + self._orchestrator.generate(prompt), + timeout=1.0 + ) + return response.strip() + except: + return f"[{variable_name}]" # fallback +``` + +--- + +### 2.2 前端:配置界面设计 + +#### 2.2.1 类型定义扩展 + +**文件位置**: `ai-service-admin/src/types/script-flow.ts` + +```typescript +export type ScriptMode = 'fixed' | 'flexible' | 'template' + +export interface FlowStep { + step_id: string + step_no: number + + // 原有字段 + content: string + wait_input: boolean + timeout_seconds?: number + timeout_action?: 'repeat' | 'skip' | 'transfer' + next_conditions?: NextCondition[] + + // 新增字段 + script_mode?: ScriptMode + intent?: string + intent_description?: string + script_constraints?: string[] + expected_variables?: string[] +} + +export const SCRIPT_MODE_OPTIONS = [ + { value: 'fixed', label: '固定话术', description: '话术内容固定不变' }, + { value: 'flexible', label: '灵活话术', description: 'AI根据意图和上下文生成' }, + { value: 'template', label: '模板话术', description: 'AI填充模板中的变量' } +] +``` + +#### 2.2.2 配置表单组件 + +**文件位置**: `ai-service-admin/src/views/admin/script-flow/index.vue` + +**UI 结构**: + +```vue + +``` + +#### 2.2.3 约束管理组件 + +**文件位置**: `ai-service-admin/src/views/admin/script-flow/components/ConstraintManager.vue` + +```vue + + + +``` + +--- + +## 3. 数据模型设计 + +### 3.1 数据库 Schema + +**无需修改表结构**,因为 `script_flows.steps` 已经是 JSON 类型。 + +**现有结构**: +```sql +CREATE TABLE script_flows ( + id UUID PRIMARY KEY, + tenant_id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + description TEXT, + steps JSONB NOT NULL, -- 直接扩展此字段 + is_enabled BOOLEAN DEFAULT TRUE, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); +``` + +**扩展后的 steps JSON 示例**: +```json +[ + { + "step_no": 1, + "script_mode": "flexible", + "intent": "获取用户姓名", + "intent_description": "礼貌询问用户姓名", + "script_constraints": ["必须礼貌", "语气自然"], + "content": "请问怎么称呼您?", + "wait_input": true, + "timeout_seconds": 60 + } +] +``` + +### 3.2 向后兼容策略 + +**读取时**: +```python +def _normalize_step(step: dict) -> dict: + """确保步骤配置包含所有必需字段""" + return { + "script_mode": step.get("script_mode", "fixed"), + "intent": step.get("intent"), + "intent_description": step.get("intent_description"), + "script_constraints": step.get("script_constraints", []), + "expected_variables": step.get("expected_variables", []), + **step # 保留其他字段 + } +``` + +**写入时**: +- 前端默认 `script_mode = 'fixed'` +- 后端不做强制校验,允许字段缺失 + +--- + +## 4. 技术决策 + +### 4.1 为什么选择 JSON 扩展而不是新表? + +**决策**: 在现有的 `steps` JSON 字段中扩展,而不是创建新表 + +**理由**: +1. **简化数据模型**: 步骤配置是流程的一部分,不需要独立管理 +2. **避免数据迁移**: 无需修改表结构,现有数据自动兼容 +3. **灵活性**: JSON 字段易于扩展,未来可以继续添加新字段 +4. **性能**: 步骤数量通常不多(<20),JSON 查询性能足够 + +**权衡**: 无法对意图字段建立索引,但实际场景中不需要按意图查询流程 + +### 4.2 为什么设置 2 秒超时? + +**决策**: LLM 调用超时设置为 2 秒 + +**理由**: +1. **用户体验**: 对话系统需要快速响应,2 秒是可接受的上限 +2. **Fallback 保障**: 超时后立即返回 fallback 话术,不影响流程执行 +3. **成本控制**: 避免长时间等待消耗资源 + +**权衡**: 可能导致部分复杂话术生成失败,但有 fallback 保障 + +### 4.3 为什么对话历史只取最近 3 轮? + +**决策**: 传递给 LLM 的对话历史限制为最近 3 轮 + +**理由**: +1. **Token 成本**: 减少 Prompt 长度,降低成本 +2. **相关性**: 最近 3 轮对话最相关,更早的对话影响较小 +3. **性能**: 减少数据库查询和网络传输 + +**权衡**: 可能丢失更早的上下文信息,但实际影响有限 + +### 4.4 为什么不缓存生成的话术? + +**决策**: 不对生成的话术进行缓存 + +**理由**: +1. **灵活性优先**: 每次生成都考虑最新的上下文,更符合"灵活话术"的定位 +2. **缓存复杂度**: 需要考虑缓存失效策略(上下文变化、配置变化) +3. **实际收益有限**: 同一步骤在同一会话中通常只执行一次 + +**未来优化**: 如果性能成为瓶颈,可以考虑基于上下文哈希的缓存 + +--- + +## 5. 错误处理与降级策略 + +### 5.1 话术生成失败 + +**场景**: LLM 调用超时或返回错误 + +**处理**: +1. 记录错误日志(包含 tenant_id, session_id, flow_id, step_no) +2. 返回 `step.content` 作为 fallback +3. 在 ChatMessage 中标记 `is_error=False`(因为有 fallback,不算错误) + +### 5.2 配置错误 + +**场景**: flexible 模式但 intent 为空 + +**处理**: +1. 前端校验:提交时检查必填字段 +2. 后端容错:如果 intent 为空,降级为 fixed 模式 + +### 5.3 模板解析错误 + +**场景**: 模板语法错误(如 `{unclosed`) + +**处理**: +1. 捕获正则匹配异常 +2. 返回原始模板(不做替换) +3. 记录警告日志 + +--- + +## 6. 性能考虑 + +### 6.1 预期性能指标 + +| 指标 | 目标值 | 说明 | +|------|--------|------| +| 话术生成延迟 (P95) | < 2s | LLM 调用时间 | +| API 响应时间增加 | < 10% | 相比固定模式 | +| 数据库查询增加 | +1 次 | 获取对话历史 | + +### 6.2 优化策略 + +1. **并行查询**: 获取对话历史和流程配置可以并行 +2. **限制历史长度**: 只查询最近 3 轮对话 +3. **超时控制**: 严格的 2 秒超时,避免长时间等待 + +--- + +## 7. 测试策略 + +### 7.1 单元测试 + +**测试文件**: `ai-service/tests/services/flow/test_script_generator.py` + +**测试用例**: +- 固定模式:直接返回 content +- 灵活模式:正常生成、超时 fallback、异常 fallback +- 模板模式:变量替换、变量缺失、模板语法错误 + +### 7.2 集成测试 + +**测试文件**: `ai-service/tests/api/test_script_flow_intent_driven.py` + +**测试场景**: +1. 创建灵活模式流程 +2. 启动流程,验证首步话术生成 +3. 推进流程,验证后续步骤话术生成 +4. 验证对话历史正确传递 + +### 7.3 端到端测试 + +**测试场景**: +1. 前端配置灵活模式流程 +2. 保存并启用流程 +3. 通过 Provider API 触发流程 +4. 验证生成的话术符合意图和约束 + +--- + +## 8. 部署与发布 + +### 8.1 发布顺序 + +1. **Phase 1**: 后端数据模型和 API 扩展 + - 部署后端代码 + - 验证 API 向后兼容性 + +2. **Phase 2**: 后端话术生成引擎 + - 部署话术生成逻辑 + - 验证 fallback 机制 + +3. **Phase 3**: 前端配置界面 + - 部署前端代码 + - 验证配置保存和加载 + +4. **Phase 4**: 灰度发布 + - 选择部分租户启用灵活模式 + - 监控性能和错误率 + - 全量发布 + +### 8.2 回滚策略 + +**如果出现问题**: +1. 前端回滚:恢复旧版本,用户无法配置灵活模式 +2. 后端回滚:恢复旧版本,灵活模式降级为固定模式 +3. 数据无需回滚:JSON 字段扩展,旧版本可以忽略新字段 + +--- + +## 9. 监控与告警 + +### 9.1 关键指标 + +| 指标 | 说明 | 告警阈值 | +|------|------|---------| +| script_generation_latency | 话术生成延迟 | P95 > 2.5s | +| script_generation_timeout_rate | 超时率 | > 5% | +| script_generation_error_rate | 错误率 | > 1% | +| fallback_usage_rate | Fallback 使用率 | > 10% | + +### 9.2 日志记录 + +**关键日志**: +```python +logger.info( + f"[AC-IDS-03] Generated script: tenant={tenant_id}, " + f"session={session_id}, flow={flow_id}, step={step_no}, " + f"mode={script_mode}, latency={latency_ms}ms" +) + +logger.warning( + f"[AC-IDS-05] Script generation timeout, use fallback: " + f"tenant={tenant_id}, session={session_id}, step={step_no}" +) +``` + +--- + +## 10. 未来扩展 + +### 10.1 短期优化(v1.1) + +- 话术生成缓存(基于上下文哈希) +- 更丰富的约束条件预设 +- 话术效果评估(用户满意度) + +### 10.2 长期规划(v2.0) + +- 多轮对话规划(提前生成后续步骤话术) +- 话术 A/B 测试 +- 基于历史数据的话术优化建议 diff --git a/spec/intent-driven-script/requirements-metadata-governance.md b/spec/intent-driven-script/requirements-metadata-governance.md new file mode 100644 index 0000000..f5f125f --- /dev/null +++ b/spec/intent-driven-script/requirements-metadata-governance.md @@ -0,0 +1,202 @@ +--- +feature_id: "IDSMETA" +title: "多知识库元数据模型与拆解治理(迭代需求)" +status: "draft" +version: "0.2.0" +active_version: "0.1.0-0.2.0" +version_history: + - version: "0.2.0" + ac_range: "AC-IDSMETA-13~22" + description: "基于已上线元数据配置界面的联动增强与治理闭环" + - version: "0.1.0" + ac_range: "AC-IDSMETA-01~12" + description: "建立多知识库元数据配置与数据拆解治理能力" +owners: + - "product" + - "backend" + - "frontend" + - "ops" +last_updated: "2026-03-02" +source: + type: "doc" + ref: "docs/spec-product-zh.md + spec/contracting.md + spec/intent-driven-script/data-decomposition-methodology.md" +--- + +# 多知识库元数据模型与拆解治理(IDSMETA) + +## 1. 背景与目标 + +### 1.1 背景 +当前系统已具备 Knowledge Base / Intent Rules / Script Flow / Prompt Template 的录入能力,并支持灵活话术流程。**元数据配置界面已上线**,但在跨模块复用与检索治理层仍存在缺口: +- 知识录入口径不一致,导致检索命中与召回不稳定 +- 已上线 metadata 配置能力尚未在 KB/Intent/Flow/Prompt 录入链路中完全联动 +- 新增业务文本时,难以稳定判断应录入 KB、Intent、现有 Flow 或新建 Flow +- 多知识库场景下缺少“意图路由 + metadata 过滤”的标准执行策略 + +### 1.2 目标 +- 在现有 metadata 配置界面基础上,补齐字段生命周期治理(draft/active/deprecated) +- 在 KB/Intent/Flow/Prompt 管理界面统一联动 metadata 配置与校验 +- 建立“数据拆解方法论”到系统配置对象的落库闭环 +- 提升多知识库检索准确率与可维护性 + +### 1.3 非目标(Out of Scope) +- 不调整现有 LLM 供应商与模型切换机制 +- 不实现全新的向量引擎或替换 Qdrant +- 不在本迭代内重构既有全部历史数据,仅提供迁移与增量治理方案 + +--- + +## 2. 模块边界(Scope) + +### 覆盖 +- 已上线 Metadata Schema 页面的治理增强(字段状态、弃用策略) +- Admin 录入界面的 metadata 通用组件化联动 +- 多知识库路由策略配置(Intent -> KB + metadata filters) +- 数据拆解结果标准化输出模板(可由运营/AI生成) + +### 不覆盖 +- 具体课程内容生产 +- 运营组织流程(培训/排班) + +--- + +## 3. 依赖盘点(Dependencies) + +- 依赖模块: + - Script Flow(`spec/intent-driven-script/requirements.md`) + - Knowledge Base 文档录入与向量化能力(现有 API) + - Intent Rule 路由能力(现有 API) +- 依赖文档: + - `docs/spec-product-zh.md` + - `spec/contracting.md` + - `spec/intent-driven-script/data-decomposition-methodology.md` + +--- + +## 4. 用户故事(User Stories) + +- [US-IDSMETA-01] 作为运营配置人员,我希望在后台统一配置 metadata 字段与可选值,以便不同模块复用同一套标签标准。 +- [US-IDSMETA-02] 作为话术与知识库管理人员,我希望录入内容时自动显示适配字段并进行校验,以便减少脏数据。 +- [US-IDSMETA-03] 作为系统路由引擎,我希望根据意图自动选择知识库并附加 metadata 过滤,以便提高召回相关性。 +- [US-IDSMETA-04] 作为产品经理,我希望把“拆解方法论”沉淀为标准输出格式,以便在不同 AI 上下文中稳定复用。 + +--- + +## 5. 验收标准(Acceptance Criteria, EARS) + +### 📌 当前活跃版本(v0.2.0) + +#### 5.2 联动增强与治理闭环(v0.2.0) + +### Phase A:已上线元数据界面的能力固化 + +- [AC-IDSMETA-13] WHEN 管理员在元数据配置界面创建或编辑字段 THEN 系统 SHALL 支持字段级状态管理(draft/active/deprecated)并在列表中可筛选。 +- [AC-IDSMETA-14] WHEN 字段状态为 deprecated THEN 系统 SHALL 禁止其在新建对象中被选择,但历史数据仍可读取。 + +### Phase B:跨模块录入联动 + +- [AC-IDSMETA-15] WHEN 在 KB 文档录入页创建/编辑内容 THEN 系统 SHALL 根据知识库类型与 scope 自动渲染 metadata 字段并执行 required 校验。 +- [AC-IDSMETA-16] WHEN 在 Intent Rule、Script Flow、Prompt Template 页面编辑配置 THEN 系统 SHALL 复用统一 metadata 组件并以一致的数据结构保存。 +- [AC-IDSMETA-17] WHEN 页面切换对象类型(如 FAQ -> Product) THEN 系统 SHALL 保留兼容字段值,并对不兼容字段给出“移除/映射”的显式提示。 + +### Phase C:检索路由与运行时治理 + +- [AC-IDSMETA-18] WHEN 命中 Intent Rule 且 response_type=rag THEN 系统 SHALL 按路由策略选择目标知识库集合(支持多库)。 +- [AC-IDSMETA-19] WHEN 进入 RAG 检索 THEN 系统 SHALL 注入会话上下文提取出的 metadata 过滤条件(至少包含 grade、subject、scene)。 +- [AC-IDSMETA-20] WHEN 路由或过滤后无有效召回 THEN 系统 SHALL 执行兜底策略(fallback kb 或固定话术)并记录结构化原因码。 + +### Phase D:方法论落地 + +- [AC-IDSMETA-21] WHEN 运营或 AI 提交“待录入文本” THEN 系统 SHALL 按固定模板输出拆解结果(归类结论、理由、落库建议、风险冲突)。 +- [AC-IDSMETA-22] WHEN 新增或更新拆解模板 THEN 系统 SHALL 保存模板版本并支持查询最近一次生效版本。 + +--- + +### 📦 历史版本(已归档) + +
+v0.1.0:元数据配置能力建立(AC-IDSMETA-01~12) + +- [AC-IDSMETA-01] 元数据配置页面支持字段定义创建(field_key、label、type、required、options、default、scope、is_filterable、is_rank_feature、status)。 +- [AC-IDSMETA-02] 保存字段定义时校验 field_key 全局唯一且仅允许小写字母数字下划线。 +- [AC-IDSMETA-03] enum 或 array(enum) 类型要求 options 非空且无重复。 +- [AC-IDSMETA-04] required 且 scope 命中时,录入保存前执行必填校验并返回字段级错误。 +- [AC-IDSMETA-05] KB 文档录入根据知识库类型展示适用 metadata 字段。 +- [AC-IDSMETA-06] Intent Rule / Script Flow / Prompt Template 支持保存结构化 metadata。 +- [AC-IDSMETA-07] 切换对象类型时保留可兼容字段并提示不兼容处理。 +- [AC-IDSMETA-08] Intent 命中后支持按路由选择目标知识库集合。 +- [AC-IDSMETA-09] RAG 检索支持注入关键 metadata 过滤条件。 +- [AC-IDSMETA-10] 无召回时触发兜底并记录原因日志。 +- [AC-IDSMETA-11] 支持按固定结构输出拆解结果。 +- [AC-IDSMETA-12] 支持拆解模板版本保留与回溯。 + +
+ +--- + +## 6. 数据规范(Metadata Baseline) + +### 6.1 全局建议字段(首批) +- `scene`: pain_point | transition | module_intro | faq | policy | closing +- `priority`: 1-10 +- `status`: draft | active | deprecated +- `version`: 语义版本(如 v1.0.0) +- `owner`: 责任人或团队 + +### 6.2 业务建议字段(首批) +- `grade`: 7 | 8 | 9 | all +- `subject`: chinese | math | english | physics | chemistry | all +- `flow_step`: step1 | step2 | step3 | step4 | step5 | none +- `intent_type`: ask_grade | ask_weak_point | module_recommend | next_action | faq_answer | compliance +- `audience`: parent | student | all + +--- + +## 7. 追踪映射(Traceability) + +| AC ID | Endpoint | 方法 | operationId(建议) | 备注 | +|------|----------|------|---------------------|------| +| AC-IDSMETA-13~14 | /admin/metadata-schemas | POST/PUT/GET | createMetadataSchema/updateMetadataSchema/listMetadataSchemas | 已上线元数据页面能力固化 | +| AC-IDSMETA-15 | /admin/kb/documents | POST/PUT | createKbDocument/updateKbDocument | 文档 metadata 联动校验 | +| AC-IDSMETA-16 | /admin/intent-rules | POST/PUT | createIntentRule/updateIntentRule | 意图规则 metadata 联动 | +| AC-IDSMETA-16 | /admin/script-flows | POST/PUT | createScriptFlow/updateScriptFlow | 流程 metadata 联动 | +| AC-IDSMETA-16 | /admin/prompt-templates | POST/PUT | createPromptTemplate/updatePromptTemplate | 模板 metadata 联动 | +| AC-IDSMETA-18~20 | /chat/completions(内部路由) | POST | routeAndRetrieve | 意图路由 + metadata 检索治理 | +| AC-IDSMETA-21~22 | /admin/data-decomposition/templates | POST/PUT/GET | manageDecompositionTemplate | 拆解模板治理 | + +> 注:如部分端点尚未存在,本迭代需在 `openapi.provider.yaml` 中新增并声明契约成熟度与 AC 追踪。 + +--- + +## 8. 非功能性需求(NFR) + +- [NFR-IDSMETA-01] metadata 校验附加延迟 P95 < 100ms(不含向量检索)。 +- [NFR-IDSMETA-02] 路由+过滤策略命中后,RAG 首包延迟不高于现网基线 +10%。 +- [NFR-IDSMETA-03] 关键链路日志完整(路由决策、过滤条件、fallback 原因)。 +- [NFR-IDSMETA-04] 旧数据兼容:无 metadata 的历史记录仍可读取,按默认策略执行。 + +--- + +## 9. 版本化迭代说明 + +- 当前版本:`v0.2.0`(在已上线 metadata 配置界面基础上的联动增强迭代) +- 后续新增能力按 `docs/spec-product-zh.md` 第 4 节执行: + - 新 AC 编号连续递增 + - 活跃版本最多保留 2 个展开 + - 历史版本折叠归档 + +--- + +## 10. 发布与验收建议 + +### 10.1 里程碑 +- M1:已上线 metadata 界面能力固化(状态管理/弃用策略) +- M2:KB/Intent/Flow/Prompt 四处统一接入 metadata 组件与校验 +- M3:意图路由+metadata 检索与 fallback 日志闭环 +- M4:拆解模板版本治理与回溯能力 + +### 10.2 验收样例(建议) +- 样例 1:录入“初二痛点&方案”,系统输出主归类=KB_PRODUCT,metadata 自动建议(grade=8, scene=pain_point) +- 样例 2:命中“初二成绩下滑怎么办”意图时,路由至 `product + parent_comm` 且过滤 `grade=8` +- 样例 3:字段 `flow_step` 被标记 deprecated 后,不可在新建对象选择,但历史对象仍可展示原值 +- 样例 4:无召回时返回 fallback 并记录 `no_recall_after_metadata_filter` diff --git a/spec/intent-driven-script/requirements.md b/spec/intent-driven-script/requirements.md new file mode 100644 index 0000000..b618259 --- /dev/null +++ b/spec/intent-driven-script/requirements.md @@ -0,0 +1,421 @@ +--- +feature_id: "IDS" +title: "意图驱动话术流程(Intent-Driven Script)需求规范" +status: "draft" +version: "1.0.0" +owners: + - "product" + - "backend" + - "frontend" +last_updated: "2026-02-28" +source: + type: "conversation" + ref: "话术流程配置合理性讨论" +--- + +# 意图驱动话术流程需求规范(IDS) + +## 1. 背景与目标 + +### 1.1 背景 +当前话术流程采用"固定话术"模式,每个步骤配置的 `content` 字段是预设的固定文本。这种模式存在以下问题: +- **缺乏灵活性**:无法根据对话上下文调整话术,显得生硬 +- **意图不明确**:配置中只有"说什么",没有"为什么说" +- **维护成本高**:需要为不同场景配置多个相似的流程 + +实际业务需求是:每个步骤有固定的**目的**(例如"获取用户姓名"),但具体**话术**应该根据上下文灵活调整。 + +### 1.2 目标 +- 支持"意图驱动"的话术生成模式,AI 根据步骤意图和上下文实时生成话术 +- 保持向后兼容,现有固定话术流程不受影响 +- 提供三种话术模式:固定、灵活、模板,满足不同场景需求 +- 前端配置界面支持意图配置和模式切换 + +### 1.3 非目标(Out of Scope) +- 不涉及用户输入的意图识别(已有 IntentRule 模块) +- 不改变流程状态机的核心逻辑 +- 不涉及 LLM 模型选择和切换 +- 不涉及话术生成的性能优化(缓存、预生成等) + +--- + +## 2. 用户故事(User Stories) + +### US-IDS-01: 配置意图驱动的话术步骤 +**作为** 话术流程配置人员 +**我想要** 在配置步骤时指定"意图"而不是固定话术 +**以便** AI 能根据对话上下文灵活生成合适的话术 + +**验收标准**: +- 前端配置界面支持选择话术模式(固定/灵活/模板) +- 灵活模式下可以配置步骤意图、意图说明、话术约束 +- 配置保存后能正确存储到数据库 + +### US-IDS-02: 灵活话术的实时生成 +**作为** 对话系统 +**我想要** 根据步骤意图和对话历史生成话术 +**以便** 提供更自然、更符合上下文的对话体验 + +**验收标准**: +- 执行灵活模式步骤时,调用 LLM 生成话术 +- 生成时考虑步骤意图、约束条件、对话历史 +- 生成失败时有明确的 fallback 机制 + +### US-IDS-03: 向后兼容现有流程 +**作为** 系统管理员 +**我想要** 现有的固定话术流程继续正常工作 +**以便** 不影响已上线的业务 + +**验收标准**: +- 现有流程数据不需要迁移即可正常执行 +- 未指定 script_mode 的步骤默认为 fixed 模式 +- API 响应包含新字段但不破坏现有客户端 + +### US-IDS-04: 模板话术的变量填充 +**作为** 话术流程配置人员 +**我想要** 配置话术模板,让 AI 填充变量部分 +**以便** 在保持话术框架的同时增加灵活性 + +**验收标准**: +- 支持在话术中使用 `{变量名}` 标记 +- AI 根据上下文填充变量 +- 模板语法错误时有明确提示 + +--- + +## 3. 验收标准详细说明(Acceptance Criteria) + +### Phase 1: 数据模型与 API 扩展 + +#### AC-IDS-01: 扩展 ScriptFlow 数据模型 +**优先级**: P0 (MVP 必须) +**描述**: 在 `ScriptFlow.steps` JSON 字段中增加意图驱动相关字段 + +**技术要求**: +- 在 `FlowStep` 类型定义中增加以下字段: + - `intent?: string` - 步骤意图(例如:"获取用户姓名") + - `intent_description?: string` - 意图详细说明 + - `script_mode?: 'fixed' | 'flexible' | 'template'` - 话术模式 + - `script_constraints?: string[]` - 话术约束条件 + - `expected_variables?: string[]` - 期望提取的变量 +- 保持 `content` 字段向后兼容 +- 默认 `script_mode = 'fixed'` + +**验收测试**: +```json +// 示例:灵活模式步骤配置 +{ + "step_id": "step_1", + "step_no": 1, + "script_mode": "flexible", + "intent": "获取用户真实姓名", + "intent_description": "需要获取用户的真实姓名用于后续身份确认", + "script_constraints": [ + "必须礼貌", + "语气自然,不要生硬", + "如果用户已经说了姓名,直接确认即可" + ], + "expected_variables": ["user_name"], + "content": "您好,请问怎么称呼您?", // fallback 话术 + "wait_input": true +} +``` + +--- + +#### AC-IDS-02: 扩展 Admin API 契约 +**优先级**: P0 (MVP 必须) +**描述**: 更新 `openapi.admin.yaml` 中 ScriptFlow 相关接口的 schema + +**技术要求**: +- 更新 `FlowStepSchema` 定义,增加新字段 +- 所有新字段标记为 `optional` +- 更新接口文档说明 +- 保持 API 版本不变(向后兼容扩展) + +**影响接口**: +- `POST /admin/script-flows` - 创建流程 +- `PUT /admin/script-flows/{id}` - 更新流程 +- `GET /admin/script-flows/{id}` - 获取流程详情 + +--- + +### Phase 2: 后端话术生成引擎 + +#### AC-IDS-03: 实现话术生成引擎 +**优先级**: P0 (MVP 必须) +**描述**: 在 `FlowEngine` 中实现根据 `script_mode` 生成话术的逻辑 + +**技术要求**: +- 在 `FlowEngine` 中新增方法 `_generate_step_content(step, context, history)` +- 实现三种模式的生成逻辑: + - `fixed`: 直接返回 `step.content` + - `flexible`: 调用 LLM 生成话术 + - `template`: 使用模板引擎填充变量 +- 在 `start()` 和 `advance()` 方法中调用话术生成 + +**代码位置**: `ai-service/app/services/flow/engine.py` + +**验收测试**: +- 固定模式:返回原始 content +- 灵活模式:生成的话术符合意图和约束 +- 模板模式:正确填充变量 + +--- + +#### AC-IDS-04: 实现灵活模式的 Prompt 构建 +**优先级**: P0 (MVP 必须) +**描述**: 为灵活模式构建合适的 LLM Prompt + +**技术要求**: +- Prompt 包含:步骤意图、约束条件、对话历史(最近 3 轮)、会话上下文 +- 明确指示 AI 生成简洁的话术(不超过 50 字) +- 包含 fallback 指令(生成失败时的处理) + +**Prompt 模板示例**: +```python +prompt = f""" +你是一个客服对话系统,当前需要执行以下步骤: + +【步骤目标】{intent} +【详细说明】{intent_description} +【约束条件】 +{'\n'.join(f'- {c}' for c in constraints)} + +【对话历史】 +{format_history(history[-3:])} + +【会话上下文】 +{format_context(context)} + +请生成一句符合目标和约束的话术(不超过50字)。 +只返回话术内容,不要解释。 +""" +``` + +--- + +#### AC-IDS-05: 实现 Fallback 机制 +**优先级**: P0 (MVP 必须) +**描述**: 当话术生成失败时,使用 fallback 策略 + +**技术要求**: +- LLM 调用超时(2秒)时,返回 `step.content` 作为 fallback +- LLM 返回错误时,记录日志并返回 fallback +- Fallback 话术不为空时使用,否则返回默认提示 + +**验收测试**: +- 模拟 LLM 超时,验证返回 fallback 话术 +- 模拟 LLM 错误,验证日志记录和 fallback + +--- + +#### AC-IDS-06: 实现模板模式的变量填充 +**优先级**: P1 (可选) +**描述**: 支持在 `content` 中使用 `{变量名}` 标记,AI 填充变量 + +**技术要求**: +- 解析模板中的变量(正则匹配 `{...}`) +- 调用 LLM 根据上下文生成变量值 +- 替换模板中的变量占位符 + +**示例**: +```python +# 模板 +content = "您好{greeting_style},请问您{polite_form}?" + +# AI 生成 +greeting_style = ",很高兴为您服务" +polite_form = "贵姓" + +# 结果 +"您好,很高兴为您服务,请问您贵姓?" +``` + +--- + +### Phase 3: 前端配置界面 + +#### AC-IDS-07: 前端类型定义扩展 +**优先级**: P0 (MVP 必须) +**描述**: 更新 `script-flow.ts` 类型定义 + +**技术要求**: +- 在 `FlowStep` 接口中增加新字段 +- 定义 `ScriptMode` 枚举类型 +- 更新相关的 Create/Update 类型 + +**代码位置**: `ai-service-admin/src/types/script-flow.ts` + +--- + +#### AC-IDS-08: 配置界面增加模式选择 +**优先级**: P0 (MVP 必须) +**描述**: 在步骤配置表单中增加话术模式选择 + +**技术要求**: +- 增加 Radio Group 选择话术模式 +- 根据选择的模式动态显示对应配置项 +- 固定模式:显示 `content` 输入框 +- 灵活模式:显示 `intent`、`intent_description`、`constraints` 配置 +- 模板模式:显示 `content` 输入框(带模板语法提示) + +**代码位置**: `ai-service-admin/src/views/admin/script-flow/index.vue` + +**UI 要求**: +- 模式切换时保留已填写的数据 +- 提供模式说明的 Tooltip +- 约束条件支持标签式添加/删除 + +--- + +#### AC-IDS-09: 约束条件管理组件 +**优先级**: P0 (MVP 必须) +**描述**: 实现约束条件的添加、删除、编辑 + +**技术要求**: +- 使用 `el-tag` 显示已添加的约束 +- 支持点击删除约束 +- 输入框回车添加新约束 +- 约束不能为空或重复 + +**UI 示例**: +``` +话术约束: [必须礼貌 ×] [语气自然 ×] [不要生硬 ×] + [输入新约束...] +``` + +--- + +#### AC-IDS-10: 流程预览增强 +**优先级**: P1 (可选) +**描述**: 在流程预览中显示步骤的意图信息 + +**技术要求**: +- 在 `FlowPreview.vue` 中显示步骤的 `script_mode` +- 灵活模式显示意图和约束 +- 固定模式显示话术内容 + +**代码位置**: `ai-service-admin/src/views/admin/script-flow/components/FlowPreview.vue` + +--- + +### Phase 4: 测试与验证 + +#### AC-IDS-11: 单元测试覆盖 +**优先级**: P0 (MVP 必须) +**描述**: 为话术生成引擎编写单元测试 + +**技术要求**: +- 测试三种模式的话术生成 +- 测试 fallback 机制 +- 测试边界情况(空配置、无效配置) + +**测试文件**: `ai-service/tests/services/flow/test_engine_script_generation.py` + +--- + +#### AC-IDS-12: 集成测试 +**优先级**: P0 (MVP 必须) +**描述**: 端到端测试意图驱动流程的执行 + +**测试场景**: +1. 创建灵活模式流程 +2. 启动流程,验证首步话术生成 +3. 输入用户消息,验证流程推进和话术生成 +4. 验证对话历史正确传递 + +--- + +#### AC-IDS-13: 向后兼容性测试 +**优先级**: P0 (MVP 必须) +**描述**: 验证现有固定话术流程不受影响 + +**测试场景**: +1. 加载现有流程(无 script_mode 字段) +2. 执行流程,验证话术正常返回 +3. 验证 API 响应包含新字段但值为 null + +--- + +## 4. 接口映射表(API Mapping) + +| 验收标准 | 接口路径 | 方法 | 变更类型 | 说明 | +|---------|---------|------|---------|------| +| AC-IDS-02 | `/admin/script-flows` | POST | 扩展请求体 | steps 增加意图字段 | +| AC-IDS-02 | `/admin/script-flows/{id}` | PUT | 扩展请求体 | 同上 | +| AC-IDS-02 | `/admin/script-flows/{id}` | GET | 扩展响应体 | 返回意图字段 | +| AC-IDS-03 | 内部方法 | - | 新增 | `_generate_step_content()` | +| AC-IDS-05 | 内部方法 | - | 修改 | `start()`, `advance()` | + +--- + +## 5. 非功能性需求(NFR) + +### NFR-IDS-01: 性能要求 +- 话术生成延迟 < 2 秒(P95) +- LLM 调用超时设置为 2 秒 +- API 响应时间增加 < 10% + +### NFR-IDS-02: 可靠性要求 +- 话术生成失败率 < 1% +- Fallback 机制 100% 可用 +- 无数据丢失 + +### NFR-IDS-03: 兼容性要求 +- 现有流程无需迁移即可运行 +- API 向后兼容(新字段可选) +- 前端支持旧版本数据 + +--- + +## 6. 数据迁移方案 + +### 6.1 数据库变更 +**无需数据库 Schema 变更**,因为 `steps` 字段已经是 JSON 类型,可以直接扩展。 + +### 6.2 现有数据处理 +- 现有流程数据保持不变 +- 执行时默认 `script_mode = 'fixed'` +- 无需运行迁移脚本 + +--- + +## 7. 风险与缓解措施 + +| 风险 | 影响 | 概率 | 缓解措施 | +|------|------|------|---------| +| LLM 生成话术不稳定 | 用户体验差 | 中 | 提供 fallback 到固定话术 | +| 生成延迟过高 | 对话不流畅 | 中 | 设置 2 秒超时,超时返回 fallback | +| 约束条件理解偏差 | 话术不符合预期 | 低 | 提供详细的 Prompt 指导 | +| 向后兼容性问题 | 现有流程失效 | 低 | 充分测试,默认 fixed 模式 | + +--- + +## 8. 发布计划 + +### 8.1 Phase 划分 +- **Phase 1**: 数据模型与 API 扩展(AC-IDS-01 ~ AC-IDS-02) +- **Phase 2**: 后端话术生成引擎(AC-IDS-03 ~ AC-IDS-06) +- **Phase 3**: 前端配置界面(AC-IDS-07 ~ AC-IDS-10) +- **Phase 4**: 测试与验证(AC-IDS-11 ~ AC-IDS-13) + +### 8.2 里程碑 +- **M1**: 后端 MVP 完成(Phase 1 + Phase 2 核心功能) +- **M2**: 前端配置完成(Phase 3) +- **M3**: 测试通过,可发布(Phase 4) + +--- + +## 9. 附录 + +### 9.1 术语表 +- **意图(Intent)**: 步骤要达到的目的,例如"获取用户姓名" +- **话术(Script)**: 实际发送给用户的文本内容 +- **约束(Constraint)**: 对话术的限制条件,例如"必须礼貌" +- **Fallback**: 当主要方案失败时的备用方案 + +### 9.2 参考文档 +- [功能定界](./scope.md) +- [现有 FlowEngine 实现](../../ai-service/app/services/flow/engine.py) +- [现有前端配置界面](../../ai-service-admin/src/views/admin/script-flow/index.vue) diff --git a/spec/intent-driven-script/scope.md b/spec/intent-driven-script/scope.md new file mode 100644 index 0000000..9702586 --- /dev/null +++ b/spec/intent-driven-script/scope.md @@ -0,0 +1,118 @@ +# 意图驱动话术流程 - 功能定界 + +## 1. 功能边界(Scope) + +### 1.1 核心目标 +将现有的"固定话术"流程升级为"意图驱动"模式,使 AI 能够根据步骤意图和上下文灵活生成话术,而不是机械地返回预设文本。 + +### 1.2 覆盖范围(In Scope) + +#### 后端改造 +- **数据模型扩展**:在 `ScriptFlow.steps` 中增加意图驱动字段(intent, script_mode, constraints 等) +- **话术生成引擎**:在 FlowEngine 中实现三种模式的话术生成逻辑 + - `fixed`:固定话术(向后兼容) + - `flexible`:意图驱动,AI 根据意图和约束实时生成 + - `template`:模板填充,AI 填充变量部分 +- **上下文传递**:将对话历史、会话上下文传递给话术生成器 +- **向后兼容**:确保现有固定话术流程不受影响 + +#### 前端改造 +- **配置界面升级**:在话术流程配置页面增加模式选择和意图配置 +- **模式切换**:支持三种模式的动态切换和对应配置项显示 +- **约束条件管理**:支持添加/删除话术约束标签 +- **预览增强**:在流程预览中显示意图信息 + +#### API 变更 +- **数据结构扩展**:ScriptFlow API 的 steps 字段增加新字段(向后兼容) +- **无需新增接口**:复用现有的 CRUD 接口 + +### 1.3 不覆盖范围(Out of Scope) + +- **意图识别**:不涉及用户输入的意图识别(已有 IntentRule 模块负责) +- **多轮对话管理**:不改变现有的流程状态机逻辑 +- **LLM 模型选择**:使用现有的 LLM 调用机制,不涉及模型切换 +- **性能优化**:不涉及话术生成的缓存、预生成等优化(可后续迭代) +- **A/B 测试**:不涉及多版本话术的效果对比 + +--- + +## 2. 外部接口清单 + +### 2.1 需要修改的接口 + +| 接口路径 | 方法 | 变更类型 | 说明 | +|---------|------|---------|------| +| `/admin/script-flows` | POST | 扩展请求体 | steps 字段增加意图驱动字段 | +| `/admin/script-flows/{id}` | PUT | 扩展请求体 | 同上 | +| `/admin/script-flows/{id}` | GET | 扩展响应体 | 返回新增字段 | + +### 2.2 内部依赖 + +| 模块 | 依赖关系 | 说明 | +|------|---------|------| +| FlowEngine | 修改 | 增加话术生成逻辑 | +| Orchestrator | 调用 | 调用 LLM 生成话术 | +| ChatMessage | 读取 | 获取对话历史作为上下文 | + +--- + +## 3. 文档清单 + +### 3.1 必须产出的文档 + +- [x] `scope.md` - 功能定界(本文档) +- [ ] `requirements.md` - 需求规范(用户故事 + 验收标准) +- [ ] `design.md` - 设计文档(数据结构 + 流程图) +- [ ] `openapi.admin.yaml` - 接口契约(扩展现有契约) +- [ ] `tasks.md` - 任务分解(Phase 划分) + +### 3.2 可选文档 + +- [ ] `migration.md` - 数据迁移方案(如需数据库变更) +- [ ] `testing.md` - 测试用例(重点场景) + +--- + +## 4. 风险与依赖 + +### 4.1 技术风险 + +| 风险 | 影响 | 缓解措施 | +|------|------|---------| +| LLM 生成话术不稳定 | 用户体验差 | 提供 fallback 到固定话术 | +| 生成延迟过高 | 影响对话流畅度 | 设置超时,超时返回默认话术 | +| 向后兼容性问题 | 现有流程失效 | 默认 script_mode=fixed | + +### 4.2 依赖项 + +- **LLM 服务可用性**:依赖 Orchestrator 的 LLM 调用能力 +- **数据库迁移**:需要 Alembic 迁移脚本(如果修改表结构) +- **前端组件库**:依赖 Element Plus 的表单组件 + +--- + +## 5. 验收标准概览 + +### 5.1 核心验收点 + +- [ ] 后端支持三种话术模式(fixed/flexible/template) +- [ ] 前端配置界面支持模式切换和意图配置 +- [ ] 现有固定话术流程不受影响(向后兼容) +- [ ] flexible 模式能根据上下文生成不同话术 +- [ ] 生成失败时有明确的 fallback 机制 + +### 5.2 非功能性要求 + +- [ ] 话术生成延迟 < 2 秒(P95) +- [ ] API 响应时间不增加 > 10% +- [ ] 数据库迁移无数据丢失 + +--- + +## 6. 下一步 + +确认功能边界后,请执行: + +``` +生成 spec/intent-driven-script/requirements.md 需求文档 +``` diff --git a/spec/intent-driven-script/tasks.md b/spec/intent-driven-script/tasks.md new file mode 100644 index 0000000..64d0ee7 --- /dev/null +++ b/spec/intent-driven-script/tasks.md @@ -0,0 +1,1126 @@ +# 意图驱动话术流程 - 任务分解 + +--- +feature_id: "IDS" +title: "意图驱动话术流程任务清单" +status: "in-progress" +version: "1.2.0" +last_updated: "2026-03-01" +--- + +## 任务概览 + +本文档将需求规范中的 13 个验收标准分解为可执行的开发任务,按 Phase 组织。 + +**总体进度**: 22/26 任务完成 (85%) + +| Phase | 描述 | 任务数 | 完成数 | 进度 | +|-------|------|--------|--------|------| +| Phase 1 | 数据模型与 API 扩展 | 4 | 4 | 100% | +| Phase 2 | 后端话术生成引擎 | 6 | 6 | 100% | +| Phase 3 | 前端配置界面 | 6 | 6 | 100% | +| Phase 4 | 测试与验证 | 6 | 6 | 100% | +| Phase 5 | 部署与发布 | 4 | 0 | 0% | + +--- + +## Phase 1: 数据模型与 API 扩展 + +**目标**: 扩展数据结构和 API 契约,为意图驱动话术提供基础 + +**预计工时**: 0.5 天 + +**依赖**: 无 + +### Task 1.1: 扩展 Python 类型定义 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-01 +- **优先级**: P0 +- **依赖**: 无 +- **负责人**: backend + +**描述**: 在后端 Python 代码中扩展 FlowStep 的类型定义 + +**文件修改**: +- `ai-service/app/models/entities.py` 或 `ai-service/app/schemas/script_flow.py` + +**具体步骤**: +1. 找到 `FlowStep` 相关的类型定义(可能在 Pydantic model 或 TypedDict 中) +2. 添加以下可选字段: + ```python + script_mode: Optional[Literal["fixed", "flexible", "template"]] = "fixed" + intent: Optional[str] = None + intent_description: Optional[str] = None + script_constraints: Optional[List[str]] = None + expected_variables: Optional[List[str]] = None + ``` +3. 确保向后兼容:所有新字段都是可选的,有默认值 + +**验收测试**: +```python +# 测试向后兼容 +step_old = {"step_no": 1, "content": "Hello"} +# 应该能正常解析,script_mode 默认为 "fixed" + +# 测试新字段 +step_new = { + "step_no": 1, + "script_mode": "flexible", + "intent": "获取用户姓名", + "script_constraints": ["必须礼貌"], + "content": "请问怎么称呼您?" +} +# 应该能正常解析 +``` + +**完成标准**: +- [x] 类型定义已扩展 +- [x] 所有新字段都是可选的 +- [x] 代码通过类型检查(mypy/pyright) + +--- + +### Task 1.2: 扩展前端 TypeScript 类型定义 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-07 +- **优先级**: P0 +- **依赖**: 无 +- **负责人**: frontend + +**描述**: 在前端 TypeScript 代码中扩展 FlowStep 接口 + +**文件修改**: +- `ai-service-admin/src/types/script-flow.ts` + +**具体步骤**: +1. 打开 `script-flow.ts` 文件 +2. 找到 `FlowStep` 接口定义 +3. 添加新字段: + ```typescript + export type ScriptMode = 'fixed' | 'flexible' | 'template' + + export interface FlowStep { + // ... 现有字段 ... + + // 新增字段 + script_mode?: ScriptMode + intent?: string + intent_description?: string + script_constraints?: string[] + expected_variables?: string[] + } + ``` +4. 添加常量定义: + ```typescript + export const SCRIPT_MODE_OPTIONS = [ + { value: 'fixed', label: '固定话术', description: '话术内容固定不变' }, + { value: 'flexible', label: '灵活话术', description: 'AI根据意图和上下文生成' }, + { value: 'template', label: '模板话术', description: 'AI填充模板中的变量' } + ] as const + ``` + +**完成标准**: +- [x] TypeScript 类型定义已扩展 +- [x] 所有新字段都是可选的 +- [x] 代码通过 TypeScript 编译 + +--- + +### Task 1.3: 更新 OpenAPI 契约 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-02 +- **优先级**: P0 +- **依赖**: Task 1.1 + +**描述**: 更新 openapi.admin.yaml 中 ScriptFlow 相关接口的 schema + +**文件修改**: +- `spec/intent-driven-script/openapi.admin.yaml` 或 `ai-service/openapi/admin.yaml` + +**具体步骤**: +1. 找到 `FlowStepSchema` 定义 +2. 添加新字段定义: + ```yaml + script_mode: + type: string + enum: [fixed, flexible, template] + default: fixed + description: 话术生成模式 + intent: + type: string + description: 步骤意图(灵活模式必填) + intent_description: + type: string + description: 意图详细说明 + script_constraints: + type: array + items: + type: string + description: 话术约束条件 + expected_variables: + type: array + items: + type: string + description: 期望提取的变量 + ``` +3. 更新接口文档说明 +4. 标记契约成熟度为 L1 + +**完成标准**: +- [x] OpenAPI schema 已更新 +- [x] 所有新字段标记为 optional +- [x] 契约通过 lint 校验 + +--- + +### Task 1.4: 验证 API 向后兼容性 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-02, AC-IDS-13 +- **优先级**: P0 +- **依赖**: Task 1.1, Task 1.3 + +**描述**: 确保 API 扩展不破坏现有客户端 + +**测试场景**: +1. 使用旧版请求体创建流程(不包含新字段) +2. 验证流程能正常保存和执行 +3. 验证 API 响应包含新字段(值为 null 或默认值) + +**测试文件**: +- `ai-service/tests/api/test_script_flow_backward_compat.py` + +**测试用例**: +```python +async def test_create_flow_without_new_fields(): + """测试不包含新字段的请求能正常工作""" + payload = { + "name": "测试流程", + "steps": [ + {"step_no": 1, "content": "Hello", "wait_input": True} + ] + } + response = await client.post("/admin/script-flows", json=payload) + assert response.status_code == 201 + + # 验证响应包含新字段(默认值) + flow = response.json() + assert flow["steps"][0]["script_mode"] == "fixed" + assert flow["steps"][0]["intent"] is None + +async def test_execute_old_flow(): + """测试旧流程能正常执行""" + # 创建不包含新字段的流程 + # 启动流程 + # 验证返回固定话术 +``` + +**完成标准**: +- [x] 所有向后兼容性测试通过 +- [x] 旧版客户端不受影响 + +--- + +## Phase 2: 后端话术生成引擎 + +**目标**: 实现三种模式的话术生成逻辑 + +**预计工时**: 2 天 + +**依赖**: Phase 1 完成 + +### Task 2.1: 创建 ScriptGenerator 模块 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-04 +- **优先级**: P0 +- **依赖**: Task 1.1 + +**描述**: 实现灵活模式的话术生成器 + +**文件创建**: +- `ai-service/app/services/flow/script_generator.py` + +**具体实现**: +```python +""" +[AC-IDS-04] Script Generator for flexible mode +""" +import asyncio +import logging +from typing import Optional + +logger = logging.getLogger(__name__) + + +class ScriptGenerator: + """灵活模式话术生成器""" + + def __init__(self, orchestrator): + self._orchestrator = orchestrator + + async def generate( + self, + intent: str, + intent_description: Optional[str], + constraints: list[str], + context: dict, + history: list[dict], + fallback: str + ) -> str: + """ + 生成灵活话术 + + Args: + intent: 步骤意图 + intent_description: 意图详细说明 + constraints: 话术约束条件 + context: 会话上下文 + history: 对话历史 + fallback: 失败时的 fallback 话术 + + Returns: + 生成的话术文本 + """ + try: + prompt = self._build_prompt( + intent, intent_description, constraints, context, history + ) + + response = await asyncio.wait_for( + self._orchestrator.generate_text(prompt), + timeout=2.0 + ) + + generated = response.strip() + logger.info( + f"[AC-IDS-04] Generated flexible script: " + f"intent={intent}, length={len(generated)}" + ) + return generated + + except asyncio.TimeoutError: + logger.warning( + f"[AC-IDS-05] Script generation timeout, use fallback: " + f"intent={intent}" + ) + return fallback + + except Exception as e: + logger.error( + f"[AC-IDS-05] Script generation failed: {e}, use fallback" + ) + return fallback + + def _build_prompt( + self, + intent: str, + intent_description: Optional[str], + constraints: list[str], + context: dict, + history: list[dict] + ) -> str: + """构建 LLM Prompt""" + prompt_parts = [ + "你是一个客服对话系统,当前需要执行以下步骤:", + "", + f"【步骤目标】{intent}" + ] + + if intent_description: + prompt_parts.append(f"【详细说明】{intent_description}") + + if constraints: + prompt_parts.append("") + prompt_parts.append("【约束条件】") + for c in constraints: + prompt_parts.append(f"- {c}") + + if history: + prompt_parts.append("") + prompt_parts.append("【对话历史】") + for msg in history[-3:]: + role = "用户" if msg.get("role") == "user" else "客服" + content = msg.get("content", "") + prompt_parts.append(f"{role}: {content}") + + if context.get("inputs"): + prompt_parts.append("") + prompt_parts.append("【已收集信息】") + for inp in context["inputs"]: + prompt_parts.append(f"- {inp}") + + prompt_parts.extend([ + "", + "请生成一句符合目标和约束的话术(不超过50字)。", + "只返回话术内容,不要解释。" + ]) + + return "\n".join(prompt_parts) +``` + +**完成标准**: +- [x] ScriptGenerator 类已实现 +- [x] Prompt 构建逻辑完整 +- [x] 超时和异常处理正确 +- [x] 日志记录完整 + +--- + +### Task 2.2: 创建 TemplateEngine 模块 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-06 +- **优先级**: P1 +- **依赖**: Task 1.1 + +**描述**: 实现模板模式的变量填充逻辑 + +**文件创建**: +- `ai-service/app/services/flow/template_engine.py` + +**具体实现**: +```python +""" +[AC-IDS-06] Template Engine for template mode +""" +import asyncio +import logging +import re +from typing import Optional + +logger = logging.getLogger(__name__) + + +class TemplateEngine: + """模板话术引擎""" + + VARIABLE_PATTERN = re.compile(r'\{(\w+)\}') + + def __init__(self, orchestrator): + self._orchestrator = orchestrator + + async def fill_template( + self, + template: str, + context: dict, + history: list[dict] + ) -> str: + """ + 填充模板变量 + + Args: + template: 话术模板(包含 {变量名} 占位符) + context: 会话上下文 + history: 对话历史 + + Returns: + 填充后的话术 + """ + try: + variables = self.VARIABLE_PATTERN.findall(template) + + if not variables: + return template + + variable_values = {} + for var in variables: + value = await self._generate_variable_value(var, context, history) + variable_values[var] = value + + result = template + for var, value in variable_values.items(): + result = result.replace(f"{{{var}}}", value) + + logger.info( + f"[AC-IDS-06] Filled template: " + f"variables={list(variable_values.keys())}" + ) + return result + + except Exception as e: + logger.error(f"[AC-IDS-06] Template fill failed: {e}, return original") + return template + + async def _generate_variable_value( + self, + variable_name: str, + context: dict, + history: list[dict] + ) -> str: + """为单个变量生成值""" + if variable_name in context: + return str(context[variable_name]) + + prompt = f""" +根据对话历史,为变量 "{variable_name}" 生成合适的值。 + +对话历史: +{self._format_history(history[-3:])} + +只返回变量值,不要解释。 +""" + + try: + response = await asyncio.wait_for( + self._orchestrator.generate_text(prompt), + timeout=1.0 + ) + return response.strip() + except: + logger.warning( + f"[AC-IDS-06] Failed to generate value for {variable_name}, " + f"use placeholder" + ) + return f"[{variable_name}]" + + def _format_history(self, history: list[dict]) -> str: + """格式化对话历史""" + lines = [] + for msg in history: + role = "用户" if msg.get("role") == "user" else "客服" + content = msg.get("content", "") + lines.append(f"{role}: {content}") + return "\n".join(lines) +``` + +**完成标准**: +- [x] TemplateEngine 类已实现 +- [x] 变量提取和替换逻辑正确 +- [x] 异常处理和 fallback 完整 + +--- + +### Task 2.3: 扩展 FlowEngine - 添加话术生成方法 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-03 +- **优先级**: P0 +- **依赖**: Task 2.1, Task 2.2 + +**描述**: 在 FlowEngine 中添加话术生成的核心方法 + +**文件修改**: +- `ai-service/app/services/flow/engine.py` + +**具体步骤**: +1. 在 `FlowEngine.__init__()` 中初始化生成器 +2. 添加 `_generate_step_content()` 方法 +3. 添加 `_get_conversation_history()` 辅助方法 + +**完成标准**: +- [x] `_generate_step_content()` 方法已实现 +- [x] 三种模式的分支逻辑正确 +- [x] `_get_conversation_history()` 方法已实现 +- [x] 错误处理和 fallback 完整 + +--- + +### Task 2.4: 修改 FlowEngine.start() 方法 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-05 +- **优先级**: P0 +- **依赖**: Task 2.3 + +**描述**: 修改流程启动逻辑,在首步使用话术生成 + +**文件修改**: +- `ai-service/app/services/flow/engine.py` + +**具体步骤**: +1. 在 `start()` 方法中调用 `_get_conversation_history()` +2. 调用 `_generate_step_content()` 生成首步话术 +3. 确保向后兼容(无 orchestrator 时使用固定话术) + +**完成标准**: +- [x] start() 方法已修改 +- [x] 首步话术能正确生成 +- [x] 向后兼容测试通过 + +--- + +### Task 2.5: 修改 FlowEngine.advance() 方法 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-05 +- **优先级**: P0 +- **依赖**: Task 2.3 + +**描述**: 修改流程推进逻辑,在后续步骤使用话术生成 + +**文件修改**: +- `ai-service/app/services/flow/engine.py` + +**具体步骤**: +1. 在 `advance()` 方法中调用 `_get_conversation_history()` +2. 调用 `_generate_step_content()` 生成下一步话术 +3. 确保向后兼容 + +**完成标准**: +- [x] advance() 方法已修改 +- [x] 后续步骤话术能正确生成 +- [x] 向后兼容测试通过 + +--- + +### Task 2.6: 实现 Fallback 机制 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-05 +- **优先级**: P0 +- **依赖**: Task 2.1 + +**描述**: 确保话术生成失败时有明确的 fallback 策略 + +**技术要求**: +- LLM 调用超时(2秒)时,返回 `step.content` 作为 fallback +- LLM 返回错误时,记录日志并返回 fallback +- Fallback 话术不为空时使用,否则返回默认提示 + +**验收测试**: +- 模拟 LLM 超时,验证返回 fallback 话术 +- 模拟 LLM 错误,验证日志记录和 fallback + +**完成标准**: +- [x] 超时 fallback 已实现 +- [x] 异常 fallback 已实现 +- [x] 日志记录完整 +- [x] 单元测试通过 + +--- + +## Phase 3: 前端配置界面 + +**目标**: 提供意图驱动话术的配置界面 + +**预计工时**: 1.5 天 + +**依赖**: Phase 1 完成 + +### Task 3.1: 创建话术模式选择组件 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-08 +- **优先级**: P0 +- **依赖**: Task 1.2 + +**描述**: 在步骤配置表单中增加话术模式选择 + +**文件修改**: +- `ai-service-admin/src/views/admin/script-flow/index.vue` + +**具体步骤**: +1. 添加 Radio Group 选择话术模式 +2. 根据选择的模式动态显示对应配置项 +3. 模式切换时保留已填写的数据 + +**UI 要求**: +- 固定模式:显示 `content` 输入框 +- 灵活模式:显示 `intent`、`intent_description`、`constraints` 配置 +- 模板模式:显示 `content` 输入框(带模板语法提示) + +**完成标准**: +- [x] 模式选择器已实现 +- [x] 动态表单切换正确 +- [x] 数据保留逻辑正确 + +--- + +### Task 3.2: 创建意图配置表单 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-08 +- **优先级**: P0 +- **依赖**: Task 3.1 + +**描述**: 实现灵活模式的意图配置表单 + +**文件修改**: +- `ai-service-admin/src/views/admin/script-flow/index.vue` + +**具体步骤**: +1. 添加"步骤意图"输入框(必填) +2. 添加"意图说明"文本域(可选) +3. 添加"期望变量"输入(可选) +4. 添加表单校验规则 + +**完成标准**: +- [x] 意图配置表单已实现 +- [x] 表单校验正确 +- [x] 数据绑定正确 + +--- + +### Task 3.3: 创建约束条件管理组件 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-09 +- **优先级**: P0 +- **依赖**: Task 1.2 + +**描述**: 实现约束条件的添加、删除、编辑 + +**文件创建**: +- `ai-service-admin/src/views/admin/script-flow/components/ConstraintManager.vue` + +**具体实现**: +```vue + + + +``` + +**完成标准**: +- [x] ConstraintManager 组件已实现 +- [x] 支持添加/删除约束 +- [x] 支持预设约束快捷添加 +- [x] 组件已集成到主表单 + +--- + +### Task 3.4: 创建模板话术配置组件 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-04 +- **优先级**: P1 +- **依赖**: Task 3.1 + +**描述**: 实现模板模式的配置界面 + +**文件修改**: +- `ai-service-admin/src/views/admin/script-flow/index.vue` + +**具体步骤**: +1. 添加话术模板输入框 +2. 添加模板语法提示 +3. 添加变量高亮显示(可选) + +**UI 示例**: +``` +话术模板: [您好{greeting_style},请问您{polite_form}?] +提示:使用 {变量名} 标记需要AI填充的部分 +``` + +**完成标准**: +- [x] 模板配置界面已实现 +- [x] 语法提示清晰 +- [x] 数据绑定正确 + +--- + +### Task 3.5: 增强流程预览组件 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-10 +- **优先级**: P1 +- **依赖**: Task 3.1 + +**描述**: 在流程预览中显示步骤的意图信息 + +**文件修改**: +- `ai-service-admin/src/views/admin/script-flow/components/FlowPreview.vue` + +**具体步骤**: +1. 显示步骤的 `script_mode` +2. 灵活模式显示意图和约束 +3. 固定模式显示话术内容 +4. 模板模式显示模板预览 + +**完成标准**: +- [x] 预览组件已增强 +- [x] 意图信息显示正确 +- [x] 不同模式显示不同内容 + +--- + +### Task 3.6: 前端表单校验与提交 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-08 +- **优先级**: P0 +- **依赖**: Task 3.1, Task 3.2, Task 3.3 + +**描述**: 实现表单校验和数据提交逻辑 + +**文件修改**: +- `ai-service-admin/src/views/admin/script-flow/index.vue` + +**校验规则**: +- 灵活模式:`intent` 必填,`content`(fallback)必填 +- 模板模式:`content` 必填,检查模板语法 +- 固定模式:`content` 必填 + +**完成标准**: +- [x] 表单校验规则已实现 +- [x] 提交逻辑正确 +- [x] 错误提示清晰 + +--- + +## Phase 4: 测试与验证 + +**目标**: 确保功能正确性和向后兼容性 + +**预计工时**: 1 天 + +**依赖**: Phase 2, Phase 3 完成 + +### Task 4.1: 后端单元测试 - ScriptGenerator +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-11 +- **优先级**: P0 +- **依赖**: Task 2.1 + +**描述**: 为 ScriptGenerator 编写单元测试 + +**测试文件**: +- `ai-service/tests/services/flow/test_script_generator.py` + +**测试用例**: +- 正常生成话术 +- 超时 fallback +- 异常 fallback +- Prompt 构建正确性 + +**完成标准**: +- [x] 测试文件已创建 +- [x] 所有测试用例通过 +- [x] 代码覆盖率 > 80% + +--- + +### Task 4.2: 后端单元测试 - TemplateEngine +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-11 +- **优先级**: P0 +- **依赖**: Task 2.2 + +**描述**: 为 TemplateEngine 编写单元测试 + +**测试文件**: +- `ai-service/tests/services/flow/test_template_engine.py` + +**测试用例**: +- 变量提取正确性 +- 变量替换正确性 +- 从上下文获取变量值 +- LLM 生成变量值 +- 异常处理 + +**完成标准**: +- [x] 测试文件已创建 +- [x] 所有测试用例通过 +- [x] 代码覆盖率 > 80% + +--- + +### Task 4.3: 后端单元测试 - FlowEngine +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-11 +- **优先级**: P0 +- **依赖**: Task 2.3, Task 2.4, Task 2.5 + +**描述**: 为 FlowEngine 话术生成逻辑编写单元测试 + +**测试文件**: +- `ai-service/tests/services/flow/test_engine_script_generation.py` + +**测试用例**: +- 固定模式话术生成 +- 灵活模式话术生成 +- 模板模式话术生成 +- 对话历史获取 +- 边界情况(空配置、无效配置) + +**完成标准**: +- [x] 测试文件已创建 +- [x] 所有测试用例通过 +- [x] 代码覆盖率 > 80% + +--- + +### Task 4.4: 集成测试 - 端到端流程 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-12 +- **优先级**: P0 +- **依赖**: Task 4.1, Task 4.2, Task 4.3 + +**描述**: 端到端测试意图驱动流程的执行 + +**测试文件**: +- `ai-service/tests/api/test_script_flow_intent_driven.py` + +**测试场景**: +1. 创建灵活模式流程 +2. 启动流程,验证首步话术生成 +3. 输入用户消息,验证流程推进和话术生成 +4. 验证对话历史正确传递 + +**完成标准**: +- [x] 测试文件已创建 +- [x] 所有测试场景通过 +- [x] 测试覆盖主要业务流程 + +--- + +### Task 4.5: 向后兼容性测试 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-13 +- **优先级**: P0 +- **依赖**: Task 4.4 + +**描述**: 验证现有固定话术流程不受影响 + +**测试场景**: +1. 加载现有流程(无 script_mode 字段) +2. 执行流程,验证话术正常返回 +3. 验证 API 响应包含新字段但值为 null +4. 验证前端能正确显示旧流程数据 + +**完成标准**: +- [x] 所有向后兼容性测试通过 +- [x] 现有流程不受影响 + +--- + +### Task 4.6: 前端组件测试 +- [x] **状态**: ✅已完成 (2026-02-28) +- **验收标准**: AC-IDS-08, AC-IDS-09 +- **优先级**: P1 +- **依赖**: Task 3.1, Task 3.2, Task 3.3 + +**描述**: 为前端组件编写测试 + +**测试文件**: +- `ai-service-admin/src/views/admin/script-flow/__tests__/` + +**测试用例**: +- 模式选择器交互 +- 约束条件管理 +- 表单校验 +- 数据提交 + +**完成标准**: +- [x] 测试文件已创建 +- [x] 主要交互测试通过 + +--- + +## Phase 5: 部署与发布 + +**目标**: 安全部署新功能 + +**预计工时**: 0.5 天 + +**依赖**: Phase 4 全部完成 + +### Task 5.1: 更新部署文档 +- [ ] **状态**: 待开始 +- **验收标准**: N/A +- **优先级**: P0 +- **依赖**: Phase 4 完成 + +**描述**: 更新部署文档和变更日志 + +**文件修改**: +- `CHANGELOG.md` +- `docs/deployment.md`(如存在) + +**具体内容**: +- 记录新功能 +- 记录 API 变更 +- 记录配置变更(如有) + +**完成标准**: +- [ ] 变更日志已更新 +- [ ] 部署文档已更新 + +--- + +### Task 5.2: 灰度发布准备 +- [ ] **状态**: 待开始 +- **验收标准**: N/A +- **优先级**: P0 +- **依赖**: Task 5.1 + +**描述**: 准备灰度发布环境 + +**具体步骤**: +1. 选择灰度租户 +2. 配置监控告警 +3. 准备回滚方案 + +**完成标准**: +- [ ] 灰度租户已确定 +- [ ] 监控已配置 +- [ ] 回滚方案已准备 + +--- + +### Task 5.3: 执行灰度发布 +- [ ] **状态**: 待开始 +- **验收标准**: N/A +- **优先级**: P0 +- **依赖**: Task 5.2 + +**描述**: 执行灰度发布并监控 + +**具体步骤**: +1. 部署后端服务 +2. 部署前端服务 +3. 监控关键指标 +4. 收集用户反馈 + +**监控指标**: +- 话术生成延迟 +- 超时率 +- 错误率 +- Fallback 使用率 + +**完成标准**: +- [ ] 灰度发布成功 +- [ ] 无严重问题 +- [ ] 用户反馈正常 + +--- + +### Task 5.4: 全量发布 +- [ ] **状态**: 待开始 +- **验收标准**: N/A +- **优先级**: P0 +- **依赖**: Task 5.3 + +**描述**: 灰度验证通过后全量发布 + +**具体步骤**: +1. 确认灰度指标正常 +2. 执行全量发布 +3. 持续监控 + +**完成标准**: +- [ ] 全量发布成功 +- [ ] 功能正常可用 +- [ ] 无用户投诉 + +--- + +## 任务依赖关系图 + +``` +Phase 1 (数据模型与 API 扩展) +├── Task 1.1 (Python 类型定义) ──────────────────────────────┐ +├── Task 1.2 (TypeScript 类型定义) ──────────────────────────┤ +├── Task 1.3 (OpenAPI 契约) ← Task 1.1 ──────────────────────┤ +└── Task 1.4 (向后兼容性测试) ← Task 1.1, Task 1.3 ──────────┘ + │ + ▼ +Phase 2 (后端话术生成引擎) +├── Task 2.1 (ScriptGenerator) ← Task 1.1 ───────────────────┐ +├── Task 2.2 (TemplateEngine) ← Task 1.1 ────────────────────┤ +├── Task 2.3 (FlowEngine 扩展) ← Task 2.1, Task 2.2 ─────────┤ +├── Task 2.4 (start 方法修改) ← Task 2.3 ────────────────────┤ +├── Task 2.5 (advance 方法修改) ← Task 2.3 ──────────────────┤ +└── Task 2.6 (Fallback 机制) ← Task 2.1 ─────────────────────┘ + │ + ▼ +Phase 3 (前端配置界面) +├── Task 3.1 (模式选择组件) ← Task 1.2 ──────────────────────┐ +├── Task 3.2 (意图配置表单) ← Task 3.1 ──────────────────────┤ +├── Task 3.3 (约束管理组件) ← Task 1.2 ──────────────────────┤ +├── Task 3.4 (模板配置组件) ← Task 3.1 ──────────────────────┤ +├── Task 3.5 (预览增强) ← Task 3.1 ──────────────────────────┤ +└── Task 3.6 (表单校验提交) ← Task 3.1, Task 3.2, Task 3.3 ──┘ + │ + ▼ +Phase 4 (测试与验证) +├── Task 4.1 (ScriptGenerator 测试) ← Task 2.1 ──────────────┐ +├── Task 4.2 (TemplateEngine 测试) ← Task 2.2 ───────────────┤ +├── Task 4.3 (FlowEngine 测试) ← Task 2.3, Task 2.4, Task 2.5┤ +├── Task 4.4 (集成测试) ← Task 4.1, Task 4.2, Task 4.3 ──────┤ +├── Task 4.5 (向后兼容测试) ← Task 4.4 ──────────────────────┤ +└── Task 4.6 (前端组件测试) ← Task 3.1, Task 3.2, Task 3.3 ──┘ + │ + ▼ +Phase 5 (部署与发布) +├── Task 5.1 (更新部署文档) ← Phase 4 完成 ──────────────────┐ +├── Task 5.2 (灰度发布准备) ← Task 5.1 ──────────────────────┤ +├── Task 5.3 (执行灰度发布) ← Task 5.2 ──────────────────────┤ +└── Task 5.4 (全量发布) ← Task 5.3 ──────────────────────────┘ +``` + +--- + +## 验收标准与任务映射 + +| 验收标准 | 关联任务 | 状态 | +|---------|---------|------| +| AC-IDS-01: 扩展 ScriptFlow 数据模型 | Task 1.1 | ✅已完成 | +| AC-IDS-02: 扩展 Admin API 契约 | Task 1.3, Task 1.4 | ✅已完成 | +| AC-IDS-03: 实现话术生成引擎 | Task 2.3 | ✅已完成 | +| AC-IDS-04: 实现灵活模式的 Prompt 构建 | Task 2.1 | ✅已完成 | +| AC-IDS-05: 实现 Fallback 机制 | Task 2.4, Task 2.5, Task 2.6 | ✅已完成 | +| AC-IDS-06: 实现模板模式的变量填充 | Task 2.2 | ✅已完成 | +| AC-IDS-07: 前端类型定义扩展 | Task 1.2 | ✅已完成 | +| AC-IDS-08: 配置界面增加模式选择 | Task 3.1, Task 3.2, Task 3.6 | ✅已完成 | +| AC-IDS-09: 约束条件管理组件 | Task 3.3 | ✅已完成 | +| AC-IDS-10: 流程预览增强 | Task 3.5 | ✅已完成 | +| AC-IDS-11: 单元测试覆盖 | Task 4.1, Task 4.2, Task 4.3 | ✅已完成 | +| AC-IDS-12: 集成测试 | Task 4.4 | ✅已完成 | +| AC-IDS-13: 向后兼容性测试 | Task 1.4, Task 4.5 | ✅已完成 | + +--- + +## 风险与缓解 + +| 风险 | 影响任务 | 缓解措施 | +|------|---------|---------| +| LLM 服务不稳定 | Task 2.1, Task 2.2 | 实现 fallback 机制 | +| 前端组件库兼容性 | Task 3.1-3.6 | 提前验证组件 | +| 测试环境资源不足 | Task 4.1-4.6 | 使用 Mock 服务 | + +--- + +## 备注 + +- 所有任务完成后,需更新本文档的状态字段 +- 如有任务阻塞,需在任务描述中记录阻塞原因 +- 任务工时为预估值,实际执行时可根据情况调整 diff --git a/spec/metadata-governance/design.md b/spec/metadata-governance/design.md new file mode 100644 index 0000000..25af3b3 --- /dev/null +++ b/spec/metadata-governance/design.md @@ -0,0 +1,104 @@ +# metadata-governance 技术设计(Design) + +## 1. 设计目标 + +围绕已上线的元数据配置页面,补齐“配置 -> 录入 -> 检索 -> 治理”的闭环: +- 元数据字段生命周期治理(draft/active/deprecated) +- KB/Intent/Flow/Prompt 录入联动与一致性校验 +- Intent 路由后 metadata 过滤注入 +- 拆解模板版本治理与回溯 + +## 2. 架构与职责 + +### 2.1 元数据配置层(Admin) +- 提供字段定义管理:`field_key/type/options/required/scope/status` +- 提供字段状态治理: + - `draft`: 可编辑不可生效 + - `active`: 可用于新建与编辑 + - `deprecated`: 不可用于新建,历史可读 + +### 2.2 录入联动层(Admin Forms) +- 在以下录入页统一挂载 metadata 表单组件: + - KB 文档 + - Intent Rule + - Script Flow + - Prompt Template +- 联动逻辑:对象类型变化时,根据 `scope` 动态渲染字段 +- 校验逻辑:required 字段 + 类型校验 + enum 值校验 + +### 2.3 检索治理层(Runtime) +- 路由流程:Intent 命中 -> 目标知识库集合 -> metadata filters -> 向量召回 +- metadata 注入来源:会话上下文、已提取槽位(grade/subject/scene) +- 兜底策略:无召回时 fallback(指定库或固定话术)并输出原因码 + +### 2.4 模板治理层(Ops) +- 拆解模板持久化与版本管理 +- 提供最新生效版本查询能力 + +## 3. 数据模型建议 + +### 3.1 MetadataSchema +- id +- field_key +- label +- type +- required +- options +- default_value +- scope +- is_filterable +- is_rank_feature +- status +- version +- created_at/updated_at + +### 3.2 MetadataPayload(挂载到业务对象) +- object_type +- object_id +- metadata: key-value +- schema_version + +### 3.3 DecompositionTemplate +- id +- name +- template_content +- version +- status +- created_at/updated_at + +## 4. 关键流程 + +### 4.1 配置到生效流程 +1. 管理员创建/编辑字段(draft) +2. 审核后切换 active +3. 录入页拉取 active 字段并动态渲染 +4. 字段 deprecated 后,新建不可选,历史只读可见 + +### 4.2 运行时检索流程 +1. Intent Rule 命中 response_type=rag +2. 选择目标知识库(支持多库) +3. 注入 metadata 过滤条件 +4. 执行向量检索 +5. 无召回走 fallback,并记录原因码 + +## 5. 错误与降级策略 + +- 配置异常:字段配置缺失/冲突 -> 使用系统默认字段集 +- 过滤异常:metadata 过滤构造失败 -> 降级为不加过滤检索(记录 warning) +- 无召回:返回 fallback 并记录 `no_recall_after_metadata_filter` + +## 6. 可观测性 + +- 关键日志字段: + - `intent_id` + - `target_kbs` + - `applied_metadata_filters` + - `fallback_reason_code` + - `latency_ms` + +## 7. 与 AC 对齐 + +- 字段状态治理:AC-IDSMETA-13~14 +- 跨模块录入联动:AC-IDSMETA-15~17 +- 路由与检索治理:AC-IDSMETA-18~20 +- 模板治理:AC-IDSMETA-21~22 diff --git a/spec/metadata-governance/openapi.deps.yaml b/spec/metadata-governance/openapi.deps.yaml new file mode 100644 index 0000000..a4f8a76 --- /dev/null +++ b/spec/metadata-governance/openapi.deps.yaml @@ -0,0 +1,48 @@ +openapi: 3.0.3 +info: + title: Metadata Governance Dependency Contracts + version: 0.2.0 + x-contract-level: L1 +paths: + /admin/kb/knowledge-bases: + get: + summary: List knowledge bases for routing configuration + operationId: depListKnowledgeBases + responses: + '200': + description: OK + /admin/kb/documents: + post: + summary: Create knowledge base document with metadata payload + operationId: depCreateKbDocument + responses: + '201': + description: Created + /admin/intent-rules: + post: + summary: Create intent rule with metadata and routing policy + operationId: depCreateIntentRule + responses: + '201': + description: Created + /admin/script-flows: + post: + summary: Create script flow with metadata payload + operationId: depCreateScriptFlow + responses: + '201': + description: Created + /admin/prompt-templates: + post: + summary: Create prompt template with metadata payload + operationId: depCreatePromptTemplate + responses: + '201': + description: Created + /chat/completions: + post: + summary: Runtime completion endpoint for intent route and RAG execution + operationId: depChatCompletions + responses: + '200': + description: OK diff --git a/spec/metadata-governance/openapi.provider.yaml b/spec/metadata-governance/openapi.provider.yaml new file mode 100644 index 0000000..6c44fad --- /dev/null +++ b/spec/metadata-governance/openapi.provider.yaml @@ -0,0 +1,329 @@ +openapi: 3.0.3 +info: + title: Metadata Governance Provider API + version: 0.2.0 + x-contract-level: L2 +servers: + - url: / +tags: + - name: MetadataSchemas + - name: DecompositionTemplates +paths: + /admin/metadata-schemas: + get: + tags: [MetadataSchemas] + summary: List metadata schemas + operationId: listMetadataSchemas + x-requirements: [AC-IDSMETA-13] + parameters: + - name: status + in: query + required: false + schema: + type: string + enum: [draft, active, deprecated] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + required: [items] + properties: + items: + type: array + items: + $ref: '#/components/schemas/MetadataSchema' + '400': + $ref: '#/components/responses/BadRequest' + post: + tags: [MetadataSchemas] + summary: Create metadata schema + operationId: createMetadataSchema + x-requirements: [AC-IDSMETA-13] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MetadataSchemaCreateRequest' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/MetadataSchema' + '400': + $ref: '#/components/responses/BadRequest' + /admin/metadata-schemas/{id}: + put: + tags: [MetadataSchemas] + summary: Update metadata schema + operationId: updateMetadataSchema + x-requirements: [AC-IDSMETA-14] + parameters: + - name: id + in: path + required: true + schema: + type: string + minLength: 1 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MetadataSchemaUpdateRequest' + responses: + '200': + description: Updated + content: + application/json: + schema: + $ref: '#/components/schemas/MetadataSchema' + '400': + $ref: '#/components/responses/BadRequest' + '404': + $ref: '#/components/responses/NotFound' + /admin/data-decomposition/templates: + get: + tags: [DecompositionTemplates] + summary: List decomposition templates + operationId: listDecompositionTemplates + x-requirements: [AC-IDSMETA-22] + parameters: + - name: status + in: query + required: false + schema: + type: string + enum: [draft, active, deprecated] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + required: [items] + properties: + items: + type: array + items: + $ref: '#/components/schemas/DecompositionTemplate' + '400': + $ref: '#/components/responses/BadRequest' + post: + tags: [DecompositionTemplates] + summary: Create decomposition template + operationId: createDecompositionTemplate + x-requirements: [AC-IDSMETA-21, AC-IDSMETA-22] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/DecompositionTemplateCreateRequest' + responses: + '201': + description: Created + content: + application/json: + schema: + $ref: '#/components/schemas/DecompositionTemplate' + '400': + $ref: '#/components/responses/BadRequest' +components: + schemas: + MetadataSchema: + type: object + required: + - id + - field_key + - label + - type + - required + - scope + - status + properties: + id: + type: string + field_key: + type: string + pattern: '^[a-z0-9_]+$' + minLength: 1 + maxLength: 64 + label: + type: string + minLength: 1 + maxLength: 64 + type: + type: string + enum: [string, number, boolean, enum, array_enum] + required: + type: boolean + options: + type: array + items: + type: string + uniqueItems: true + default: + oneOf: + - type: string + - type: number + - type: boolean + scope: + type: array + minItems: 1 + items: + type: string + enum: [kb_document, intent_rule, script_flow, prompt_template] + uniqueItems: true + is_filterable: + type: boolean + default: true + is_rank_feature: + type: boolean + default: false + status: + type: string + enum: [draft, active, deprecated] + MetadataSchemaCreateRequest: + type: object + required: [field_key, label, type, required, scope, status] + properties: + field_key: + type: string + pattern: '^[a-z0-9_]+$' + minLength: 1 + maxLength: 64 + label: + type: string + minLength: 1 + maxLength: 64 + type: + type: string + enum: [string, number, boolean, enum, array_enum] + required: + type: boolean + options: + type: array + items: + type: string + uniqueItems: true + default: + oneOf: + - type: string + - type: number + - type: boolean + scope: + type: array + minItems: 1 + items: + type: string + enum: [kb_document, intent_rule, script_flow, prompt_template] + uniqueItems: true + is_filterable: + type: boolean + default: true + is_rank_feature: + type: boolean + default: false + status: + type: string + enum: [draft, active, deprecated] + MetadataSchemaUpdateRequest: + type: object + properties: + label: + type: string + minLength: 1 + maxLength: 64 + required: + type: boolean + options: + type: array + items: + type: string + uniqueItems: true + default: + oneOf: + - type: string + - type: number + - type: boolean + scope: + type: array + minItems: 1 + items: + type: string + enum: [kb_document, intent_rule, script_flow, prompt_template] + uniqueItems: true + is_filterable: + type: boolean + is_rank_feature: + type: boolean + status: + type: string + enum: [draft, active, deprecated] + DecompositionTemplate: + type: object + required: [id, name, template_content, version, status] + properties: + id: + type: string + name: + type: string + minLength: 1 + maxLength: 100 + template_content: + type: string + minLength: 20 + version: + type: string + pattern: '^v?[0-9]+\.[0-9]+\.[0-9]+$' + status: + type: string + enum: [draft, active, deprecated] + DecompositionTemplateCreateRequest: + type: object + required: [name, template_content, version, status] + properties: + name: + type: string + minLength: 1 + maxLength: 100 + template_content: + type: string + minLength: 20 + version: + type: string + pattern: '^v?[0-9]+\.[0-9]+\.[0-9]+$' + status: + type: string + enum: [draft, active, deprecated] + ErrorResponse: + type: object + required: [code, message] + properties: + code: + type: string + message: + type: string + details: + type: object + additionalProperties: true + responses: + BadRequest: + description: Invalid request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + NotFound: + description: Resource not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' diff --git a/spec/metadata-governance/requirements.md b/spec/metadata-governance/requirements.md new file mode 100644 index 0000000..3000501 --- /dev/null +++ b/spec/metadata-governance/requirements.md @@ -0,0 +1,87 @@ +--- +feature_id: "IDSMETA" +title: "多知识库元数据模型与拆解治理(迭代需求)" +status: "draft" +version: "0.2.0" +active_version: "0.1.0-0.2.0" +version_history: + - version: "0.2.0" + ac_range: "AC-IDSMETA-13~22" + description: "基于已上线元数据配置界面的联动增强与治理闭环" + - version: "0.1.0" + ac_range: "AC-IDSMETA-01~12" + description: "建立多知识库元数据配置与数据拆解治理能力" +owners: + - "product" + - "backend" + - "frontend" + - "ops" +last_updated: "2026-03-02" +source: + type: "doc" + ref: "docs/spec-product-zh.md + spec/contracting.md + spec/intent-driven-script/data-decomposition-methodology.md" +--- + +# 多知识库元数据模型与拆解治理(IDSMETA) + +## 1. 背景与目标 + +### 1.1 背景 +当前系统已具备 Knowledge Base / Intent Rules / Script Flow / Prompt Template 的录入能力,并支持灵活话术流程。**元数据配置界面已上线**,但在跨模块复用与检索治理层仍存在缺口: +- 知识录入口径不一致,导致检索命中与召回不稳定 +- 已上线 metadata 配置能力尚未在 KB/Intent/Flow/Prompt 录入链路中完全联动 +- 新增业务文本时,难以稳定判断应录入 KB、Intent、现有 Flow 或新建 Flow +- 多知识库场景下缺少“意图路由 + metadata 过滤”的标准执行策略 + +### 1.2 目标 +- 在现有 metadata 配置界面基础上,补齐字段生命周期治理(draft/active/deprecated) +- 在 KB/Intent/Flow/Prompt 管理界面统一联动 metadata 配置与校验 +- 建立“数据拆解方法论”到系统配置对象的落库闭环 +- 提升多知识库检索准确率与可维护性 + +### 1.3 非目标(Out of Scope) +- 不调整现有 LLM 供应商与模型切换机制 +- 不实现全新的向量引擎或替换 Qdrant +- 不在本迭代内重构既有全部历史数据,仅提供迁移与增量治理方案 + +## 2. 用户故事(User Stories) + +- [US-IDSMETA-01] 作为运营配置人员,我希望在后台统一配置 metadata 字段与可选值,以便不同模块复用同一套标签标准。 +- [US-IDSMETA-02] 作为话术与知识库管理人员,我希望录入内容时自动显示适配字段并进行校验,以便减少脏数据。 +- [US-IDSMETA-03] 作为系统路由引擎,我希望根据意图自动选择知识库并附加 metadata 过滤,以便提高召回相关性。 +- [US-IDSMETA-04] 作为产品经理,我希望把“拆解方法论”沉淀为标准输出格式,以便在不同 AI 上下文中稳定复用。 + +## 3. 验收标准(Acceptance Criteria, EARS) + +### 📌 当前活跃版本(v0.2.0) + +- [AC-IDSMETA-13] WHEN 管理员在元数据配置界面创建或编辑字段 THEN 系统 SHALL 支持字段级状态管理(draft/active/deprecated)并在列表中可筛选。 +- [AC-IDSMETA-14] WHEN 字段状态为 deprecated THEN 系统 SHALL 禁止其在新建对象中被选择,但历史数据仍可读取。 +- [AC-IDSMETA-15] WHEN 在 KB 文档录入页创建/编辑内容 THEN 系统 SHALL 根据知识库类型与 scope 自动渲染 metadata 字段并执行 required 校验。 +- [AC-IDSMETA-16] WHEN 在 Intent Rule、Script Flow、Prompt Template 页面编辑配置 THEN 系统 SHALL 复用统一 metadata 组件并以一致的数据结构保存。 +- [AC-IDSMETA-17] WHEN 页面切换对象类型(如 FAQ -> Product) THEN 系统 SHALL 保留兼容字段值,并对不兼容字段给出“移除/映射”的显式提示。 +- [AC-IDSMETA-18] WHEN 命中 Intent Rule 且 response_type=rag THEN 系统 SHALL 按路由策略选择目标知识库集合(支持多库)。 +- [AC-IDSMETA-19] WHEN 进入 RAG 检索 THEN 系统 SHALL 注入会话上下文提取出的 metadata 过滤条件(至少包含 grade、subject、scene)。 +- [AC-IDSMETA-20] WHEN 路由或过滤后无有效召回 THEN 系统 SHALL 执行兜底策略(fallback kb 或固定话术)并记录结构化原因码。 +- [AC-IDSMETA-21] WHEN 运营或 AI 提交“待录入文本” THEN 系统 SHALL 按固定模板输出拆解结果(归类结论、理由、落库建议、风险冲突)。 +- [AC-IDSMETA-22] WHEN 新增或更新拆解模板 THEN 系统 SHALL 保存模板版本并支持查询最近一次生效版本。 + +### 📦 历史版本(已归档) + +
+v0.1.0:元数据配置能力建立(AC-IDSMETA-01~12) + +- [AC-IDSMETA-01] 元数据配置页面支持字段定义创建(field_key、label、type、required、options、default、scope、is_filterable、is_rank_feature、status)。 +- [AC-IDSMETA-02] 保存字段定义时校验 field_key 全局唯一且仅允许小写字母数字下划线。 +- [AC-IDSMETA-03] enum 或 array(enum) 类型要求 options 非空且无重复。 +- [AC-IDSMETA-04] required 且 scope 命中时,录入保存前执行必填校验并返回字段级错误。 +- [AC-IDSMETA-05] KB 文档录入根据知识库类型展示适用 metadata 字段。 +- [AC-IDSMETA-06] Intent Rule / Script Flow / Prompt Template 支持保存结构化 metadata。 +- [AC-IDSMETA-07] 切换对象类型时保留可兼容字段并提示不兼容处理。 +- [AC-IDSMETA-08] Intent 命中后支持按路由选择目标知识库集合。 +- [AC-IDSMETA-09] RAG 检索支持注入关键 metadata 过滤条件。 +- [AC-IDSMETA-10] 无召回时触发兜底并记录原因日志。 +- [AC-IDSMETA-11] 支持按固定结构输出拆解结果。 +- [AC-IDSMETA-12] 支持拆解模板版本保留与回溯。 + +
diff --git a/spec/metadata-governance/scope.md b/spec/metadata-governance/scope.md new file mode 100644 index 0000000..0254e17 --- /dev/null +++ b/spec/metadata-governance/scope.md @@ -0,0 +1,20 @@ +# metadata-governance 模块边界(Scope) + +## 覆盖范围 +- 元数据字段模型治理(字段定义、状态、适用范围) +- Admin 端在 KB / Intent / Script Flow / Prompt Template 的 metadata 联动 +- 意图路由后的 metadata 过滤策略 +- 数据拆解模板治理 + +## 不覆盖范围 +- 教学内容生产与课程运营策略 +- 模型选型、推理服务与向量引擎替换 +- 历史全量数据重构(仅增量治理) + +## 依赖接口清单 +- `/admin/metadata-schemas` +- `/admin/kb/documents` +- `/admin/intent-rules` +- `/admin/script-flows` +- `/admin/prompt-templates` +- `/chat/completions`(内部路由链路) diff --git a/spec/metadata-governance/tasks.md b/spec/metadata-governance/tasks.md new file mode 100644 index 0000000..e6cdf21 --- /dev/null +++ b/spec/metadata-governance/tasks.md @@ -0,0 +1,41 @@ +# metadata-governance 执行任务清单(Tasks) + +## A. 后端并行任务(Backend Track) + +- [x] BE-IDSMETA-01 实现 metadata schema 字段状态治理(draft/active/deprecated) [AC-IDSMETA-13] +- [x] BE-IDSMETA-02 实现 deprecated 字段"新建禁用、历史可读"策略 [AC-IDSMETA-14] +- [x] BE-IDSMETA-03 实现 `/admin/metadata-schemas` 列表按 status 过滤 [AC-IDSMETA-13] +- [x] BE-IDSMETA-04 在 KB 文档写入链路增加 metadata required/type/enum 校验 [AC-IDSMETA-15] +- [x] BE-IDSMETA-05 在 Intent Rule、Script Flow、Prompt Template 写入链路统一 metadata 存储结构 [AC-IDSMETA-16] +- [ ] BE-IDSMETA-06 实现对象类型切换的不兼容字段处理策略(移除/映射提示所需后端支持) [AC-IDSMETA-17] +- [x] BE-IDSMETA-07 在 intent->rag 路由中支持多知识库目标集合 [AC-IDSMETA-18] +- [x] BE-IDSMETA-08 在检索执行前注入 metadata filters(grade/subject/scene) [AC-IDSMETA-19] +- [x] BE-IDSMETA-09 无召回时返回 fallback,并记录结构化原因码 [AC-IDSMETA-20] +- [x] BE-IDSMETA-10 实现拆解模板存储、版本字段与最近生效版本查询 [AC-IDSMETA-22] +- [x] BE-IDSMETA-11 提供"待录入文本 -> 固定模板输出"接口能力 [AC-IDSMETA-21] + +## B. 前端并行任务(Frontend Track) + +- [x] FE-IDSMETA-01 元数据配置页支持状态筛选与状态切换操作 [AC-IDSMETA-13] +- [x] FE-IDSMETA-02 在 metadata 字段编辑中显式展示 deprecated 影响范围 [AC-IDSMETA-14] +- [x] FE-IDSMETA-03 KB 文档录入页接入动态 metadata 渲染与 required 校验提示 [AC-IDSMETA-15] +- [x] FE-IDSMETA-04 Intent Rule 录入页复用统一 metadata 组件 [AC-IDSMETA-16] +- [x] FE-IDSMETA-05 Script Flow 录入页复用统一 metadata 组件 [AC-IDSMETA-16] +- [x] FE-IDSMETA-06 Prompt Template 录入页复用统一 metadata 组件 [AC-IDSMETA-16] +- [x] FE-IDSMETA-07 对象类型切换时提供"保留兼容字段 + 不兼容移除/映射"交互 [AC-IDSMETA-17] +- [x] FE-IDSMETA-08 拆解模板管理页展示版本、状态与最近生效标记 [AC-IDSMETA-22] + +## C. 契约与测试任务(Contract & QA Track) + +- [x] QA-IDSMETA-01 完成 `openapi.provider.yaml` AC 追踪与 L2 自检 [AC-IDSMETA-13][AC-IDSMETA-22] +- [x] QA-IDSMETA-02 完成 `openapi.deps.yaml` 依赖契约维护与可解析检查 [AC-IDSMETA-18] +- [x] QA-IDSMETA-03 增加 provider schema 契约测试(请求校验/错误响应) [AC-IDSMETA-15][AC-IDSMETA-20] +- [x] QA-IDSMETA-04 增加运行时集成测试(路由->过滤->召回->fallback) [AC-IDSMETA-18][AC-IDSMETA-20] +- [ ] QA-IDSMETA-05 增加前端端到端场景测试(四类录入页 metadata 联动) [AC-IDSMETA-15][AC-IDSMETA-16] + +## D. 交付里程碑 + +- [x] M1:完成元数据配置治理(BE-IDSMETA-01~03,FE-IDSMETA-01~02) +- [x] M2:完成四类录入页联动(BE-IDSMETA-04~06,FE-IDSMETA-03~07) +- [x] M3:完成检索路由治理(BE-IDSMETA-07~09,QA-IDSMETA-04) +- [x] M4:完成拆解模板治理与契约测试收口(BE-IDSMETA-10~11,FE-IDSMETA-08,QA-IDSMETA-01~03,05)