Skip to content

GaussAA/Formative

 
 

Repository files navigation

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with the Formative repository.

项目概述

定型 Formative 是一个 AI 驱动的产品开发方案生成器,使用 LangGraph 状态机工作流将用户需求转化为完整的开发方案。系统通过六个渐进式阶段帮助用户在 AI 写代码前先把想法"定型"。

核心流程: 需求采集 → 风险分析 → 技术选型 → MVP 规划 → 架构设计 → 文档生成

常用命令

开发与构建

pnpm dev                # 启动开发服务器 (http://localhost:3000)
pnpm build             # 构建生产版本
pnpm start             # 启动生产服务器

代码质量检查

pnpm lint              # 运行 ESLint
pnpm lint:fix          # 自动修复 ESLint 问题
pnpm format:check      # 检查代码格式
pnpm format            # 格式化代码
pnpm type-check        # TypeScript 类型检查
pnpm check             # 运行所有检查(类型 + lint + 格式)

测试

pnpm test              # 运行单元测试(监听模式)
pnpm test:unit         # 单次运行单元测试
pnpm test:coverage     # 生成测试覆盖率报告
pnpm test:e2e          # 运行 E2E 测试
pnpm test:e2e:ui       # E2E 测试 UI 模式

运维脚本

pnpm ops               # 运维工具菜单
pnpm ops:start         # 快速启动开发环境
pnpm ops:clean         # 清理缓存和临时文件(支持多种选项)
pnpm ops:stop          # 停止所有 Node 进程
pnpm ops:reinstall     # 重新安装依赖
pnpm ops:health        # 检查项目健康状态

包管理器: 项目使用 pnpm。已有 pnpm-lock.yaml

环境变量配置

在项目根目录创建 .env.local 文件:

# 必需配置
LLM_PROVIDER=deepseek   # 支持: deepseek | qwen | ollama | mimo
LLM_MODEL=deepseek-chat
LLM_API_KEY=your_api_key_here
LLM_BASE_URL=https://api.deepseek.com/v1  # 可选,根据 provider 自动设置

LLM Providers:

  • DeepSeek: https://platform.deepseek.com/ - 默认 baseURL: https://api.deepseek.com/v1
  • Qwen: https://dashscope.aliyuncs.com/ - 默认 baseURL: https://dashscope.aliyuncs.com/compatible-mode/v1
  • Ollama: 本地运行,无需 API_KEY - 默认 baseURL: http://localhost:11434/v1
  • Mimo: OpenAI 兼容 API - 默认 baseURL: https://api.mimo.com/v1

核心架构

LangGraph 工作流状态机

工作流图 (src/lib/graph/index.ts):

用户输入 → Extractor → Planner → 条件路由
                              ↓
                    ┌──────────┼──────────┐
                    ↓          ↓          ↓
                  Asker   RiskAnalyst  TechAdvisor
                    ↓          ↓          ↓
                              MVPGuardary → SpecGenerator

路由逻辑 (src/lib/graph/index.ts:32):

export function routeNext(state: GraphStateType): string {
  // 根据 currentStage 和 needMoreInfo 决定下一个节点
  // 检查各阶段是否已运行过(通过 state.summary 判断)
  // 返回节点名称或 'END'
}

状态持久化: 使用全局单例 MemorySaver 确保跨请求状态持久化。

Agent 节点系统

8个 Agent 节点位于 src/lib/agents/,每个节点使用特定的 LLM 配置:

节点 文件 Temperature MaxTokens 职责
extractor extractor.ts 0.1 1000 从用户输入提取结构化需求信息
planner planner.ts 0.2 800 评估需求完备度,决定是否需要更多信息
asker asker.ts 0.5 500 生成引导性问题(对话模式)
form_validator form-validator.ts 0.2 1000 验证表单数据的合理性
risk_analyst risk-analyst.ts 0.3 1500 分析风险,生成 3 个实施方案
tech_advisor tech-advisor.ts 0.3 1500 推荐技术栈选项
mvp_boundary mvp-boundary.ts 0.3 1500 定义 MVP 功能边界
spec_generator spec-generator.ts 0.2 4000 生成最终 PRD 文档

配置定义: src/lib/llm/config.ts

Agent 节点开发规范

每个 Agent 节点必须:

  1. 接收 GraphStateType 作为输入参数
  2. 返回 Partial<GraphStateType> 更新状态
  3. 使用 callLLMWithJSONByAgentcallLLMByAgent 调用 LLM
  4. 适当使用 logger 记录关键操作
export async function myAgentNode(state: GraphStateType): Promise<Partial<GraphStateType>> {
  logger.agent('MyAgent', state.sessionId, 'Starting task');

  try {
    const result = await callLLMWithJSONByAgent<MyResponseType>(
      'myAgent', // 对应 config.ts 中的配置 key
      systemPrompt,
      contextMessage
    );

    return {
      response: result.message,
      summary: {
        ...state.summary,
        [Stage.MY_STAGE]: result.data,
      },
    };
  } catch (error: unknown) {
    logger.error('MyAgent failed', {
      sessionId: state.sessionId,
      error: error instanceof Error ? error.message : String(error),
    });
    throw error;
  }
}

状态管理

后端状态 (src/lib/graph/state.ts)

使用 LangGraph 的 Annotation.Root() 定义状态 Schema:

export const GraphState = Annotation.Root({
  sessionId: Annotation<string>,
  currentStage: Annotation<Stage>,
  completeness: Annotation<number>,
  profile: Annotation<RequirementProfile>,
  summary: Annotation<StagesSummary>,
  messages: Annotation<Array<{ role: string; content: string }>>,
  userInput: Annotation<string>,
  response: Annotation<string>,
  options: Annotation<OptionChip[] | undefined>,
  needMoreInfo: Annotation<boolean>,
  missingFields: Annotation<string[]>,
  askedQuestions: Annotation<string[]>,
  stop: Annotation<boolean>,
  finalSpec: Annotation<string | undefined>,
  metadata: Annotation<{ createdAt?: number; updatedAt?: number; totalTokens?: number }>,
});

关键字段:

  • currentStage: 当前阶段枚举 (0-7)
  • profile: 需求画像(产品目标、用户、功能等)
  • summary: 各阶段总结数据
  • needMoreInfo: 是否需要更多信息
  • missingFields: 缺失的字段列表
  • askedQuestions: 已问问题列表(用于循环检测)

前端状态 (src/contexts/StageContext.tsx)

React Context API 管理全局状态:

  • IndexedDB 自动保存: 2 秒防抖减少写入频率 75%
  • useTransition: 非紧急状态更新优化
  • 手动保存: 支持立即保存功能
  • 多标签页: 支持跨标签页状态同步

LLM 调用优化

统一接口 (src/lib/llm/helper.ts)

import { callLLMWithJSONByAgent, callLLMByAgent } from '@/lib/llm/helper';

// 使用配置化调用 - 自动应用优化的参数
const result = await callLLMWithJSONByAgent<MySchema>(
  'extractor', // agentType,从 config.ts 获取配置
  systemPrompt,
  userMessage,
  conversationHistory // 可选
);

LRU 缓存 (src/lib/cache/lru-cache.ts)

  • 容量: 200 个条目
  • 自动清理: 每 10 分钟清理一次
  • 收益: 减少 30-50% API 调用成本
export const llmCache = new LRUCache<string, unknown>(200);

超时重试 (src/lib/utils/retry.ts)

  • 策略: 指数退避 + 随机抖动
  • 默认: 3 次重试,30s 超时
  • 收益: 成功率 95% → 99%+
const result = await retryWithTimeout(
  () => callLLMWithJSONByAgent(...),
  { maxRetries: 3 },
  30000
);

日志系统 (src/lib/logger/index.ts)

日志级别

级别 场景
DEBUG 开发环境详细轨迹
INFO 关键业务路径
WARN 可恢复异常
ERROR 需要人工介入错误
CRITICAL 系统级崩溃

使用示例

import logger from '@/lib/logger';

logger.info('User submitted form', { sessionId, data });
logger.agent('Extractor', sessionId, 'Information extracted', { extracted });
logger.error('LLM call failed', { error: errorMessage });

特性:

  • JSON 格式输出
  • 敏感数据自动脱敏
  • 源码位置追踪
  • TraceId 支持

测试策略

单元测试 (Vitest)

目录: tests/

测试原则:

  • AAA 模式 (Arrange, Act, Assert)
  • 禁止依赖真实数据库/外部网络
  • 必须使用 Mock
  • 覆盖率目标 ≥ 80%
pnpm test              # 监听模式
pnpm test:unit         # 单次运行
pnpm test:coverage     # 覆盖率报告

E2E 测试 (Playwright)

目录: tests/e2e/

pnpm test:e2e          # 运行 E2E 测试
pnpm test:e2e:ui       # UI 模式

数据流向

用户输入
    ↓
API Route (/api/chat)
    ↓
runWorkflow() / continueWorkflow()
    ↓
LangGraph StateGraph
    ↓
各 Agent 节点处理(配置化 LLM + 缓存 + 重试)
    ↓
返回 GraphState(可选 SSE 流式)
    ↓
前端更新 StageContext
    ↓
IndexedDB 防抖保存(2秒延迟)

阶段过渡条件

  1. 需求采集 (completeness === 100 + 所有必填字段)

    • 必填: productGoal, targetUsers, coreFunctions, needsDataStorage, needsMultiUser, needsAuth
    • 进入: RISK_ANALYSIS
  2. 风险分析 (用户选择方案)

    • 条件: state.summary[Stage.RISK_ANALYSIS].selectedApproach 存在
    • 进入: TECH_STACK
  3. 技术选型 (用户选择技术栈)

    • 条件: state.summary[Stage.TECH_STACK].techStack 存在
    • 进入: MVP_BOUNDARY
  4. MVP 规划 (自动生成)

    • 进入: DIAGRAM_DESIGN
  5. 架构设计 (自动生成)

    • 进入: DOCUMENT_GENERATION
  6. 文档生成 (自动生成)

    • 完成: COMPLETED

流式响应 (SSE)

API: /api/chat?stream=true

实现: src/lib/streaming/stream-utils.ts

响应格式:

data: {"type":"text","content":"..."}
data: {"type":"metadata","options":[...],"profile":{...}}

Server Actions (React 19)

文件: src/app/actions/requirement-actions.ts

'use server';
export async function submitRequirementForm(
  prevState: RequirementFormState | null,
  formData: FormData
): Promise<RequirementFormState>;

组件中使用:

const [state, formAction, isPending] = useActionState(submitRequirementForm, null);
<form action={formAction}>...</form>

性能优化

优化项 收益 文件
React Compiler 减少 20-30% 重渲染 next.config.ts
useTransition 阶段切换流畅 StageContext.tsx
useDeferredValue 列表渲染优化 TechStackStage.tsx
LLM 缓存 API 成本 -30-50% lru-cache.ts
超时重试 成功率 95% → 99%+ retry.ts
SSE 流式 用户体验 +300% stream-utils.ts
PPR TTFB -50-70% next.config.ts
Server Actions 表单代码 -40-60% requirement-actions.ts
IndexedDB 防抖 写入频率 -75% StageContext.tsx

代码质量标准

类型安全

  • any 类型: 所有未知类型使用 unknown + 类型守卫
  • 严格 TypeScript: 启用 noUncheckedIndexedAccess, exactOptionalPropertyTypes
  • 统一 API 响应: 使用 ApiResponse<T> 泛型接口

代码规范

  • ESLint 9 Flat Config: 纯 Flat 配置
  • 错误处理: 所有 catch 块使用 error: unknown
  • 函数长度: 单个函数 ≤ 50 行
  • 嵌套深度: 禁止超过 3 层嵌套
  • 早退模式: 优先使用 Guard Clauses

构建验证

  • 生产构建: pnpm build 必须通过
  • 类型检查: TypeScript 严格模式
  • ESLint: 无错误

重要文件位置

核心架构

  • 工作流: src/lib/graph/index.ts
  • 状态定义: src/lib/graph/state.ts
  • Agent 节点: src/lib/agents/
  • LLM 配置: src/lib/llm/config.ts
  • LLM 调用: src/lib/llm/helper.ts

前端组件

  • 主界面: src/app/page.tsx
  • 阶段容器: src/components/stages/
  • 状态管理: src/contexts/StageContext.tsx
  • 会话存储: src/lib/sessionStorage.ts

API

  • 聊天接口: src/app/api/chat/route.ts
  • Server Actions: src/app/actions/

测试

  • 单元测试: tests/
  • E2E 测试: tests/e2e/

运维

  • 清理脚本: scripts/ops/clean.js (支持 13 种选项)
  • 运维菜单: scripts/ops/README.md

提示词管理

目录: prompts/

文件命名: {type}.system.md

修改后: 需重启开发服务器(提示词在内存中缓存)

可用类型:

  • extractor, planner, asker, form-validator
  • risk, tech, mvp, diagram, diagram-update, spec

调试技巧

查看日志

# LLM 调用
pnpm dev | grep "agentType\|LLM cache hit\|Token usage"

# 路由决策
pnpm dev | grep "ROUTING DECISION\|ROUTING:"

# 错误追踪
pnpm dev | grep "ERROR\|Failed"

检查数据

  • IndexedDB: DevTools → Application → IndexedDB → sessions
  • LLM 配置: src/lib/llm/config.ts
  • 环境变量: .env.local

常见问题

  • API 失败: 检查 LLM_API_KEY 和 LLM_BASE_URL
  • 构建错误: 确保使用 pnpm
  • 类型错误: pnpm type-check
  • ESLint 错误: pnpm lint:fix

技术栈版本

  • Next.js: 16.1.1 (App Router, Turbopack)
  • React: 19.2.3
  • TypeScript: 5.9.3
  • ESLint: 9.x (Flat Config)
  • LangChain: 1.2.7
  • LangGraph: 1.0.14
  • Vitest: 单元测试
  • Playwright: E2E 测试
  • 包管理器: pnpm

项目约定

Git 分支

  • feat/xxx: 新功能
  • fix/xxx: Bug 修复
  • docs/xxx: 文档变更

Commit Message

<type>(<scope>): <description>

feat(extractor): 添加多语言支持
fix(planner): 修复循环检测逻辑
docs(readme): 更新环境变量说明

文件组织

src/
├── app/                    # Next.js App Router
│   ├── api/chat/route.ts   # API 端点
│   └── actions/            # Server Actions
├── components/             # React 组件
│   └── stages/             # 阶段组件
├── contexts/               # React Context
├── lib/
│   ├── agents/             # 8 个 Agent 节点
│   ├── cache/              # LRU 缓存
│   ├── graph/              # LangGraph 工作流
│   ├── llm/                # LLM 调用封装
│   ├── logger/             # 日志系统
│   ├── streaming/          # SSE 流式
│   ├── utils/              # 工具函数
│   └── sessionStorage.ts   # IndexedDB 封装
├── types/                  # TypeScript 类型定义
└── lib/                    # 工具库

快速开始

  1. 配置环境变量:

    cp .env.example .env.local
    # 编辑 .env.local,填入 LLM_API_KEY
  2. 安装依赖:

    pnpm install
  3. 启动开发:

    pnpm dev
  4. 运行测试:

    pnpm test
    pnpm test:e2e
  5. 代码检查:

    pnpm check

项目特点

LangGraph 状态机: 可视化工作流,状态持久化 ✅ 8 个专用 Agent: 各司其职,参数优化 ✅ LLM 优化: 缓存 + 重试 + 配置化调用 ✅ React 19: Server Actions, useTransition, PPR ✅ 完整日志: JSON 格式,5 级日志系统 ✅ 全面测试: Vitest + Playwright ✅ 运维工具: 自动化脚本,一键清理 ✅ 类型安全: 零 any,严格模式 ✅ 性能优化: 多项指标提升 20-300%


最后更新: 2026-01-11 文档维护: 保持与代码同步更新

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 93.7%
  • JavaScript 5.2%
  • Other 1.1%