Files
ftb-project-management/docs/agent-spec.md
2e595c7e72
Some checks failed
Deploy Production / Build, push, deploy, verify (push) Has been cancelled
refactor(data): 收口关系表运行时数据源
- 移除已迁移业务 AppData 运行时 fallback,改走领域 API 和关系表快读
- 补齐需求产品负责人、版本计划任务 JSON 和成员 username 回填迁移
- 统一治理字典入口,并补充 AI provider、数据源契约和领域服务测试

Co-Authored-By: Codex GPT-5 <codex@openai.com>
2026-07-09 14:59:49 +08:00

18 KiB
Raw Permalink 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 输出必须有"对账报告"

    • 拆解任务前,先输出结构化对账:
      • 完美对应(需求 ↔ 原型注释 ↔ 任务)
      • ⚠️ 需求未见原型
      • 无需求ID分组原型有明确功能但没有匹配到关联需求
      • 注释含糊无法转化
    • 对账报告先呈现给用户,用户审核后才执行写入
  4. AI 预估不等于执行人预估

    • AI 只能输出 aiEstimateHours
    • estimateHours 留给负责人/执行人确认后填写
    • AI 不输出预计开始/截止时间,排期由负责人后续维护
  5. AI 可推荐负责人,但不自动分配

    • AI 只能从当前版本成员 members[].name 中输出可选的 recommendedAssigneeName
    • 推荐只作为采纳弹窗里的辅助信息,默认不写入 assigneeId
    • 用户勾选“采纳推荐负责人”后,前端再次校验推荐姓名属于当前版本成员,才写入 DevTask/TestCase
    • 没有明确匹配成员时不输出推荐字段
  6. 历史版本不强制存储

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

Agent 列表

Agent 1Prototype Decompose Agent原型拆解

目的:把"产品方案原型 + 关联需求"拆解成开发任务草案 + 测试用例草案。关联需求是正式范围锚点原型中明确可拆但没有匹配到关联需求的功能也可以拆成无需求ID分组草案。

输入

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

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

触发条件

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

输出

  • 对账报告(结构化文本,含"完美对应/需求未见原型/无需求ID分组/含糊"
  • DevTask 草案数组(每条带结构化 description + taskTypeName + aiDraft: true + references[] + aiEstimateHours,可选 categoryCode / recommendedAssigneeName / recommendedAssigneeReason
  • TestCase 草案数组(每条带 taskTypeName + aiDraft: true + references[] + aiEstimateHours,可选 categoryCode / recommendedAssigneeName / recommendedAssigneeReason
  • target = dev_taskstestCaseDrafts 必须为空数组;target = test_casesdevTaskDrafts 必须为空数组

原型与需求匹配规则

  • 优先按需求编号匹配:原型批注或文本出现 requirement.id / requirement.code 时,必须优先判定为该需求命中。
  • 编号未出现时,再按需求标题和需求概述(title / description)做语义匹配。
  • 有 QY 编号时,prototype_note 引用只能使用真实存在的 QY 编号。
  • 没有 QY 编号但原型文本已命中需求编号或需求概述时,不应丢弃;可只引用 requirement,并在 matched.noteIds 返回空数组。
  • 既匹配不到需求编号,也匹配不到需求概述语义,但能形成明确功能名称和任务范围的原型批注,进入 prototypeOnly,对应草案带 requirementName 且不带 requirement 引用。
  • 只有无法形成稳定任务/用例的含糊批注才进入 ambiguous
  • 原型批注只要包含标题、详细说明、字段、异常或验收标准之一,且能判断用户动作或系统行为,就不能进入 ambiguous;这类内容必须进入 matchedprototypeOnly 并继续拆解。

开发任务与测试用例拆解粒度

  • Agent 先在内部把每条 QY 或命中的需求拆成交付切片,再生成 DevTask/TestCase交付切片维度按 UI、交互、接口、数据、异常、边界、状态流转、兼容和回归扫描。
  • 每条业务规则、字段规则、交互规则、异常规则和验收标准都必须至少映射到 1 条开发任务或 1 条测试用例;本次 target 不包含的一侧可以不输出,但另一侧必须覆盖。
  • DevTask 必须是一个可交付工程动作。前端、后端、接口、数据库、数据处理和集成支持要按职责拆开。
  • DevTask description 必填,至少包含实现范围和验收点;如存在非目标范围或依赖,也必须写明。

测试用例拆解粒度

  • TestCase 要按功能点、UI 交互、表单校验、接口、数据一致性、权限、异常、边界、状态流转、兼容性和回归点拆细。
  • 不允许用一条“验证 XX 完整流程”覆盖多个交互、多个接口或多个规则。
  • 一条 QY 若同时涉及 UI、接口、数据、异常和状态变化通常应拆出 3-8 条 TestCase。
  • TestCase description 必填,至少包含前置条件、操作步骤和预期结果;涉及边界、异常或数据一致性时,必须写明测试数据或状态。
  • DevTask / TestCase 必须输出 taskTypeName,但它必须是可复用的任务类型字典项,不是任务标题或任务概述。categoryCode 只作为可选的兼容映射字段;没有合适稳定码时可以省略,不能因此停止拆解。

写入

  • 用户确认后,调用 useDevTaskStore.createTaskuseTestCaseStore.createTestCase
  • 打开采纳弹窗前,前端先过滤当前版本已采纳过的重复 DevTask/TestCase 草案
  • 写入前,前端按 taskTypeName 检查 TaskCategory 字典;可复用开发类型不存在时自动追加非系统任务类型。测试用例未知类型不自动入库,优先按 categoryCode 或默认测试类型回退。
  • 写入字段中 aiDraft: trueaiDraftAt: ISO时间戳
  • 写入 aiEstimateHours,不写入执行人预估 estimateHours
  • DevTask / TestCase 必须写入 versionId 作为执行归属;requirementId 可选
  • 无正式需求 ID 的草案写入 requirementName 作为分组展示名,列表显示为 无需求ID · {requirementName}
  • 无需求ID分组不创建 Requirement不写入需求池不加入版本关联需求列表
  • DevTask 草案不写预计开始/截止时间,负责人后续排期时再填写
  • 只有用户在采纳弹窗勾选“采纳推荐负责人”时,才把已校验的 recommendedAssigneeName 写入 assigneeId

权限

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

失败回退

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

MVP 阶段限制V3.1

  • 只生成 DevTask 和 TestCase 草案
  • 不自动分配 assigneeAI 只提供可选推荐,用户确认采纳后才写入
  • 不做"上一版基准 diff"

Agent 2Risk Watch Agent小宝预警解读

目的:解释小宝预警规则引擎输出的版本发版风险结果,生成项目经理可读的风险原因、延期预测、建议发版窗口和处理动作。

输入

  • 版本上下文:产品、项目、版本、期望发版日期。
  • 规则风险结果:riskScoreriskLevelforecastReleaseDatedelayDaysconfidence、风险信号。
  • 趋势和快照:风险分变化、连续上升/下降、关键 Bug、失败用例、阻塞和静默风险变化。
  • 日报与工作活动证据:今日交付、今日进展、今日风险、进展备注、需要补充进展的事项。

触发

  • on_track 不触发。
  • at_risklikely_delayedblocked 自动触发。
  • attention 当前服务端只在临近发版且仍有未完成工作时触发;前端历史趋势策略保留为兼容展示,不作为 V3.2 服务端后台触发要求。

输出summarywhy[]forecastrecommendedReleaseWindowsuggestedActions[]ownerHints[]

权限:读规则结果和压缩证据;写 xiaobao_risk_insights 关系表缓存。历史 AppData 兼容名 xiaobao-risk-insights 仅用于迁移/归档,不作为运行时写入目标。不修改 Version、Requirement、DevTask、TestCase、Bug、Member。

失败回退AI 不可用时保留规则预警前端显示“规则预警已生成AI 解读会在触发条件满足时自动补充”。AI 失败不影响快照保存和规则风险展示。

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

仅占位。本次 V3.2 不执行排期建议;后续如要做成员负载与历史耗时驱动的排期建议,需要先补独立规划。

多 Agent 协作(暂不执行)

当前 Prototype Decompose Agent 和 Risk Watch Agent 相互独立运行:原型拆解由用户在产品方案 Tab 触发Risk Watch 由小宝 summary 后台刷新后按 policy 入队。当前不做多 Agent 编排;未来 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[];
aiEstimateHours?: number; // AI 预估耗时,单位小时

Agent 输入预期

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

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

Agent 输出预期

interface DecomposeOutput {
  report: {
    matched: Array<{ reqId: string; noteIds: string[]; taskCount: number }>;
    reqOnly: string[];     // 需求 ID 列表
    prototypeOnly: Array<{ requirementName: string; noteIds: string[]; taskCount: number }>;
    ambiguous: Array<{ noteId: string; reason: string }>;
  };
  devTaskDrafts: Array<{ title: string; description: string; taskTypeName: string; categoryCode?: string; priority: Priority; aiEstimateHours: number; requirementName?: string; recommendedAssigneeName?: string; recommendedAssigneeReason?: string; references: Reference[] }>;
  testCaseDrafts: Array<{ title: string; description: string; taskTypeName: string; categoryCode?: string; priority: Priority; aiEstimateHours: number; requirementName?: string; recommendedAssigneeName?: string; recommendedAssigneeReason?: string; references: Reference[] }>;
}

要求AI 不输出数据库 categoryIdtaskTypeName 是必填的可复用类型名,不能写成“排行榜测试”这类当前文档专属概述;categoryCode 只是可选映射提示,不限制 AI 拆解。前端确认写入时按 taskTypeName 解析 TaskCategory可复用开发类型缺失时才追加到任务类型字典测试用例未知类型回退到已有测试分类。AI 不输出 estimateHours、预计开始或预计截止。草案没有 requirement 引用时,必须有 requirementName 和至少一个 prototype_note 引用。

任务/用例分组契约

interface VersionScopedRequirementGroup {
  versionId: string;       // 执行归属,必填
  requirementId?: string;  // 正式需求 ID可选
  requirementName?: string; // 无正式需求 ID 时的展示分组名
}

要求:版本级聚合使用 versionId;需求级进度只统计带 requirementId 的 DevTask。无需求ID分组只影响版本任务/用例视图,不影响需求池和关联需求列表。

视觉规范

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

  • 整行加 border-l-2 border-l-purple-400 bg-purple-50/30
  • 标题旁紫色徽章「AI 草案」(bg-purple-100 text-purple-600
  • 用户在详情抽屉里编辑保存任意字段后,徽章和左边线自动消失
  • 无需求ID分组不额外显示“原型发现”等标记只在分组标题中展示 无需求ID · {requirementName}

Business Analysis Agent第一版已落地

Business Analysis Agent 是只读业务数据分析 Agent不复用 Prototype Decompose Agent 的草案写入契约,也不复用 Risk Watch Agent 的单版本风险解释契约。

第一版已接入 /api/v1/ai/analysis/wenfan-xiaobao 和产品/项目/版本详情页上下文入口。当前支持 Template Strategy 和 Deterministic Rule CompositionAI Planning 只保留为受控计划建议边界,生成的 AnalysisPlan 必须经过 Analysis Plan Processor 校验和规范化后才能执行。图表契约为 Unified ChartSpec前端通过 ECharts Renderer 渲染。

入口:

  • /wenfan-xiaobao业务数据分析对话优先尝试业务分析AI 分析不可用时保留内置帮助 fallback。
  • 产品、项目、版本详情页:带当前上下文的智能分析入口和只读分析 Drawer。

核心链路:

Question + Context
  -> Analysis Planner
  -> Semantic Layer
  -> Permission Scope Resolver
  -> Analysis Strategy
  -> Analysis Plan Processor
  -> Metric Engine
  -> Metric Result
  -> ChartSpec / Insight / Report / Follow-ups

硬约束:

  • AI 不写 SQL不直接查数据库。
  • AI Planning 只生成 AnalysisPlan 建议,必须经系统校验和规范化。
  • Agent 仅查询当前用户已有权限的数据,不允许自然语言绕过权限。
  • 输出 ChartSpec 是平台统一契约,不是 ECharts option前端第一版用 ECharts Renderer。
  • Metric Catalog 记录 metric version公式或业务口径变化必须升版本。
  • 输出必须包含 Insight Card、图表、固定结构报告、可点击 Evidence 和只读 Follow-up。
  • 详情页入口只传 surface 和对应上下文 ID后端基于当前用户和上下文再次收窄范围不能只信任前端。

视觉规范见 docs/superpowers/specs/2026-07-08-business-analysis-agent-design.md 的 AI Analysis Design System。