spec: add metadata-governance module specification [AC-IDSMETA-13~22]

This commit is contained in:
MerCry 2026-03-02 22:14:02 +08:00
parent e10cbc2321
commit e179abd0e5
12 changed files with 3502 additions and 0 deletions

View File

@ -0,0 +1,214 @@
# 多知识库与数据拆解方法论(用于 Intent-Driven Script 系统)
## 1. 当前落地建议(先执行)
### 1.1 建议创建的知识库数量与定位
建议先建 **4 个核心知识库 + 1 个兜底库(可选)**
1. **KB_PRODUCTproduct课程产品库**
- 放什么:课程模块、年级适配、学科能力点、学习路径、阶段价值
- 不放什么:退款政策、隐私条款、运营口径说明
2. **KB_PARENT_COMMscript/general家长沟通素材库**
- 放什么:家长痛点表达、共情语料、自然过渡语、解释型话术素材
- 不放什么:硬规则、流程跳转条件
3. **KB_FAQfaq高频问答库**
- 放什么:价格、班型、课时、上课形式、效果周期等标准问答
- 不放什么:长篇教育理念、复杂诊断内容
4. **KB_POLICYpolicy合规与边界库**
- 放什么:承诺边界、敏感词、隐私说明、不可承诺清单
- 不放什么:销售话术素材
5. **KB_GENERALgeneral可选兜底知识库**
- 放什么:跨场景通识内容、无法明确归属但需保留的信息
- 不放什么:高频关键知识(应尽量归入前 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 和路由提升质量,再考虑扩大知识库数量。

View File

@ -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
<template>
<el-form-item label="话术模式">
<el-radio-group v-model="currentStep.script_mode">
<el-radio-button
v-for="option in SCRIPT_MODE_OPTIONS"
:key="option.value"
:label="option.value"
>
{{ option.label }}
<el-tooltip :content="option.description">
<el-icon><QuestionFilled /></el-icon>
</el-tooltip>
</el-radio-button>
</el-radio-group>
</el-form-item>
<!-- 固定模式 -->
<template v-if="currentStep.script_mode === 'fixed'">
<el-form-item label="话术内容" required>
<el-input
v-model="currentStep.content"
type="textarea"
:rows="3"
placeholder="输入固定话术内容"
/>
</el-form-item>
</template>
<!-- 灵活模式 -->
<template v-if="currentStep.script_mode === 'flexible'">
<el-form-item label="步骤意图" required>
<el-input
v-model="currentStep.intent"
placeholder="例如:获取用户姓名"
/>
</el-form-item>
<el-form-item label="意图说明">
<el-input
v-model="currentStep.intent_description"
type="textarea"
:rows="2"
placeholder="详细描述这一步的目的和期望效果"
/>
</el-form-item>
<el-form-item label="话术约束">
<ConstraintManager v-model="currentStep.script_constraints" />
</el-form-item>
<el-form-item label="Fallback话术" required>
<el-input
v-model="currentStep.content"
type="textarea"
:rows="2"
placeholder="AI生成失败时使用的备用话术"
/>
</el-form-item>
</template>
<!-- 模板模式 -->
<template v-if="currentStep.script_mode === 'template'">
<el-form-item label="话术模板" required>
<el-input
v-model="currentStep.content"
type="textarea"
:rows="3"
placeholder="使用 {变量名} 标记可变部分,例如:您好{user_name},请问您{inquiry_style}"
/>
<div class="template-hint">
提示:使用 {变量名} 标记需要AI填充的部分
</div>
</el-form-item>
</template>
</template>
```
#### 2.2.3 约束管理组件
**文件位置**: `ai-service-admin/src/views/admin/script-flow/components/ConstraintManager.vue`
```vue
<template>
<div class="constraint-manager">
<div class="constraint-tags">
<el-tag
v-for="(constraint, index) in modelValue"
:key="index"
closable
@close="removeConstraint(index)"
>
{{ constraint }}
</el-tag>
</div>
<el-input
v-model="newConstraint"
placeholder="输入约束条件后按回车添加"
@keyup.enter="addConstraint"
class="constraint-input"
>
<template #append>
<el-button @click="addConstraint">添加</el-button>
</template>
</el-input>
<div class="constraint-presets">
<span class="preset-label">常用约束:</span>
<el-button
v-for="preset in PRESET_CONSTRAINTS"
:key="preset"
size="small"
@click="addPreset(preset)"
>
{{ preset }}
</el-button>
</div>
</div>
</template>
<script setup lang="ts">
const PRESET_CONSTRAINTS = [
'必须礼貌',
'语气自然',
'简洁明了',
'不要生硬',
'不要重复'
]
const addConstraint = () => {
if (newConstraint.value.trim()) {
emit('update:modelValue', [...modelValue.value, newConstraint.value.trim()])
newConstraint.value = ''
}
}
</script>
```
---
## 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. **性能**: 步骤数量通常不多(<20JSON 查询性能足够
**权衡**: 无法对意图字段建立索引,但实际场景中不需要按意图查询流程
### 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 测试
- 基于历史数据的话术优化建议

View File

@ -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 保存模板版本并支持查询最近一次生效版本。
---
### 📦 历史版本(已归档)
<details>
<summary>v0.1.0元数据配置能力建立AC-IDSMETA-01~12</summary>
- [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] 支持拆解模板版本保留与回溯。
</details>
---
## 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 界面能力固化(状态管理/弃用策略)
- M2KB/Intent/Flow/Prompt 四处统一接入 metadata 组件与校验
- M3意图路由+metadata 检索与 fallback 日志闭环
- M4拆解模板版本治理与回溯能力
### 10.2 验收样例(建议)
- 样例 1录入“初二痛点&方案”,系统输出主归类=KB_PRODUCTmetadata 自动建议grade=8, scene=pain_point
- 样例 2命中“初二成绩下滑怎么办”意图时路由至 `product + parent_comm` 且过滤 `grade=8`
- 样例 3字段 `flow_step` 被标记 deprecated 后,不可在新建对象选择,但历史对象仍可展示原值
- 样例 4无召回时返回 fallback 并记录 `no_recall_after_metadata_filter`

View File

@ -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)

View File

@ -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 需求文档
```

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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 保存模板版本并支持查询最近一次生效版本。
### 📦 历史版本(已归档)
<details>
<summary>v0.1.0元数据配置能力建立AC-IDSMETA-01~12</summary>
- [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] 支持拆解模板版本保留与回溯。
</details>

View File

@ -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`(内部路由链路)

View File

@ -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 filtersgrade/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~03FE-IDSMETA-01~02
- [x] M2完成四类录入页联动BE-IDSMETA-04~06FE-IDSMETA-03~07
- [x] M3完成检索路由治理BE-IDSMETA-07~09QA-IDSMETA-04
- [x] M4完成拆解模板治理与契约测试收口BE-IDSMETA-10~11FE-IDSMETA-08QA-IDSMETA-01~03,05