# 提取策略体系升级改造总结 ## [AC-MRS-07-UPGRADE] 提取策略链改造 --- ## 一、改造目标 将槽位定义的提取策略从"单选(extract_strategy)"升级为"可排序策略链(extract_strategies)",并在运行时按顺序执行,直到成功提取并通过校验。 ### 核心改进 - ✅ 支持策略链配置,如 `[user_input, rule, llm]` - ✅ 运行时按优先级顺序执行 - ✅ 统一失败分类和日志追踪 - ✅ 完全兼容旧数据 --- ## 二、改造范围 ### 1. 数据库层 **文件**: `scripts/migrations/009_add_extract_strategies.sql` - 新增 `extract_strategies` JSONB 字段 - 数据迁移:将旧 `extract_strategy` 转换为数组格式 - 保留旧字段用于兼容读取 ### 2. 后端实体层 **文件**: `app/models/entities.py` - 新增 `ExtractFailureType` 枚举(4种失败类型) - `SlotDefinition` 模型新增 `extract_strategies` 字段 - 添加 `get_effective_strategies()` 方法(兼容读取) - 添加 `validate_strategies()` 方法(校验策略链) - 更新 `SlotDefinitionCreate` 和 `SlotDefinitionUpdate` Schema ### 3. 后端服务层 **文件**: `app/services/slot_definition_service.py` - 新增 `_validate_strategies()` 方法 - 新增 `_normalize_strategies()` 方法 - 创建/更新时支持策略链校验和处理 - 同时保存新旧字段 **文件**: `app/services/mid/slot_strategy_executor.py` (新增) - `SlotStrategyExecutor` 策略链执行器 - `StrategyChainResult` 执行结果 - `StrategyStepResult` 单步结果 - `ExtractContext` 提取上下文 - 支持 4 种失败类型分类 - 详细的执行日志追踪 ### 4. 后端 API 层 **文件**: `app/api/admin/slot_definition.py` - 更新 `_slot_to_dict()` 返回策略链字段 **文件**: `app/schemas/metadata.py` - 更新 `SlotDefinitionResponse` 响应模型 - 更新 `SlotDefinitionCreateRequest` 请求模型 - 更新 `SlotDefinitionUpdateRequest` 请求模型 **文件**: `app/services/mid/role_based_field_provider.py` - 更新 `get_slot_definitions_by_role()` 返回策略链字段 ### 5. 前端类型层 **文件**: `ai-service-admin/src/types/slot-definition.ts` - 新增 `ExtractFailureType` 类型 - 更新 `SlotDefinition` 接口 - 更新 `SlotDefinitionCreateRequest` 接口 - 更新 `SlotDefinitionUpdateRequest` 接口 - 新增 `StrategyStepResult` 接口 - 新增 `StrategyChainResult` 接口 - 新增 `validateExtractStrategies()` 函数 - 新增 `getEffectiveStrategies()` 函数 ### 6. 前端页面层 **文件**: `ai-service-admin/src/views/admin/slot-definition/index.vue` - 表格列改为显示策略链(带序号) - 新增策略链编辑器组件 - 拖拽排序(vuedraggable) - 添加/删除策略 - 策略去重校验 - 表单提交时校验策略链 --- ## 三、执行语义 ### 策略链执行流程 ``` 1. 按数组顺序执行策略 2. 某一步成功提取且校验通过 -> 停止并返回结果 3. 当前策略失败 -> 记录失败原因,继续下一策略 4. 全部失败 -> 返回结构化失败结果,并使用 ask_back_prompt ``` ### 失败分类(统一) | 失败类型 | 说明 | |---------|------| | `EXTRACT_EMPTY` | 提取结果为空 | | `EXTRACT_PARSE_FAIL` | 解析失败 | | `EXTRACT_VALIDATION_FAIL` | 校验失败 | | `EXTRACT_RUNTIME_ERROR` | 运行时错误 | ### 日志追踪 每步执行都有可追踪日志: ``` [SlotStrategyExecutor] Starting strategy chain for slot 'grade': strategies=['rule', 'llm'], tenant=xxx [SlotStrategyExecutor] Executing step 1/2: slot_key=grade, strategy=rule [SlotStrategyExecutor] Step 1 failed: slot_key=grade, strategy=rule, failure_type=EXTRACT_EMPTY, reason=... [SlotStrategyExecutor] Strategy chain succeeded at step 2: slot_key=grade, strategy=llm, total_time_ms=123.45 ``` --- ## 四、数据兼容性 ### 读取兼容 ```python # 优先使用 extract_strategies,如果不存在则兼容读取 extract_strategy def get_effective_strategies(self) -> list[str]: if self.extract_strategies and len(self.extract_strategies) > 0: return self.extract_strategies if self.extract_strategy: return [self.extract_strategy] return [] ``` ### 写入策略 - 新数据:同时写入 `extract_strategies` 和 `extract_strategy` - 旧数据:通过 migration 自动转换 --- ## 五、测试覆盖 ### 新增测试文件 **文件**: `tests/test_slot_strategy_executor.py` - ✅ 第一步成功时停止 - ✅ 第一步失败,第二步成功 - ✅ 所有策略都失败 - ✅ 校验失败的情况 - ✅ 运行时错误处理 - ✅ 空策略链处理 - ✅ 未知策略处理 - ✅ 结果转换为字典 - ✅ 便捷函数测试 - ✅ 上下文创建测试 ### 现有测试 - ✅ `tests/test_slot_definition_service.py` - 16个测试全部通过 - ✅ `tests/test_role_based_field_provider.py` - 11个测试全部通过 **总计**: 38个测试全部通过 ✅ --- ## 六、前端界面预览 ### 列表页 - 提取策略链列显示带序号的策略标签 - 如:`1. 规则提取` `2. LLM推断` ### 编辑页 - 策略链编辑器支持: - 拖拽调整顺序 - 添加策略(下拉选择,自动去重) - 删除策略 - 清空策略链 - 实时校验策略链有效性 --- ## 七、使用示例 ### 创建带策略链的槽位定义 ```python from app.models.entities import SlotDefinitionCreate slot_create = SlotDefinitionCreate( slot_key="grade", type="string", required=True, extract_strategies=["rule", "llm", "user_input"], # 策略链 ask_back_prompt="请告诉我您的年级", ) ``` ### 执行策略链提取 ```python from app.services.mid.slot_strategy_executor import execute_extract_strategies result = await execute_extract_strategies( strategies=["rule", "llm", "user_input"], tenant_id="tenant-123", slot_key="grade", user_input="我想了解初一语文课程", validation_rule=r"^初[一二三]$", ) if result.success: print(f"提取成功: {result.final_value} (使用策略: {result.final_strategy})") else: print(f"提取失败,需要追问: {result.ask_back_prompt}") for step in result.steps: print(f" {step.strategy}: {step.failure_type} - {step.failure_reason}") ``` --- ## 八、迁移步骤 1. **执行数据库迁移** ```bash psql -d your_database -f scripts/migrations/009_add_extract_strategies.sql ``` 2. **重启后端服务** - 自动加载新模型和API 3. **刷新前端页面** - 自动显示策略链编辑器 --- ## 九、文件变更清单 ### 新增文件 - `scripts/migrations/009_add_extract_strategies.sql` - `app/services/mid/slot_strategy_executor.py` - `tests/test_slot_strategy_executor.py` - `docs/extract-strategy-upgrade-summary.md` ### 修改文件 - `app/models/entities.py` - `app/schemas/metadata.py` - `app/services/slot_definition_service.py` - `app/api/admin/slot_definition.py` - `app/services/mid/role_based_field_provider.py` - `ai-service-admin/src/types/slot-definition.ts` - `ai-service-admin/src/views/admin/slot-definition/index.vue` --- ## 十、验证清单 - [x] 数据库迁移脚本可执行 - [x] 后端实体模型支持策略链 - [x] 后端API支持策略链CRUD - [x] 运行时策略链执行器工作正常 - [x] 失败分类和日志追踪完整 - [x] 旧数据兼容读取 - [x] 前端界面支持策略链排序配置 - [x] 前端构建成功 - [x] 所有测试通过(38个) --- **改造完成时间**: 2026-03-06 **改造状态**: ✅ 全部完成