文档阅读区

AI Actions 设计

版本: v0.5.0
日期: 2025-12-17
说明: AI Actions 详细设计文档


一、概述

1.1 定位

AI Actions 是 Core 平台提供的只读 AI 动作类型,用于在规则中调用 LLM 生成草稿和洞察。

1.2 核心原则

  • 只读:不允许模型直接改 Task/Rule/Config
  • 草稿输出:输出只写 ai_insights/docs_drafts,并发 ai.* 事件
  • 人工确认:必须人工确认后才能落地为真实实体
  • 全审计:所有 AI 调用都有完整的审计记录

二、Action 类型

2.1 invoke_llm_summary

用途:对 alert / event thread 做摘要、建议

定义

action:
  type: invoke_llm_summary
  prompt_template: ops.alert_analysis@1.0.0
  context_refs:
    alertIds: ["{{alert.id}}"]
    eventIds: ["{{alert.related_event_ids}}"]
  output_schema:
    type: object
    properties:
      summary: string
      possible_causes: array
      suggestions: array
  target_type: ai_insight  # 写入 ai_insight 实体

执行流程

  1. 解析 action 定义
  2. 调用 LLM Gateway(组装上下文、渲染 Prompt、调用 LLM)
  3. 校验输出(使用 output_schema)
  4. 创建 ai_insight 实体
  5. 生成 ai.insight.created 事件
  6. 记录审计日志

2.2 invoke_llm_report

用途:日报/周报生成

定义

action:
  type: invoke_llm_report
  prompt_template: project-mngt.weekly_report@1.0.0
  context_refs:
    entityIds: ["{{project.id}}"]
    timeRange: {"start": "week_start", "end": "week_end"}
  output_schema:
    type: object
    properties:
      report: string
      highlights: array
      risks: array
  target_type: document_draft  # 写入 document_draft 实体

执行流程

  1. 解析 action 定义
  2. 调用 LLM Gateway
  3. 校验输出
  4. 创建 document_draft 实体
  5. 生成 ai.document_draft.created 事件
  6. 记录审计日志

2.3 invoke_llm_generate_doc

用途:会议纪要/PRD/里程碑草案/任务拆解输出为"草稿"

定义

action:
  type: invoke_llm_generate_doc
  prompt_template: project-mngt.meeting_minutes@1.0.0
  context_refs:
    eventIds: ["{{meeting.event_ids}}"]
    entityIds: ["{{meeting.id}}"]
  output_schema:
    type: object
    properties:
      content: string
      action_items: array
  target_type: document_draft  # 写入草稿,不直接创建实体

执行流程

  1. 解析 action 定义
  2. 调用 LLM Gateway
  3. 校验输出
  4. 创建 document_draft 实体
  5. 生成 ai.document_draft.created 事件
  6. 记录审计日志

三、实现设计

3.1 Action Executor 扩展

位置: backend/app/kernel/actions/executor.py

新增方法

class ActionExecutor:
    async def _execute_invoke_llm_summary(
        self,
        action_def: Dict[str, Any],
        context: Dict[str, Any],
    ) -> Dict[str, Any]:
        """执行 invoke_llm_summary Action"""
        # 1. 解析 action 定义
        prompt_template_id = action_def["prompt_template"]
        context_refs = action_def.get("context_refs", {})
        variables = action_def.get("variables", {})
        output_schema = action_def.get("output_schema")
        target_type = action_def.get("target_type", "ai_insight")
        
        # 2. 调用 LLM Gateway
        llm_gateway = LLMGateway()
        result = await llm_gateway.chat(
            prompt_template_id=prompt_template_id,
            context_refs=context_refs,
            variables=variables,
        )
        
        # 3. 校验输出
        if output_schema:
            validator = OutputValidator()
            is_valid, error, parsed = validator.validate(
                result["content"],
                output_schema,
            )
            if not is_valid:
                raise ValueError(f"Output validation failed: {error}")
        
        # 4. 创建实体
        entity_service = EntityService()
        entity = await entity_service.create(
            type_id=target_type,
            data={
                "content": result["content"],
                "parsed": parsed,
                "source": "ai",
                "prompt_template_id": prompt_template_id,
            },
        )
        
        # 5. 生成事件
        event_service = EventService()
        await event_service.record(
            event_type="ai.insight.created",
            entity_id=entity.id,
            payload={
                "ai_insight_id": entity.id,
                "prompt_template_id": prompt_template_id,
            },
        )
        
        # 6. 记录审计
        await self._record_ai_action_audit(
            action_type="invoke_llm_summary",
            prompt_template_id=prompt_template_id,
            context_refs=context_refs,
            result=result,
            entity_id=entity.id,
        )
        
        return {
            "status": "success",
            "entity_id": entity.id,
            "result": result,
        }
    
    async def _execute_invoke_llm_report(
        self,
        action_def: Dict[str, Any],
        context: Dict[str, Any],
    ) -> Dict[str, Any]:
        """执行 invoke_llm_report Action"""
        # 类似 invoke_llm_summary,但 target_type 是 document_draft
        pass
    
    async def _execute_invoke_llm_generate_doc(
        self,
        action_def: Dict[str, Any],
        context: Dict[str, Any],
    ) -> Dict[str, Any]:
        """执行 invoke_llm_generate_doc Action"""
        # 类似 invoke_llm_summary,但 target_type 是 document_draft
        pass

3.2 约束检查

位置: backend/app/kernel/actions/executor.py

实现

class ActionExecutor:
    def _check_ai_action_constraints(
        self,
        action_type: str,
        target_type: str,
    ):
        """
        检查 AI Action 约束
        
        v0.5 约束:
        - 不允许直接改 Task/Rule/Config
        - 只允许写入 ai_insight/document_draft
        """
        # 禁止的类型
        forbidden_types = ["task", "rule", "config", "project", "alert"]
        
        if target_type in forbidden_types:
            raise ValueError(
                f"AI Action cannot directly modify {target_type}. "
                f"Use ai_insight or document_draft instead."
            )
        
        # 允许的类型
        allowed_types = ["ai_insight", "document_draft"]
        
        if target_type not in allowed_types:
            raise ValueError(
                f"AI Action target_type must be one of {allowed_types}, "
                f"got {target_type}"
            )

四、类型定义

4.1 ai_insight 类型

位置: apps/core/domain/types/ai_insight.yaml

定义

- id: ai_insight
  name: AI 洞察
  description: AI 生成的洞察和建议
  schema:
    properties:
      content:
        type: string
        description: 洞察内容
      parsed:
        type: object
        description: 解析后的结构化数据
      source:
        type: string
        enum: [ai]
        description: 来源
      prompt_template_id:
        type: string
        description: Prompt 模板 ID
      related_entity_ids:
        type: array
        items:
          type: string
        description: 关联的实体 ID 列表
    required: [content, source]
  lifecycle:
    states: [active, archived]
    transitions:
      - from: active
        to: archived
  allowedEvents:
    - ai.insight.created
    - ai.insight.archived

4.2 document_draft 类型

位置: apps/core/domain/types/document_draft.yaml

定义

- id: document_draft
  name: 文档草稿
  description: AI 生成的文档草稿
  schema:
    properties:
      title:
        type: string
        description: 草稿标题
      content:
        type: string
        description: 草稿内容
      parsed:
        type: object
        description: 解析后的结构化数据
      source:
        type: string
        enum: [ai]
        description: 来源
      prompt_template_id:
        type: string
        description: Prompt 模板 ID
      target_type:
        type: string
        description: 目标类型(task/document/milestone 等)
      target_entity_id:
        type: string
        description: 目标实体 ID(如果已采纳)
      status:
        type: string
        enum: [pending, adopted, rejected]
        description: 状态
      related_entity_ids:
        type: array
        items:
          type: string
        description: 关联的实体 ID 列表
    required: [title, content, source, status]
  lifecycle:
    states: [pending, adopted, rejected]
    transitions:
      - from: pending
        to: adopted
      - from: pending
        to: rejected
  allowedEvents:
    - ai.document_draft.created
    - ai.document_draft.adopted
    - ai.document_draft.rejected

五、事件定义

5.1 ai.insight.created

Schema

{
  "type": "object",
  "properties": {
    "ai_insight_id": {"type": "string"},
    "prompt_template_id": {"type": "string"},
    "related_entity_ids": {"type": "array"}
  },
  "required": ["ai_insight_id"]
}

5.2 ai.document_draft.created

Schema

{
  "type": "object",
  "properties": {
    "document_draft_id": {"type": "string"},
    "prompt_template_id": {"type": "string"},
    "target_type": {"type": "string"},
    "related_entity_ids": {"type": "array"}
  },
  "required": ["document_draft_id"]
}

5.3 ai.document_draft.adopted

Schema

{
  "type": "object",
  "properties": {
    "document_draft_id": {"type": "string"},
    "target_entity_id": {"type": "string"},
    "target_type": {"type": "string"}
  },
  "required": ["document_draft_id", "target_entity_id"]
}

六、草稿→落地工作流

6.1 采纳 API

POST /api/v1/entities/{draft_id}/adopt

请求

{
  "target_type": "task",  // 或 "document", "milestone" 等
  "updates": {  // 可选,采纳前可以修改
    "title": "修改后的标题"
  }
}

响应

{
  "status": "success",
  "target_entity_id": "task_123",
  "event_id": "evt_456"
}

实现逻辑

  1. 读取草稿内容
  2. 解析内容(JSON/Markdown)
  3. 应用用户修改(如果有)
  4. 创建真实实体(Task/Milestone/Document)
  5. 生成实体创建事件
  6. 标记草稿为"已采纳"
  7. 生成 ai.document_draft.adopted 事件

文档版本: v1.0
最后更新: 2025-12-17