refactor(server): steward 意图改用声明式注册表编排

- 新增 steward_intent_registry,IntentDescriptor 统一描述意图的识别关键词、动作步骤构建、字段白名单与副作用集合,替代分散的 if/else
- 新增 steward_intent_bootstrap 注册 expense_application 等意图;新增 steward_query_executors 提供差旅标准查询的无副作用执行与城市/席别标签化输出
- action_contracts/action_executor/graph_planner/intent_agent/model_plan_builder/planner_extraction/fallback 适配注册表,识别与执行分发自动从注册表取数
- 新增 intent_registry/query_executors 测试,更新 intent_agent 测试
This commit is contained in:
caoxiaozhu
2026-06-25 11:50:02 +08:00
parent d321005044
commit eaada4bc57
15 changed files with 1023 additions and 54 deletions

View File

@@ -25,6 +25,44 @@ from app.services.steward_planner_shared import (
)
def _matches_query_signal(compact: str) -> bool:
"""判断输入是否命中查询类意图信号词(差旅标准等)。
查询意图不应进入申请/报销候选流程确认,也不应被当作普通业务输入走规则兜底。
"""
from app.services.steward_intent_registry import all_signal_keywords
query_indicators = ("标准", "补助", "补贴", "差标", "政策", "制度", "多少")
if not any(indicator in compact for indicator in query_indicators):
return False
signal_keywords = all_signal_keywords()
return any(keyword in compact for keyword in signal_keywords)
def _resolve_assigned_agent_for_draft(task_type: str) -> str:
"""从注册表取 assigned_agent,查不到时回退到申请/报销默认值。"""
from app.services.steward_intent_registry import get_intent
intent = get_intent(task_type)
if intent is not None:
return intent.assigned_agent
if task_type == "expense_application":
return "application_assistant"
return "reimbursement_assistant"
def _resolve_task_label_for_draft(task_type: str) -> str:
"""从注册表取意图中文标签,查不到时回退到申请/报销默认值。"""
from app.services.steward_intent_registry import get_intent
intent = get_intent(task_type)
if intent is not None:
return intent.label
if task_type == "expense_application":
return "费用申请"
return "费用报销"
class StewardPlannerExtractionMixin:
def _has_multiple_financial_demands(self, message: str) -> bool:
task_drafts = self._extract_task_drafts(message)
@@ -89,6 +127,9 @@ class StewardPlannerExtractionMixin:
compact = re.sub(r"\s+", "", text)
if not compact or request.attachments:
return False
# 查询类意图(差旅标准等)不走申请/报销候选流程确认
if _matches_query_signal(compact):
return False
if re.search(r"申请|报销|草稿|提交|审批|保存|发起|创建", compact):
return False
if not re.search(r"出差|差旅|客户现场|项目|部署|实施|支撑|支持|协助|拜访|调研|培训|会议|驻场|上线|验收", compact):
@@ -115,15 +156,13 @@ class StewardPlannerExtractionMixin:
base_date: date,
request: StewardPlanRequest,
) -> StewardTask:
from app.services.steward_model_plan_builder import StewardModelPlanBuilder
fields = self._extract_ontology_fields(draft.segment, draft.task_type, base_date, request)
missing_fields = self._resolve_missing_fields(draft.task_type, fields)
task_id = f"task_{'app' if draft.task_type == 'expense_application' else 'reim'}_{draft.index:03d}"
assigned_agent = (
"application_assistant"
if draft.task_type == "expense_application"
else "reimbursement_assistant"
)
title_prefix = "费用申请" if draft.task_type == "expense_application" else "费用报销"
task_id = StewardModelPlanBuilder._build_task_id(draft.task_type, draft.index)
assigned_agent = _resolve_assigned_agent_for_draft(draft.task_type)
title_prefix = _resolve_task_label_for_draft(draft.task_type)
title = self._build_task_title(title_prefix, fields, draft.index)
return StewardTask(
task_id=task_id,