diff --git a/docs/discovery-workflow.md b/docs/discovery-workflow.md new file mode 100644 index 0000000..d6a6224 --- /dev/null +++ b/docs/discovery-workflow.md @@ -0,0 +1,437 @@ +# 项目发现工作流 (Project Discovery Workflow) + +本文档详细说明了 AI 项目自动发现和收录的完整工作流程。 + +## 📋 工作流概览 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 项目发现完整流程 │ +└─────────────────────────────────────────────────────────────────┘ + +1. n8n 自动化平台 + │ + ├─ 定期抓取 GitHub/Twitter/HackerNews 等平台 + ├─ 筛选符合条件的项目链接 + │ + ▼ +2. 调用创建任务 API + POST /api/discovery/tasks + │ + ├─ 存入 ProjectDiscoveryTask 表 + ├─ 状态: PENDING + │ + ▼ +3. 手动触发本地命令 (定期执行) + /discover-projects + │ + ├─ 通过 curl 获取待处理任务 + ├─ 调用 Content Explorer Agent + │ ├─ 使用 agent-browser 探索项目 + │ ├─ 提取项目信息 (README, 代码结构等) + │ ├─ 生成结构化 JSON 数据 + │ └─ 应用内容质量标准 + │ + ├─ 调用 API Submitter Agent + │ ├─ 批量标记任务为 IN_PROGRESS + │ ├─ 提交探索数据到完成 API + │ └─ 自动重试失败的提交 + │ + ▼ +4. 完成任务并入库 + POST /api/discovery/tasks/{id}/complete + │ + ├─ 验证数据格式 (Zod Schema) + ├─ 多级去重检测 (GitHub/Website URL) + ├─ 创建或更新 Project + ├─ 创建 Tag 和关联关系 + ├─ 创建 ExternalLink + │ + ├─ 更新任务状态: COMPLETED/FAILED + │ + ▼ +5. 数据已入库,可在前台展示 +``` + +--- + +## 🔄 详细步骤说明 + +### 步骤 1: n8n 自动收集项目链接 + +**平台**: n8n 自动化平台 (独立部署) + +**工作内容**: +- 定期抓取 GitHub Trending、Twitter、HackerNews 等平台 +- 根据关键词筛选 AI 相关项目 +- 提取项目的基本信息 (名称、链接、简介等) + +**输出数据格式**: +```json +{ + "sourceUrl": "https://github.com/langchain-ai/langchain", + "sourceType": "github_trending" // 或 "twitter", "hackernews" 等 +} +``` + +--- + +### 步骤 2: 调用创建任务 API + +**API 端点**: `POST /api/discovery/tasks` + +**调用示例**: +```bash +curl -X POST https://your-domain.com/api/discovery/tasks \ + -H "Content-Type: application/json" \ + -H "x-api-key: YOUR_API_KEY" \ + -d '{ + "apiKey": "YOUR_API_KEY", + "tasks": [ + { + "sourceUrl": "https://github.com/langchain-ai/langchain", + "sourceType": "github_trending" + }, + { + "sourceUrl": "https://github.com/openai/openai-quickstart-python", + "sourceType": "github_trending" + } + ] + }' +``` + +**数据库变更**: +- 在 `ProjectDiscoveryTask` 表中插入新记录 +- `status` = `PENDING` +- `sourceUrl` 和 `sourceType` 来自 n8n +- `createdAt` = 当前时间 + +--- + +### 步骤 3: 手动触发本地命令 + +**执行环境**: 本地开发环境 (Local Development) + +**执行命令**: +```bash +# 处理默认 10 个任务 (每批 3 个) +/discover-projects + +# 处理指定数量的任务 +/discover-projects 20 + +# 自定义批次大小 +/discover-projects 9 --batch=2 + +# 处理所有待处理任务 +/discover-projects all --batch=5 +``` + +**命令执行流程**: +1. 通过 curl 调用 `GET /api/discovery/tasks?status=PENDING&limit=N` +2. 获取待处理的任务列表 +3. 分批处理 (默认每批 3 个任务) +4. 为每个任务启动 **Content Explorer Agent** + +--- + +### 步骤 3.1: Content Explorer Agent (项目探索) + +**Agent 定义**: `.claude/agents/content-explorer-agent.md` + +**核心能力**: +- 使用 `agent-browser` 子任务并行探索 GitHub 项目 +- 访问项目主页、README、代码结构 +- 提取项目元数据 (名称、描述、标签、链接等) +- 生成符合 `ProjectInputSchema` 的 JSON 数据 + +**内容质量标准** (参考: `.claude/schemas/project-content-template.md`): +- ✅ **描述**: 客观说明功能、突出价值、避免营销术语、10-500字 +- ✅ **内容**: 从 README 提取并重新组织、符合中文表达习惯 +- ✅ **链接**: 必须包含 GITHUB 链接、所有链接可访问 +- ✅ **标签**: 1-10 个标签、按技术/应用/状态分类 +- ✅ **动态数据**: Star/Fork 等动态数据不写入内容,使用 GitHub Badge + +**输出数据格式**: +```json +{ + "name": "LangChain", + "nameEn": "LangChain", + "description": "开发由 LLM 驱动的应用程序的框架,提供文档加载、文本分割、向量存储等核心组件", + "descriptionEn": "Framework for developing applications powered by language models", + "content": "## 核心功能\n\n- 文档加载: 支持 PDF、TXT、网页等多种格式\n- 文本分割: 智能分割长文本\n...", + "tags": [ + { "name": "LLM", "nameEn": "Large Language Model" }, + { "name": "框架", "nameEn": "Framework" } + ], + "links": [ + { "type": "GITHUB", "url": "https://github.com/langchain-ai/langchain", "title": "GitHub 仓库" }, + { "type": "WEBSITE", "url": "https://python.langchain.com", "title": "官方文档" } + ], + "status": "ACTIVE" +} +``` + +--- + +### 步骤 3.2: API Submitter Agent (数据提交) + +**Agent 定义**: `.claude/agents/api-submitter-agent.md` + +**核心能力**: +- 批量标记任务为 `IN_PROGRESS` +- 调用 `POST /api/discovery/tasks/{id}/complete` 提交数据 +- 自动重试失败的提交 (指数退避,最多 3 次) +- 处理部分成功/失败情况 + +**提交流程**: +``` +1. PATCH /api/discovery/tasks/{id} → status=IN_PROGRESS + ↓ +2. POST /api/discovery/tasks/{id}/complete → 提交探索数据 + ↓ +3. 检查响应 + ├─ 成功 → 标记任务完成 + ├─ 失败 → 重试 (最多 3 次) + └─ 最终失败 → 记录错误信息 +``` + +--- + +### 步骤 4: 完成任务并入库 + +**API 端点**: `POST /api/discovery/tasks/{id}/complete` + +**处理逻辑** (参考: `src/app/api/discovery/tasks/[id]/complete/route.ts`): + +1. **验证数据格式**: 使用 `ProjectInputSchema` 验证 +2. **多级去重检测**: + - 优先级 1: GitHub URL 精确匹配 + - 优先级 2: Website URL 精确匹配 + - 优先级 3: slug 匹配 +3. **创建或更新项目**: + - 如果存在重复项目 → 更新所有字段、标签、链接 + - 如果不存在 → 创建新项目 +4. **更新任务状态**: + - 成功 → `COMPLETED` + - 失败 → `FAILED` (记录错误信息) + +**数据库变更**: +- `Project` 表: 创建或更新记录 +- `Tag` 表: Upsert 标签 +- `ProjectTag` 表: 创建关联关系 +- `ExternalLink` 表: 创建或更新链接 +- `ProjectDiscoveryTask` 表: 更新 `status`、`projectId`、`completedAt` + +--- + +## 🗂️ 数据模型关系 + +``` +ProjectDiscoveryTask (任务表) + ├─ id: String (主键) + ├─ status: TaskStatus (PENDING/IN_PROGRESS/COMPLETED/FAILED) + ├─ sourceUrl: String (n8n 提供的原始 URL) + ├─ sourceType: String (github_trending/twitter/hackernews) + ├─ explorationData: Json (Agent 探索结果) + ├─ explorationSummary: String (探索摘要) + ├─ projectId: String (关联到 Project.id) + ├─ errorMessage: String (失败原因) + └─ createdAt/startedAt/completedAt: DateTime + +Project (项目表) ← 通过 projectId 关联 + ├─ id, name, nameEn, slug + ├─ description, descriptionEn + ├─ content, contentEn + ├─ status (ACTIVE/ARCHIVED) + └─ 关联: tags, links, discoveryTasks + +Tag (标签表) + └─ 通过 ProjectTag 多对多关联 + +ExternalLink (外部链接表) + └─ 通过 projectId 一对多关联 +``` + +--- + +## 🔧 环境配置 + +### 环境变量 + +```env +# .env.local (本地开发) +WEBHOOK_API_KEY=your-production-api-key-here # 用于调用完成 API + +# 生产环境 (Vercel Dashboard 配置) +DATABASE_URL=postgres://... +WEBHOOK_API_KEY=your-production-api-key-here +``` + +### 依赖服务 + +1. **n8n 平台**: + - 独立部署 (自托管或云服务) + - 配置定时工作流 (Workflow) + - 存储 `WEBHOOK_API_KEY` 用于 API 调用 + +2. **本地开发环境**: + - Node.js 18+ + - pnpm 包管理器 + - Claude Code CLI (支持斜杠命令) + +3. **生产环境**: + - Vercel (Next.js 部署) + - Neon PostgreSQL (数据库) + +--- + +## 📊 执行监控 + +### 查看待处理任务 + +```bash +# 查询待处理任务数量 +curl https://your-domain.com/api/discovery/tasks?status=PENDING&limit=100 + +# 查询进行中的任务 +curl https://your-domain.com/api/discovery/tasks?status=IN_PROGRESS + +# 查询失败的任务 (需要重试) +curl https://your-domain.com/api/discovery/tasks?status=FAILED +``` + +### 重试失败任务 + +```bash +# 手动重试失败的任务 +/discover-projects 10 --status=FAILED +``` + +--- + +## 🎯 质量保障 + +### 内容质量标准 (详细参考: `.claude/schemas/project-content-template.md`) + +1. **描述要求**: + - 清晰说明项目的核心功能 + - 突出项目的独特价值 + - 避免使用营销术语 ("最好"、"第一"、"革命性" 等) + - 字数控制在 10-500 字 + +2. **内容要求**: + - 从项目 README 提取并重新组织 + - 避免机械翻译,符合中文表达习惯 + - 支持 Markdown 格式 + - 动态数据 (Star/Fork) 不写入内容 + +3. **链接要求**: + - 必须包含 GITHUB 链接 + - 所有链接必须可访问 + - 链接类型必须正确 (WEBSITE/GITHUB/HUGGINGFACE/PAPER) + +4. **标签要求**: + - 1-10 个标签 + - 按技术栈/应用领域/开发状态分类 + - 中英文对应 + +### 数据验证 + +所有提交的数据必须通过 `ProjectInputSchema` 验证 (详见 `src/lib/validations.ts`): + +```typescript +ProjectInputSchema { + name: string (1-200字符, 必填) + description: string (10-500字符, 必填) + tags: Tag[] (1-10个, 必填) + links: ExternalLink[] (1-10个, 必填) + nameEn?: string (1-200字符) + descriptionEn?: string + content?: string (Markdown, 最多10000字符) + contentEn?: string + status?: "ACTIVE" | "ARCHIVED" + source?: string +} +``` + +--- + +## 🚀 快速开始 + +### 第一次使用 + +1. **配置 n8n 工作流**: + - 创建新的 n8n Workflow + - 配置定时触发器 (如每天凌晨 2 点) + - 添加 HTTP Request 节点调用 `POST /api/discovery/tasks` + +2. **本地执行命令**: + ```bash + # 启动开发服务器 (如果未运行) + pnpm dev + + # 执行项目发现命令 + /discover-projects + ``` + +3. **查看结果**: + - 访问 https://your-domain.com 查看新收录的项目 + - 检查数据库确认数据正确性 + +### 日常维护 + +1. **定期执行命令** (建议每天 1-2 次): + ```bash + /discover-projects 20 + ``` + +2. **监控失败任务**: + - 检查 `status=FAILED` 的任务 + - 分析错误原因 (网络问题、数据格式等) + - 必要时手动重试 + +3. **优化内容质量**: + - 随机抽查已收录项目的描述和内容 + - 调整 Agent 的提示词以提升质量 + +--- + +## 🔍 故障排查 + +### 常见问题 + +1. **任务长时间处于 IN_PROGRESS 状态**: + - 可能原因: Agent 探索超时、网络问题 + - 解决方案: 手动更新任务状态为 PENDING 后重试 + +2. **大量任务失败**: + - 检查 `errorMessage` 字段 + - 常见原因: 数据格式不正确、URL 无法访问、API Key 错误 + +3. **重复项目被创建**: + - 检查去重逻辑是否正常工作 + - 确认 `ExternalLink` 表的索引 `idx_link_type_url` 存在 + +4. **n8n 无法调用 API**: + - 检查 `WEBHOOK_API_KEY` 是否正确配置 + - 确认 API 端点可访问 + - 查看 n8n 执行日志 + +--- + +## 📚 相关文档 + +- **API 参考**: `docs/api-reference.md` +- **数据模型**: `prisma/schema.prisma` +- **验证规则**: `src/lib/validations.ts` +- **Agent 定义**: `.claude/agents/content-explorer-agent.md` +- **Agent 定义**: `.claude/agents/api-submitter-agent.md` +- **内容质量标准**: `.claude/schemas/project-content-template.md` +- **项目主文档**: `CLAUDE.md` + +--- + +## 📝 更新日志 + +- **2025-01-18**: 创建文档,记录完整的项目发现工作流