ai-robot-core/docs/extract-strategy-upgrade-su...

268 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 提取策略体系升级改造总结
## [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
**改造状态**: ✅ 全部完成