Files
agent-park/docs/discovery-workflow.md
T
mzaxd 13acdd426b docs: 完善 CLAUDE.md 开发指南和项目发现工作流文档
- 添加常见开发模式指南(API 端点、数据库字段、自定义 Agent、多语言内容)
- 新增故障排除部分,涵盖常见问题和调试技巧
- 改进 GET /api/discovery/tasks 端点,支持通过查询参数传递 API key
- 更新环境变量示例,使用更安全的 API key 格式
2026-01-19 07:57:44 +08:00

549 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目发现工作流 (Project Discovery Workflow)
本文档详细说明了 AI 项目自动发现和收录的完整工作流程。
## 📋 工作流概览
```
┌─────────────────────────────────────────────────────────────────┐
│ 项目发现完整流程 │
└─────────────────────────────────────────────────────────────────┘
1. n8n 自动化平台
├─ 定期抓取 GitHub/Twitter/HackerNews 等平台
├─ 筛选符合条件的项目链接
2. 调用去重检查 API (推荐)
POST /api/discovery/check-duplicates
├─ 检查 URL 是否已存在任务
├─ 检查 URL 对应项目是否已收录
├─ 过滤出需要创建的 URL
3. 调用创建任务 API
POST /api/discovery/tasks
├─ 存入 ProjectDiscoveryTask 表
├─ 状态: PENDING
4. 手动触发本地命令 (定期执行)
/discover-projects
├─ 通过 curl 获取待处理任务
├─ 调用 Content Explorer Agent
│ ├─ 使用 agent-browser 探索项目
│ ├─ 提取项目信息 (README, 代码结构等)
│ ├─ 生成结构化 JSON 数据
│ └─ 应用内容质量标准
├─ 调用 API Submitter Agent
│ ├─ 批量标记任务为 IN_PROGRESS
│ ├─ 提交探索数据到完成 API
│ └─ 自动重试失败的提交
5. 完成任务并入库
POST /api/discovery/tasks/{id}/complete
├─ 验证数据格式 (Zod Schema)
├─ 多级去重检测 (GitHub/Website URL)
├─ 创建或更新 Project
├─ 创建 Tag 和关联关系
├─ 创建 ExternalLink
├─ 更新任务状态: COMPLETED/FAILED
6. 数据已入库,可在前台展示
```
---
## 🔄 详细步骤说明
### 步骤 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` = 当前时间
---
### 步骤 2.5: 调用去重检查 API(推荐)
**API 端点**: `POST /api/discovery/check-duplicates`
**调用示例**:
```bash
curl -X POST https://your-domain.com/api/discovery/check-duplicates \
-H "Content-Type: application/json" \
-d '{
"apiKey": "YOUR_API_KEY",
"urls": [
"https://github.com/langchain-ai/langchain",
"https://github.com/openai/openai-quickstart-python"
]
}'
```
**返回结果**:
```json
{
"success": true,
"results": [
{
"url": "https://github.com/langchain-ai/langchain",
"shouldCreate": false,
"reason": "Task already exists with status PENDING",
"existingTask": {
"id": "cmxxxxx",
"status": "PENDING",
"sourceUrl": "https://github.com/langchain-ai/langchain",
"createdAt": "2025-01-18T10:00:00Z",
"projectId": null
}
},
{
"url": "https://github.com/openai/openai-quickstart-python",
"shouldCreate": true,
"reason": "No existing task or project found"
}
],
"stats": {
"total": 2,
"shouldCreate": 1,
"duplicate": 1
}
}
```
**去重逻辑**(按优先级):
1. **优先级 1**: 检查是否有 PENDING/IN_PROGRESS 的相同 URL 任务
- 如果存在 → `shouldCreate: false`
- 原因:任务已在处理中,避免重复探索
2. **优先级 2**: 检查是否有 COMPLETED/FAILED 的相同 URL 任务
- 如果存在 → `shouldCreate: false`
- 原因:任务已探索过,无需重复
3. **优先级 3**: 检查 URL 对应的项目是否已存在(通过 ExternalLink
- 如果存在 → `shouldCreate: false`
- 原因:项目已通过其他来源收录
4. **默认**: 允许创建新任务
- `shouldCreate: true`
**n8n 集成建议**:
```javascript
// n8n Workflow 示例
const checkResponse = await fetch('https://your-domain.com/api/discovery/check-duplicates', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
apiKey: 'YOUR_API_KEY',
urls: collectedUrls // 从上一步收集的 URL 列表
})
})
const { results, stats } = await checkResponse.json()
// 过滤出应该创建任务的 URL
const urlsToCreate = results
.filter(r => r.shouldCreate)
.map(r => r.url)
// 只为不重复的 URL 创建任务
if (urlsToCreate.length > 0) {
await fetch('https://your-domain.com/api/discovery/tasks', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
apiKey: 'YOUR_API_KEY',
tasks: urlsToCreate.map(url => ({
sourceUrl: url,
sourceType: 'github_trending'
}))
})
})
}
console.log(`创建 ${urlsToCreate.length} 个新任务,跳过 ${stats.duplicate} 个重复任务`)
```
---
### 步骤 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=sk_live_your_secure_api_key_min_32_chars # 用于调用完成 API
# 生产环境 (Vercel Dashboard 配置)
DATABASE_URL=postgres://...
WEBHOOK_API_KEY=sk_live_your_secure_api_key_min_32_chars
```
### 依赖服务
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**: 创建文档,记录完整的项目发现工作流