350 lines
19 KiB
Python
350 lines
19 KiB
Python
"""Business-scene contracts for the platform AI routing console."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
|
|
AI_SCENE_REGISTRY: dict[str, dict[str, Any]] = {
|
|
"project_launch": {
|
|
"label": "项目启动草案",
|
|
"summary": "快速起草,失败后深度修复,结果必须进入确认",
|
|
"scene_family": "project_lifecycle",
|
|
"scene_owner": "PMFlow 项目启动链",
|
|
"lifecycle": "active",
|
|
"function_names": ["pmflow_launch_draft_v1", "project_from_text_analysis", "project_from_text_charter"],
|
|
"default_slot": "structured",
|
|
"required_slots": ["structured"],
|
|
"allowed_slots": ["structured"],
|
|
"protected": True,
|
|
"business_goal": "把一句话想法转成可确认的项目草案、初始任务和项目真相种子。",
|
|
"input_contract": "原始想法、空间上下文、已有项目约束",
|
|
"output_contract": "结构化草案 + 人工确认",
|
|
"success_criteria": ["草案字段完整", "缺失问题显式列出", "确认前不创建项目"],
|
|
"failure_policy": "结构化失败必须显式失败或进入待确认,禁止模板句冒充成功。",
|
|
"confirmation_policy": "必须进入人工确认后才写入项目主链。",
|
|
"evidence_policy": "需要结构化输出与 JSON Schema 探测证据。",
|
|
"protected_reason": "该场景会生成项目初始事实和任务,错误写入会污染后续执行主链。",
|
|
"expected_slot_key": "structured",
|
|
"expected_slot_label": "结构化槽",
|
|
},
|
|
"requirement_structuring": {
|
|
"label": "需求结构化",
|
|
"summary": "深度优先,保护项目真相层入口",
|
|
"scene_family": "project_lifecycle",
|
|
"scene_owner": "PMFlow 需求主链",
|
|
"lifecycle": "active",
|
|
"function_names": ["project_requirement_extraction", "pmflow_requirement_plan_draft", "pmflow_requirement_plan_round"],
|
|
"default_slot": "structured",
|
|
"required_slots": ["high", "structured"],
|
|
"allowed_slots": ["high", "structured"],
|
|
"protected": True,
|
|
"business_goal": "把用户需求沉淀为可追踪、可确认、可拆解的结构化需求草案。",
|
|
"input_contract": "需求文本、追问上下文、reply/thread 锚点",
|
|
"output_contract": "JSON Schema + 缺字段追问",
|
|
"success_criteria": ["业务字段来自 requirement_card", "缺字段进入追问", "不从 prose 反推业务字段"],
|
|
"failure_policy": "结构化不足时返回待确认或追问,禁止掉回普通问答链。",
|
|
"confirmation_policy": "需求 draft confirm 必须有明确锚点或卡片按钮。",
|
|
"evidence_policy": "需要结构化输出、JSON Schema 与上下文锚点证据。",
|
|
"protected_reason": "需求草案是后续任务拆解和执行确认的业务真源。",
|
|
"expected_slot_key": "structured",
|
|
"expected_slot_label": "结构化槽",
|
|
},
|
|
"task_breakdown": {
|
|
"label": "任务拆解",
|
|
"summary": "快速结构化,失败后深度修复,仍失败则标记待补充",
|
|
"scene_family": "project_lifecycle",
|
|
"scene_owner": "PMFlow 执行队列",
|
|
"lifecycle": "active",
|
|
"function_names": ["generate_task_breakdown", "decompose_tasks_from_charter", "sstc_ai_breakdown"],
|
|
"default_slot": "structured",
|
|
"required_slots": ["structured"],
|
|
"allowed_slots": ["structured"],
|
|
"protected": True,
|
|
"business_goal": "把已确认需求拆成可执行任务、依赖、责任边界和 pending 项。",
|
|
"input_contract": "需求草案、项目目标、团队能力图谱",
|
|
"output_contract": "结构化任务 + pending 标记",
|
|
"success_criteria": ["任务边界清晰", "不确定项标记 pending", "失败不冒充拆解完成"],
|
|
"failure_policy": "低阶结构化失败可升级;仍失败时必须显式 pending。",
|
|
"confirmation_policy": "高风险任务写入前需要人工确认。",
|
|
"evidence_policy": "需要结构化输出、JSON Schema 和任务字段完整性证据。",
|
|
"protected_reason": "任务拆解会直接影响执行队列和后续协同。",
|
|
"expected_slot_key": "structured",
|
|
"expected_slot_label": "结构化槽",
|
|
},
|
|
"assignee_matching": {
|
|
"label": "人员匹配",
|
|
"summary": "深度分析,必须结合人员能力图谱",
|
|
"scene_family": "execution",
|
|
"scene_owner": "PMFlow 人员能力图谱",
|
|
"lifecycle": "active",
|
|
"function_names": ["recommend_assignees_for_task"],
|
|
"default_slot": "high",
|
|
"required_slots": ["high"],
|
|
"allowed_slots": ["high"],
|
|
"protected": True,
|
|
"business_goal": "基于人员能力图谱、负载和任务要求推荐可解释负责人。",
|
|
"input_contract": "任务要求、技能图谱、团队负载",
|
|
"output_contract": "能力图谱 + 可解释推荐",
|
|
"success_criteria": ["推荐理由可解释", "能力缺口显式展示", "不跳过人员能力图谱"],
|
|
"failure_policy": "证据不足时只给待确认候选,不自动派发。",
|
|
"confirmation_policy": "负责人变更属于执行决策,需要用户确认或 reviewer 审核。",
|
|
"evidence_policy": "需要人员能力图谱、负载和任务匹配证据。",
|
|
"expected_slot_key": "high",
|
|
"expected_slot_label": "深度槽",
|
|
},
|
|
"internal_qa": {
|
|
"label": "内部问答",
|
|
"summary": "先走受控内部查询,再按复杂度组织答案",
|
|
"scene_family": "knowledge",
|
|
"scene_owner": "PMFlow 内部问答链",
|
|
"lifecycle": "active",
|
|
"function_names": ["adaptive_rag_answer_normal", "adaptive_rag_answer_deep", "rag_db_project_semantic_retrieval"],
|
|
"default_slot": "mixed",
|
|
"required_slots": ["low", "high"],
|
|
"allowed_slots": ["low", "high"],
|
|
"protected": False,
|
|
"business_goal": "基于项目真相、语义事实和知识库回答内部问题。",
|
|
"input_contract": "问题、对象绑定、内部上下文包",
|
|
"output_contract": "内部证据优先 + 来源摘要",
|
|
"success_criteria": ["先走内部证据", "来源中文化展示", "证据不足时澄清或显式不确定"],
|
|
"failure_policy": "不得让 LLM 自由编造内部结论;证据不足时返回 uncertain/clarify。",
|
|
"confirmation_policy": "只读回答不需要确认,涉及写入动作必须进入待确认。",
|
|
"evidence_policy": "需要 semantic facts、项目真相或受控检索证据。",
|
|
"expected_slot_key": "mixed",
|
|
"expected_slot_label": "快速/深度混合",
|
|
},
|
|
"external_query": {
|
|
"label": "外部实时查询",
|
|
"summary": "外部查询必须经过计划、来源校验和答案验证",
|
|
"scene_family": "external",
|
|
"scene_owner": "PMFlow 外部查询链",
|
|
"lifecycle": "active",
|
|
"function_names": ["external_query_plan", "adaptive_rag_answer"],
|
|
"default_slot": "external_query",
|
|
"required_slots": ["external_query"],
|
|
"allowed_slots": ["external_query", "high"],
|
|
"protected": True,
|
|
"business_goal": "在需要新鲜外部信息时检索、验证并用中文业务摘要呈现。",
|
|
"input_contract": "外部问题、freshness 需求、来源策略",
|
|
"output_contract": "实时来源 + verifier + freshness guard",
|
|
"success_criteria": ["来源过滤 fail-closed", "verifier 可用", "无法确认时不编造最新结论"],
|
|
"failure_policy": "外部查询失败必须显式失败或返回 freshness guard。",
|
|
"confirmation_policy": "只读外部回答不确认;接入或入库动作需要确认。",
|
|
"evidence_policy": "需要外部 provider、source filtering、verifier 和 freshness 证据。",
|
|
"protected_reason": "外部事实错误会直接影响策略判断和推荐质量。",
|
|
"expected_slot_key": "external_query",
|
|
"expected_slot_label": "外部查询槽",
|
|
},
|
|
"feishu_understanding": {
|
|
"label": "飞书理解",
|
|
"summary": "快速理解与分流,低置信度进入澄清",
|
|
"scene_family": "collaboration",
|
|
"scene_owner": "PMFlow 飞书集成",
|
|
"lifecycle": "active",
|
|
"function_names": ["feishu_level_classification", "feishu_signal_extraction", "pmflow_semantic_context_decision"],
|
|
"default_slot": "low",
|
|
"required_slots": ["low"],
|
|
"allowed_slots": ["low"],
|
|
"protected": False,
|
|
"business_goal": "从飞书消息、回复线程和卡片回流中恢复正确业务上下文。",
|
|
"input_contract": "飞书消息、reply/thread、卡片按钮、source_message_id",
|
|
"output_contract": "上下文锚点 + 主链选择",
|
|
"success_criteria": ["优先 canonical reply/thread", "不按同群旧草稿回捞", "主链选择可审计"],
|
|
"failure_policy": "锚点不足时澄清或回到中性问答,不强行进入需求链。",
|
|
"confirmation_policy": "draft confirm 必须来自显式锚点或卡片动作。",
|
|
"evidence_policy": "需要 reply/thread、work_item_id 或 active draft workspace 证据。",
|
|
"expected_slot_key": "low",
|
|
"expected_slot_label": "快速槽",
|
|
},
|
|
"feishu_reply": {
|
|
"label": "飞书回复",
|
|
"summary": "快速润色,不改变业务结论",
|
|
"scene_family": "collaboration",
|
|
"scene_owner": "PMFlow 飞书集成",
|
|
"lifecycle": "active",
|
|
"function_names": ["feishu_humanized_reply", "feishu_qa_direct_natural_reply"],
|
|
"default_slot": "low",
|
|
"required_slots": ["low"],
|
|
"allowed_slots": ["low"],
|
|
"protected": False,
|
|
"business_goal": "把业务结论改写成适合飞书对话的中文自然表达。",
|
|
"input_contract": "业务结论、回复场景、对象上下文",
|
|
"output_contract": "中文自然表达 + 不改变结论",
|
|
"success_criteria": ["不新增未证实事实", "不改变业务结论", "语气适合协作场景"],
|
|
"failure_policy": "润色失败时返回原结论或显式失败,不编造补充信息。",
|
|
"confirmation_policy": "只读回复不确认;写入项目状态仍需确认。",
|
|
"evidence_policy": "需要上游业务结论与来源摘要。",
|
|
"expected_slot_key": "low",
|
|
"expected_slot_label": "快速槽",
|
|
},
|
|
"release_review": {
|
|
"label": "发布评审",
|
|
"summary": "候选场景:发布前汇总变更、风险、验证和回滚建议",
|
|
"scene_family": "project_lifecycle",
|
|
"scene_owner": "PMFlow 发布增长链",
|
|
"lifecycle": "candidate",
|
|
"function_names": [],
|
|
"default_slot": "",
|
|
"required_slots": [],
|
|
"allowed_slots": [],
|
|
"protected": False,
|
|
"business_goal": "把一次发布前的变更、验证证据、风险和回滚方案组织成可审查结论。",
|
|
"input_contract": "变更集、验证记录、失败样本、项目目标",
|
|
"output_contract": "发布评审摘要 + 风险清单 + 回滚建议",
|
|
"success_criteria": ["风险可追踪", "验证证据可解释", "回滚建议不冒充自动发布"],
|
|
"failure_policy": "证据不足时标记待补充,不生成发布通过结论。",
|
|
"confirmation_policy": "发布结论必须由负责人确认。",
|
|
"evidence_policy": "需要变更集、测试/验证和失败样本证据。",
|
|
"expected_slot_key": "high",
|
|
"expected_slot_label": "深度槽",
|
|
},
|
|
"retrospective_summary": {
|
|
"label": "项目复盘摘要",
|
|
"summary": "候选场景:从执行记录和结果信号生成复盘草案",
|
|
"scene_family": "project_lifecycle",
|
|
"scene_owner": "PMFlow 复盘链",
|
|
"lifecycle": "candidate",
|
|
"function_names": [],
|
|
"default_slot": "",
|
|
"required_slots": [],
|
|
"allowed_slots": [],
|
|
"protected": False,
|
|
"business_goal": "把项目结果、执行轨迹和关键偏差整理为可确认复盘。",
|
|
"input_contract": "项目目标、任务结果、发布数据、团队反馈",
|
|
"output_contract": "结构化复盘草案 + 改进行动",
|
|
"success_criteria": ["结论有证据", "改进项可执行", "不把推测写成事实"],
|
|
"failure_policy": "证据不足时只输出待补充项。",
|
|
"confirmation_policy": "复盘写回项必须人工确认。",
|
|
"evidence_policy": "需要执行、发布和反馈证据。",
|
|
"expected_slot_key": "long_context",
|
|
"expected_slot_label": "长上下文槽",
|
|
},
|
|
"change_review": {
|
|
"label": "变更审查",
|
|
"summary": "从项目主链消息抽取待审变更,写回前必须人工确认",
|
|
"scene_family": "project_lifecycle",
|
|
"scene_owner": "PMFlow Change Review",
|
|
"lifecycle": "active",
|
|
"function_names": ["pmflow_change_review_extraction_v1"],
|
|
"default_slot": "structured",
|
|
"required_slots": ["structured"],
|
|
"allowed_slots": ["structured"],
|
|
"protected": True,
|
|
"business_goal": "把项目主链里的新增诉求、风险、任务和决策抽取成 ChangeSet 待审对象。",
|
|
"input_contract": "项目线程消息、附件摘要、可选对象锚点",
|
|
"output_contract": "结构化 proposed_items + evidence + missing_info",
|
|
"success_criteria": ["候选对象来自本轮消息证据", "风险分级清楚", "不自动提交变更"],
|
|
"failure_policy": "结构化失败或证据不足时显式失败/待补充,禁止创建模板 ChangeSet。",
|
|
"confirmation_policy": "写回或提交变更必须确认。",
|
|
"evidence_policy": "需要项目线程消息证据和结构化输出证据。",
|
|
"protected_reason": "该场景会生成可写回项目事实和任务的待审对象,误抽取会污染项目主链。",
|
|
"expected_slot_key": "structured",
|
|
"expected_slot_label": "结构化槽",
|
|
},
|
|
"project_memory_writeback": {
|
|
"label": "项目记忆写回",
|
|
"summary": "候选场景:把已确认结论写入项目记忆和语义事实",
|
|
"scene_family": "knowledge",
|
|
"scene_owner": "PMFlow 记忆层",
|
|
"lifecycle": "candidate",
|
|
"function_names": [],
|
|
"default_slot": "",
|
|
"required_slots": [],
|
|
"allowed_slots": [],
|
|
"protected": False,
|
|
"business_goal": "把已确认业务结论转成可审计、可撤销的项目记忆写回计划。",
|
|
"input_contract": "确认后的业务结论、来源摘要、对象绑定",
|
|
"output_contract": "写回计划 + 证据引用 + 待确认",
|
|
"success_criteria": ["只写确认事实", "来源可追踪", "可撤销"],
|
|
"failure_policy": "来源不足时禁止写回。",
|
|
"confirmation_policy": "写回动作必须人工确认。",
|
|
"evidence_policy": "需要确认卡片、来源摘要和对象绑定证据。",
|
|
"expected_slot_key": "structured",
|
|
"expected_slot_label": "结构化槽",
|
|
},
|
|
"mcp_execution_planning": {
|
|
"label": "MCP 执行规划",
|
|
"summary": "候选场景:为本地或外部工具执行生成受控计划",
|
|
"scene_family": "execution",
|
|
"scene_owner": "PMFlow 工具执行层",
|
|
"lifecycle": "candidate",
|
|
"function_names": [],
|
|
"default_slot": "",
|
|
"required_slots": [],
|
|
"allowed_slots": [],
|
|
"protected": False,
|
|
"business_goal": "把用户意图转成受控工具执行计划、权限边界和确认点。",
|
|
"input_contract": "用户意图、工具目录、权限和环境约束",
|
|
"output_contract": "工具执行计划 + 权限确认",
|
|
"success_criteria": ["命令可解释", "权限边界清楚", "危险动作确认"],
|
|
"failure_policy": "工具能力或权限不足时显式失败。",
|
|
"confirmation_policy": "本机执行、写操作和外部副作用必须确认。",
|
|
"evidence_policy": "需要工具目录、权限和运行环境证据。",
|
|
"expected_slot_key": "tool",
|
|
"expected_slot_label": "工具槽",
|
|
},
|
|
"contract_sync": {
|
|
"label": "合同同步",
|
|
"summary": "候选场景:把外部规范或契约同步为内部可用上下文",
|
|
"scene_family": "knowledge",
|
|
"scene_owner": "PMFlow 契约同步",
|
|
"lifecycle": "candidate",
|
|
"function_names": [],
|
|
"default_slot": "",
|
|
"required_slots": [],
|
|
"allowed_slots": [],
|
|
"protected": False,
|
|
"business_goal": "把外部文档、接口契约或流程规范同步成可审计上下文。",
|
|
"input_contract": "外部文档、接口契约、同步来源",
|
|
"output_contract": "结构化契约摘要 + 差异说明",
|
|
"success_criteria": ["来源明确", "差异可审查", "不覆盖未确认契约"],
|
|
"failure_policy": "解析或来源校验失败时不写入。",
|
|
"confirmation_policy": "同步写入必须确认。",
|
|
"evidence_policy": "需要来源、版本和解析证据。",
|
|
"expected_slot_key": "long_context",
|
|
"expected_slot_label": "长上下文槽",
|
|
},
|
|
}
|
|
|
|
|
|
def scene_contract(scene_key: str) -> dict[str, Any]:
|
|
scene = AI_SCENE_REGISTRY.get(str(scene_key or "").strip())
|
|
if not scene:
|
|
return {
|
|
"scene_key": scene_key,
|
|
"label": scene_key,
|
|
"business_goal": "该场景由 PMFlow AI 运行层按业务语义触发。",
|
|
"input_contract": "业务上下文",
|
|
"output_contract": "显式成功 / 显式失败 / 待确认",
|
|
"success_criteria": ["输出可解释", "失败显式表达", "不绕过保护边界"],
|
|
"failure_policy": "证据不足或结构化不足时必须显式失败、澄清或进入待确认。",
|
|
"confirmation_policy": "涉及写入、派发或发布的动作必须人工确认。",
|
|
"evidence_policy": "需要对应场景的上下文、能力槽位和运行证据。",
|
|
"protected_reason": None,
|
|
"expected_slot_key": "",
|
|
"expected_slot_label": "按场景所需能力选择槽位",
|
|
"scene_family": "unknown",
|
|
"scene_owner": "PMFlow AI 运行层",
|
|
"lifecycle": "active",
|
|
"protected": False,
|
|
}
|
|
return {
|
|
"scene_key": scene_key,
|
|
"label": scene["label"],
|
|
"business_goal": scene["business_goal"],
|
|
"input_contract": scene["input_contract"],
|
|
"output_contract": scene["output_contract"],
|
|
"success_criteria": list(scene["success_criteria"]),
|
|
"failure_policy": scene["failure_policy"],
|
|
"confirmation_policy": scene["confirmation_policy"],
|
|
"evidence_policy": scene["evidence_policy"],
|
|
"protected_reason": scene.get("protected_reason"),
|
|
"expected_slot_key": scene.get("expected_slot_key", ""),
|
|
"expected_slot_label": scene.get("expected_slot_label", "按场景所需能力选择槽位"),
|
|
"scene_family": scene.get("scene_family", "unknown"),
|
|
"scene_owner": scene.get("scene_owner", "PMFlow AI 运行层"),
|
|
"lifecycle": scene.get("lifecycle", "active"),
|
|
"protected": bool(scene.get("protected", False)),
|
|
}
|