Files
ftb-project-management/docs/agent-spec.md
2026-06-25 09:52:05 +08:00

9.0 KiB
Raw Blame History

Agent 规范

本文件是 FTB 系统中所有 AI Agent 的唯一权威定义。任何对 agent 的能力、职责、权限、协作方式的修改,必须先在本文件落地,再同步到 architecture / decisions / workflow / roadmap / glossary。

何时更新本文件

  1. 新增 agent:新建一个独立 agent
  2. agent 职责变化:输入/输出/调用条件变了
  3. agent 权限变化:可读哪些数据、可写哪些数据变了
  4. 多 agent 协作方式变化:编排顺序、依赖关系、出错回退策略变了

不影响以上四类的 prompt 微调、模型版本切换、性能优化不需要更新本文件。

全局原则

  1. AI 不直接动数据,先生草案,用户确认

    • 所有写入实体DevTask / TestCase必须带 aiDraft: true 标记
    • 用户编辑保存后,标记自动清除(在 useDevTaskStore.updateTask / useTestCaseStore.updateTestCase 里实现)
  2. 每条产物强制带引用

    • DevTask / TestCase 必须有 references: Reference[],至少 1 条
    • 引用类型:requirement / prototype_note / external
    • 不带引用的草案不允许写入
  3. AI 输出必须有"对账报告"

    • 拆解任务前,先输出三段对账:
      • 完美对应(需求 ↔ 原型注释 ↔ 任务)
      • ⚠️ 仅需求未见原型 / 仅原型未见需求
      • 注释含糊无法转化
    • 对账报告先呈现给用户,用户审核后才执行写入
  4. 历史版本不强制存储

    • 系统不要求历史原型 URL 作为基准
    • 拆偏问题靠"对账报告"暴露给用户,由人工补救
    • 这条决定见 decisions.md #17

Agent 列表

Agent 1Prototype Decompose Agent原型拆解

目的:把"产品方案原型 + 关联需求"拆解成开发任务草案 + 测试用例草案。

输入

  • 当前版本「产品方案」类型 + status=completed 的 VersionPlan取其 resultUrl 作为原型链接(约定:产品方案的成果即原型)
  • 当前版本关联需求列表(已被加进 Version 的 Requirement[]
  • 版本成员清单(带角色:前端/后端/UI/测试)

调用入口:版本详情页 → 产品方案 Tab → 计划状态 = completed 后按钮「AI 拆解任务和用例」

触发条件

  • 当前版本至少有 1 条 type=product 的 VersionPlan 处于 completed 且 resultUrl 非空(提交了原型)
  • 当前版本至少关联 1 条需求

输出

  • 对账报告(结构化文本,含"完美对应/单边/含糊"三段)
  • DevTask 草案数组(每条带 aiDraft: true + references[]
  • TestCase 草案数组(每条带 aiDraft: true + references[]

写入

  • 用户确认后,调用 useDevTaskStore.createTaskuseTestCaseStore.createTestCase
  • 写入字段中 aiDraft: trueaiDraftAt: ISO时间戳

权限

  • Version, Requirement, VersionPlan, Member
  • DevTask仅 aiDraft 草案、TestCase仅 aiDraft 草案)
  • 不得修改Requirement、Version、VersionPlan、Member、Bug

失败回退

  • 原型 URL 不可达 → 报告"原型无法访问",不写入任何数据
  • 没有已完成的产品方案计划 → 报告"请先完成产品方案并提交原型成果",不写入
  • 关联需求为空 → 报告"无关联需求,无法对照",不写入
  • 对账报告全是 → 报告"原型注释含糊度过高,建议人工拆解",不写入

MVP 阶段限制V3.1

  • 只生成 DevTask 和 TestCase 草案
  • 不自动分配 assigneeassignee 留给用户从草案编辑时手填)
  • 不做"上一版基准 diff"

Agent 2Risk Watch Agent风险预警— 待规划

仅占位,正式规划见 roadmap.md V3.2。

Agent 3Schedule Suggest Agent排期建议— 待规划

仅占位,正式规划见 roadmap.md V3.2。

多 Agent 协作V3.2 规划)

当前 V3.1 只有 Prototype Decompose Agent 单独运行。 未来 Risk Watch / Schedule Suggest 引入后,编排策略另行设计。

实现位置

V3.1 起,所有 Agent 走 NestJS 后端(不走 Next.js API Route原因

  • 与现有 product / requirement 模块架构一致
  • 共享 Prisma 实例便于后续 AiLog 持久化
  • 多 Agent 引入时统一在 AiGateway 管理 prompt / 降级 / 重试

代码位置:

apps/server/src/modules/
├── ai/
│   ├── ai.module.ts
│   ├── ai.controller.ts                # POST /api/v1/ai/decompose
│   ├── ai.service.ts                   # 抓原型 + 调 LLM + 解析
│   ├── ai-gateway.service.ts           # Anthropic 客户端单例懒加载key 改了重建)
│   ├── prompts/decompose.ts            # System Prompt + Tool Schema
│   └── dto/decompose.dto.ts            # 入参校验
└── config/
    ├── config.module.ts
    ├── ai-config.controller.ts         # GET/PATCH /api/v1/config/ai, POST /test
    ├── ai-config.service.ts            # 读写 data/ai-config.json
    └── dto/update-ai-config.dto.ts

共享类型:packages/shared/src/agent.ts(前后端通用)

配置管理

多提供商支持V3.1.5 起):系统支持配置任意数量的 AI 提供商,每个独立的 baseURL / apiKey / model运行时切换激活。

支持的 API 格式

  • anthropic — Anthropic 官方 + 兼容 Anthropic Messages API 格式的中转站(如 ikuncode 的 anthropic 端点)
  • openai — OpenAI 官方 + 兼容 OpenAI Chat Completions 格式的中转站

API Key 优先级:当前激活提供商的 apiKey → 环境变量 ANTHROPIC_API_KEY(兜底,仅 anthropic 格式可用)

前端配置入口/admin/ai-config,仅超管(role.permissions'*')可见

字段(每个 Provider

  • id:用户自定义唯一 IDikuncode
  • name:显示名
  • formatanthropic / openai
  • baseURL:完整 API endpoint
  • apiKey:完整 Key 仅在服务端持有;前端只能拿到 mask 视图
  • model:该提供商上使用的模型 ID
  • remark:可选备注

全局字段

  • activeProviderId:当前激活哪个 provider
  • updatedAt / updatedBy:审计

测试连接POST /api/v1/config/ai/test{ id },用 16 token 极简调用验证目标 provider 可用性

激活POST /api/v1/config/ai/activate{ id },切换激活 providerAiGateway 缓存自动失效,下次调用重新构建客户端

安全约束

  • 配置文件路径在 .gitignore 里(apps/server/data/),不进入版本控制
  • 前端 GET 接口永远不返回完整 Key
  • 修改 Key 只能从前端 PATCH 上传新值,不支持读出旧值
  • 编辑提供商时若不传 apiKey则保留原值

数据迁移旧版V3.1)的 { anthropicApiKey, model } 单 key 结构,自动迁移为多 providers 结构id 为 anthropic-official,自动激活)。

数据契约

Reference 类型

interface Reference {
  type: 'requirement' | 'prototype_note' | 'external';
  id: string;       // REQ-008 / QY0007 / 自由文本
  label: string;    // 展示用
  url?: string;     // 可选跳转链接
}

AI 草案标记

// DevTask 和 TestCase 共有
aiDraft?: boolean;
aiDraftAt?: string;  // ISO 时间戳
references?: Reference[];

Agent 输入预期

interface DecomposeInput {
  version: VersionWithContext;       // 上下文(不含 prototypeUrl原型从产品方案成果取
  prototypeUrl: string;              // 从产品方案 completed 计划的 resultUrl 派生
  requirements: Requirement[];       // 当前版本所属项目下已采纳、可用于本次拆解的需求
  members: VersionMember[];          // 该版本参与人员(带角色)
}

要求:requirements 不能从产品级全量需求池直接取,必须经过项目维度和已采纳状态过滤。

Agent 输出预期

interface DecomposeOutput {
  report: {
    matched: Array<{ reqId: string; noteIds: string[]; taskCount: number }>;
    reqOnly: string[];     // 需求 ID 列表
    noteOnly: string[];    // 原型注释 ID 列表
    ambiguous: Array<{ noteId: string; reason: string }>;
  };
  devTaskDrafts: Array<Omit<DevTask, 'id' | 'taskNo' | 'createdAt' | 'updatedAt' | 'isBlocked' | 'categoryId'> & { categoryCode: string; aiDraft: true; aiDraftAt: string; references: Reference[] }>;
  testCaseDrafts: Array<Omit<TestCase, 'id' | 'caseNo' | 'createdAt' | 'updatedAt' | 'status' | 'categoryId'> & { categoryCode: string; aiDraft: true; aiDraftAt: string; references: Reference[] }>;
}

要求AI 不输出数据库 categoryId,只输出稳定 categoryCode。前端确认写入时按 TaskCategory.code 映射成 categoryId;映射失败时使用对应分组的默认类型兜底。

视觉规范

AI 草案在 DevTask / TestCase 列表中的视觉区分:

  • 整行加 border-l-2 border-l-purple-400 bg-purple-50/30
  • 标题旁紫色徽章「AI 草案」(bg-purple-100 text-purple-600
  • 用户在详情抽屉里编辑保存任意字段后,徽章和左边线自动消失