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

7.3 KiB
Raw Permalink Blame History

提取策略体系升级改造总结

[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() 方法(校验策略链)
  • 更新 SlotDefinitionCreateSlotDefinitionUpdate 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

四、数据兼容性

读取兼容

# 优先使用 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_strategiesextract_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推断

编辑页

  • 策略链编辑器支持:
    • 拖拽调整顺序
    • 添加策略(下拉选择,自动去重)
    • 删除策略
    • 清空策略链
  • 实时校验策略链有效性

七、使用示例

创建带策略链的槽位定义

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="请告诉我您的年级",
)

执行策略链提取

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. 执行数据库迁移

    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

十、验证清单

  • 数据库迁移脚本可执行
  • 后端实体模型支持策略链
  • 后端API支持策略链CRUD
  • 运行时策略链执行器工作正常
  • 失败分类和日志追踪完整
  • 旧数据兼容读取
  • 前端界面支持策略链排序配置
  • 前端构建成功
  • 所有测试通过38个

改造完成时间: 2026-03-06 改造状态: 全部完成