# 三层模型：流程模板 → 工作流 → 人设体系

> 创建: 2026-06-28 | 状态: 设计阶段
> 关联: [Agent架构说明-2026-06-14.md](./Agent架构说明-2026-06-14.md)（当前 Agent 能力边界）
> 关联: [ARCHITECTURE.md](../../../ARCHITECTURE.md)（项目架构总纲，本文为专项展开）

---

## 一、背景与问题

DevFlow 的工作流引擎（df-workflow）已具备 DAG 定义、拓扑排序、节点调度、状态流转等核心能力。AI Chat 已具备单链 ReAct、工具调用、审批机制。

但现有架构缺少两个关键抽象：

| 缺失 | 导致的问题 |
|------|-----------|
| **流程模板**（Template） | 工作流定义与具体项目绑定，无法复用标准流程。每个项目需从零搭建 DAG |
| **人设**（Persona） | 所有 AINode 使用通用 LLM 调用，无角色分工。编码、审查、测试节点行为无差异 |

**解决方案**：引入三层模型——**模板层定义蓝图、工作流层执行实例、人设层注入角色**。

---

## 二、三层模型总览

```
┌──────────────────────────────────────────────────────────┐
│                     模板层 (Template)                      │
│    "应该做什么" — 可复用的阶段蓝图                          │
│                                                          │
│    ├─ 节点 DAG 定义（拓扑 + 类型 + 数据流）                │
│    ├─ 建议人设标注（persona_hint，实例化时可覆盖）          │
│    ├─ 质量门禁（condition + on_fail）                     │
│    ├─ 产出物规范（artifacts 声明）                         │
│    └─ 存储：YAML 文件 / DB 模板库                          │
├──────────────────────────────────────────────────────────┤
│                     工作流层 (Workflow)                    │
│    "怎么执行" — 模板的运行时实例                           │
│                                                          │
│    ├─ 模板实例化（绑定具体项目参数、分支名、路径）           │
│    ├─ DAG 执行（拓扑排序 + 并行调度 + 状态流转）           │
│    ├─ 数据绑定（inputs/outputs 按 ID 映射）                │
│    ├─ 条件分支（condition 求值 → 动态路由）                │
│    ├─ 断点续跑（状态快照 + 恢复）                          │
│    └─ 载体：df-workflow（现有，✅ 核心完成）               │
├──────────────────────────────────────────────────────────┤
│                     人设层 (Persona)                       │
│    "谁来做" — Agent 角色卡                                 │
│                                                          │
│    ├─ system prompt（角色定位、行为规范）                  │
│    ├─ allowed_tools（该角色可调用的工具集）                │
│    ├─ output_format（输出约束）                           │
│    ├─ suggested_tier（推荐模型层级）                      │
│    ├─ behavior rules（如"每次输出前先检查..."）            │
│    └─ 注入点：AINode 执行时从 NodeContext 读取 persona_id  │
└──────────────────────────────────────────────────────────┘
```

### 关键原则

1. **三层独立演化**：模板添加新节点类型、工作流优化调度算法、人设新增角色——互不阻塞
2. **交汇点单一**：三层只在 AINode 执行时交汇——工作流传递 persona_id，Node 端根据 id 载入人设配置
3. **模板标注建议而非绑定**：模板只写 `persona_hint: coder`，实例化时可改为 `coder-rust` 或 `coder-py`
4. **人设可跨模板复用**：`reviewer` 人设既可用于"功能开发模板"的审查节点，也可用于"Bug 修复模板"的审查节点

---

## 三、流程模板（Template Layer）

### 3.1 数据结构

```yaml
# templates/feature-dev.yaml
id: feature-dev                        # 模板唯一标识
name: 功能开发模板                       # 显示名称
description: 标准功能开发全流程           # 描述
template_version: 1                     # 模板版本（用于升级检测）
tags: ["feature", "standard"]           # 分类标签

nodes:
  - id: analysis                        # 节点 ID
    type: ai                            # 节点类型（ai / script / human / subflow）
    persona_hint: analyst               # 建议人设（实例化时可覆盖）
    prompt: "分析需求：{{inputs.requirement}}"  # 提示词
    inputs:                             # 数据输入映射
      requirement: "$ctx.requirement"   # $ctx = 工作流上下文参数
    outputs:                            # 输出声明
      prd: text
    config:                             # 节点级配置（覆盖默认）
      temperature: 0.3

  - id: design
    type: ai
    persona_hint: architect
    prompt: "基于 PRD 设计架构：{{inputs.analysis.prd}}"
    inputs:
      analysis: "$nodes.analysis"       # $nodes = 上游节点输出
    outputs:
      arch_doc: text

  - id: coding
    type: ai
    persona_hint: coder
    prompt: "实现：{{inputs.design.arch_doc}}"
    inputs:
      design: "$nodes.design"
    outputs:
      code: text

  - id: review
    type: ai
    persona_hint: reviewer
    prompt: "审查代码：{{inputs.coding.code}}"
    inputs:
      coding: "$nodes.coding"

  - id: test
    type: script
    prompt: ""                          # Script 节点用 command
    command: "cargo test"
    timeout_secs: 300

  - id: release
    type: human
    prompt: "确认发布到生产？"

edges:                                  # 显式边定义（可选，缺省按 nodes 顺序连接）
  - from: analysis
    to: design
  - from: design
    to: coding
  - from: coding
    to: review
  - from: review
    to: test
  - from: test
    to: release

conditions:                             # 条件分支
  - node: review
    if: "output.verdict != 'pass'"
    goto: coding                        # 审查不通过，回编码节点

quality_gates:                          # 质量门禁
  - node: review
    condition: "output.verdict == 'pass'"
    on_fail: "block"                    # block / goto / warn
  - node: test
    condition: "output.exit_code == 0"
    on_fail: "goto coding"

artifacts:                              # 产出物声明
  prd: "$nodes.analysis.prd"
  arch: "$nodes.design.arch_doc"
  code: "$nodes.coding.code"
  review_report: "$nodes.review.text"
```

### 3.2 模板实例化流程

```
① 用户选择模板（如"功能开发模板"）
② 填写实例化参数：
   ├─ project_id: 绑定到哪个项目
   ├─ requirement: 需求描述（注入 $ctx.requirement）
   ├─ persona_overrides: 按节点覆盖人设
   │    └─ coding → coder-rust（该项目是 Rust 后端）
   └─ branch: feature/search（绑定 Git 分支）

③ 实例化引擎执行：
   ├─ 复制 DAG 拓扑
   ├─ 绑定数据映射（替换 $ctx / $nodes 占位符）
   ├─ 应用人设覆盖
   ├─ 创建 WorkflowRun（状态 = pending）
   └─ 写入 DB（workflow_runs + workflow_nodes 表）

④ 工作流引擎调度执行
```

### 3.3 内置模板清单

| 模板 ID | 名称 | 适用场景 | 节点链 |
|---------|------|---------|--------|
| `feature-dev` | 功能开发 | 新增功能 | 需求分析 → 架构设计 → 编码 → 审查 → 测试 → 发布 |
| `bug-fix` | Bug 修复 | 缺陷修复 | 问题复现 → 根因分析 → 修复编码 → 回归测试 → 发布 |
| `algorithm-dev` | 算法开发 | 算法类功能 | 需求分析 → 算法设计 → 实现 → 基准测试 → 验证 → 发布 |
| `refactor` | 代码重构 | 重构优化 | 代码分析 → 重构计划 → 编码 → 审查 → 回归测试 |

> 模板为内置预设，用户可自定义模板（复制内置模板修改后存为用户模板）。

---

## 四、人设层（Persona Layer）

### 4.1 数据结构

```rust
/// 智能体人设 — Agent 角色卡
pub struct AgentPersona {
    /// 人设标识（如 "coder-rust"、"reviewer"）
    pub id: PersonaId,
    /// 人设名称
    pub name: String,
    /// 人设描述
    pub description: String,
    /// 系统提示词（核心——定义 Agent 的角色、行为规范）
    pub system_prompt: String,
    /// 可用工具列表（空 = 继承自父级配置）
    pub allowed_tools: Vec<ToolName>,
    /// 推荐模型层级
    pub suggested_tier: ModelTier,
    /// 输出格式约束
    pub output_format: OutputFormat,
    /// 行为规则
    pub rules: Vec<BehaviorRule>,
    /// Few-shot 样例
    pub examples: Vec<PersonaExample>,
}

/// 行为规则
pub struct BehaviorRule {
    pub rule_type: RuleType,  // PreCheck / PostCheck / Constraint
    pub description: String,
    pub check_prompt: String, // AI 检查提示
}

/// 输出格式约束
pub enum OutputFormat {
    FreeText,
    Markdown,
    Json { schema: Value },
    Code { language: String },
}
```

### 4.2 内置人设清单

| 人设 ID | 名称 | 核心 system_prompt 要点 | 建议工具 |
|---------|------|------------------------|---------|
| `analyst` | 需求分析师 | 拆解用户故事、识别歧义、输出 PRD | read_file, search_knowledge |
| `architect` | 系统架构师 | 模块划分、接口设计、技术选型 | read_file, search_knowledge, write_file |
| `coder-rust` | Rust 工程师 | 类型安全、错误处理、性能优先 | read_file, write_file, search_code, list_directory, run_command |
| `coder-ts` | TS/前端工程师 | 组件复用、类型定义、响应式 | read_file, write_file, search_code, list_directory, run_command |
| `reviewer` | 代码审查员 | 安全漏洞、性能问题、CRITICAL/MAJOR/MINOR | read_file, search_code, git_diff |
| `tester` | 测试工程师 | 边界条件、覆盖率、测试隔离 | read_file, write_file, run_command |
| `algorithm` | 算法工程师 | 复杂度分析、精度对比、优化策略 | read_file, write_file, run_command, benchmark |
| `devops` | DevOps 工程师 | 容器化、CI/CD、监控告警 | read_file, write_file, run_command |

### 4.3 人设的内部结构（persona.rs 设计）

```rust
// crates/df-ai/src/persona.rs（新建）

pub struct PersonaRegistry {
    builtins: HashMap<PersonaId, AgentPersona>,
    customs: HashMap<PersonaId, AgentPersona>,
}

impl PersonaRegistry {
    pub fn new() -> Self { /* 载入内置人设 */ }
    pub fn get(&self, id: &PersonaId) -> Option<&AgentPersona>;
    pub fn register(&mut self, persona: AgentPersona);  // 注册自定义人设
    pub fn list(&self) -> Vec<&AgentPersona>;
    pub fn get_system_prompt(&self, id: &PersonaId) -> Option<&str>;
    pub fn filter_tools(&self, id: &PersonaId, all_tools: &[ToolDef]) -> Vec<ToolDef>;
}
```

### 4.4 人设注入时机

人设在两个入口注入，覆盖不同的使用场景：

```
场景 A: Workflow AINode 执行
  DAG Executor → AiNode::execute()
    → NodeContext 中有 persona_id（来自模板实例化）
    → AiNode 调用 PersonaRegistry::get(persona_id)
    → 将 persona.system_prompt 附加到 LLM prompt 头部
    → 将 persona.allowed_tools 传入工具选择器
    → 执行 LLM complete()

场景 B: AI Chat Agentic Loop
  run_agentic_loop()
    → 根据 intent 识别结果自动选人设
    → Code Intent → 自动绑定 coder 人设
    → 绑定后: system_prompt = coder.system_prompt
    → 绑定后: 工具面板 = coder.allowed_tools
    → 执行 ReAct 循环（带人设约束）
```

---

## 五、三层在现有代码中的落地映射

### 5.1 新增与修改文件清单

| 文件 | 操作 | 说明 |
|------|------|------|
| `crates/df-ai/src/persona.rs` | **新建** | AgentPersona 结构体 + PersonaRegistry + 内置人设 |
| `crates/df-ai/src/lib.rs` | 修改 | 导出 `pub mod persona` |
| `crates/df-ai/src/coordinator.rs` | 修改 | 从空壳变为人设调度器——给子任务分配人设 |
| `crates/df-nodes/src/ai_node.rs` | 修改 | execute() 中读取 `NodeContext` 的 `persona_id`，加载人设配置 |
| `crates/df-workflow/src/node.rs` | 修改 | `NodeContext` 新增 `persona_id: Option<PersonaId>` 字段 |
| `crates/df-types/src/types.rs` | 修改 | 新增 `PersonaId` 类型 |
| `src-tauri/src/commands/ai/agentic.rs` | 修改 | `run_agentic_loop` 根据 intent 自动选人设 |
| `src-tauri/src/commands/ai/tool_registry.rs` | 修改 | 工具注册表支持按人设过滤 |

### 5.2 现有三条路径如何汇合

```
                    ┌──────────────────────┐
                    │  模板（YAML）         │
                    │  persona_hint: coder  │
                    └──────────┬───────────┘
                               │ 实例化
                               ▼
                    ┌──────────────────────┐
                    │  工作流实例           │
                    │  NodeContext {        │
                    │    persona_id: "coder"│
                    │  }                    │
                    └──────────┬───────────┘
                               │ 执行到 AINode
                               ▼
┌──────────────────────────────────────────────┐
│  AiNode::execute()                            │
│    ├─ 从 ctx.persona_id 查到人设配置          │
│    ├─ 拼接 system_prompt → LLM               │
│    ├─ 限制工具集 → allowed_tools              │
│    └─ 输出格式约束 → output                   │
└──────────────────────────────────────────────┘
```

---

## 六、与现有 Agent 架构的关系

current [Agent架构说明-2026-06-14.md](./Agent架构说明-2026-06-14.md) 提到的四个"无"中，人设层直接回应了以下问题：

| 原缺口 | 人设层如何解决 |
|--------|---------------|
| coordinator 空壳 | 人设调度是 coordinator 的第一个实现步骤：子任务按类型分配人设 |
| 单链 ReAct 无角色区分 | 人设注入后，同一 loop 按绑定的人设输出不同风格的响应 |
| Agent 能力边界模糊 | 人设的 `allowed_tools` 显式声明能力边界，"能做什么"由人设而非通用配置决定 |

> 人设层不解决所有缺口（如执行类工具、MCP 外部工具），但它是多 Agent 协作的第一步。

---

## 七、Phase 落地建议

### Phase A：数据结构 + 内置人设（单独推进，不阻塞其他任务）

```
目标: 定义 AgentPersona 结构体 + 5 个内置人设 + PersonaRegistry
文件: crates/df-ai/src/persona.rs
验证: PersonaRegistry::get("coder") 返回正确的人设配置
```

### Phase B：AINode 接入人设

```
目标: AINode 执行时从 NodeContext 读 persona_id，拼接 system_prompt
文件: crates/df-workflow/src/node.rs + crates/df-nodes/src/ai_node.rs
验证: 带 persona_id 的 AiNode 输出带有人设风格的文本
```

### Phase C：流程模板系统

```
目标: YAML 模板定义 + 实例化引擎（模板 → 工作流 DAG）
文件: df-workflow 新增模板加载逻辑
验证: 加载 feature-dev.yaml → 实例化为带 persona_hint 的 DAG
```

### Phase D：AI Chat 接入人设

```
目标: run_agentic_loop 根据 intent 自动选人设，工具面板按人设过滤
文件: src-tauri/commands/ai/agentic.rs + tool_registry.rs
验证: Code Intent 下只暴露编码相关工具
```

---

## 八、设计决策

| 决策 | 选项 | 结论 | 理由 |
|------|------|------|------|
| 人设定义位置 | 编译期 vs 运行时 | 编译期内置 + 运行时扩展 | 内置人设保证基线质量，扩展性留给插件机制 |
| 模板格式 | YAML vs JSON vs Rust DSL | YAML | 人类可读写，适合非开发者定义模板 |
| 人设与 model 的关系 | 人设绑定 model vs 分离 | 分离（人设只建议 `suggested_tier`） | 模型选择由调用方决定，人设不越界 |
| 模板实例化时机 | 启动时 vs 使用时 | 使用时（lazy instantiation） | 启动时加载数百模板影响冷启动 |
