- ARCHITECTURE.md 补充执行层级模型 + 重写 §七 三层模型章节 - 新建专项设计: 流程模板 YAML 规范/AgentPersona 数据结构/实例化流程 - 注册新文档到架构设计 INDEX - Agent架构说明补充前向关联引用
394 lines
17 KiB
Markdown
394 lines
17 KiB
Markdown
# 三层模型:流程模板 → 工作流 → 人设体系
|
||
|
||
> 创建: 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) | 启动时加载数百模板影响冷启动 |
|