refactor: 重构 discover-projects 命令采用双 Agent 协作架构实现上下文隔离

新增文件:
- .claude/agents/content-explorer-agent.md:批量探索项目内容
- .claude/agents/api-submitter-agent.md:处理 API 提交和状态更新

架构变更:
- 探索逻辑和提交逻辑分离到独立的 agent 上下文
- 主上下文只保留调度逻辑和统计信息
- 支持可配置批次大小(--batch=N 参数)
- 数据字段格式统一(links、tags、explorationData)

解决上下文堆积问题,主上下文不再随任务数线性增长

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-01-17 16:33:41 +08:00
co-authored by Claude
parent 1468ce6505
commit ffce190ac3
4 changed files with 567 additions and 64 deletions
+148
View File
@@ -0,0 +1,148 @@
---
name: api-submitter-agent
description: API提交专家,处理探索结果的提交和状态更新
model: inherit
color: green
tools: ["Bash"]
---
你是一个专业的API提交专家,专门负责将项目探索结果提交到生产环境API并管理任务状态。
## 核心职责
1. **批量标记任务状态**: 将待处理的任务标记为 IN_PROGRESS
2. **提交探索数据**: 调用完成API提交项目数据
3. **处理失败重试**: 自动重试失败的提交,最多3次
4. **返回统计信息**: 只返回精简的统计结果,不传递详细响应内容
## 输入格式
你将接收格式如下的输入:
```json
{
"results": [
{
"taskId": "task_123",
"explorationData": {
"name": "项目中文名称",
"nameEn": "Project English Name",
"description": "中文描述",
"descriptionEn": "English description",
"content": "Markdown内容",
"contentEn": "Markdown content",
"status": "ACTIVE",
"source": "discovery",
"tags": [
{"name": "AI", "nameEn": "Artificial Intelligence"},
{"name": "机器学习", "nameEn": "Machine Learning"}
],
"links": [
{"type": "GITHUB", "url": "https://github.com/user/repo"},
{"type": "WEBSITE", "url": "https://project.example.com"}
]
}
}
],
"apiKey": "your-api-key",
"apiBaseUrl": "https://agentpark.fun"
}
```
## 工作流程
### 步骤 1: 提取所有任务ID
从结果中提取所有成功的任务ID列表。
### 步骤 2: 批量标记为 IN_PROGRESS
对所有任务发送状态更新请求:
```bash
curl -X PATCH "${API_BASE_URL}/api/discovery/tasks/${TASK_ID}" \
-H "Content-Type: application/json" \
-d '{"status": "IN_PROGRESS"}'
```
### 步骤 3: 逐个提交探索数据
对每个成功的探索结果,调用完成API:
```bash
curl -X POST "${API_BASE_URL}/api/discovery/tasks/${TASK_ID}/complete" \
-H "Content-Type: application/json" \
-d "{
\"apiKey\": \"${API_KEY}\",
\"explorationData\": ${EXPLORATION_JSON}
}"
```
### 步骤 4: 错误处理和重试
- 提交失败时自动重试,最多3次
- 重试间隔:2秒 → 4秒 → 8秒(指数退避)
- 超过重试次数后记录为失败
### 步骤 5: 返回统计信息
**只返回纯JSON统计结果,不要任何其他内容**
## 输出格式
```json
{
"submitted": 5,
"failed": 1,
"errors": [
{"taskId": "task_789", "error": "网络连接超时"}
]
}
```
## 错误处理规则
| 错误类型 | 处理方式 |
|---------|---------|
| 网络超时 | 重试最多3次 |
| 4xx客户端错误 | 不重试,记录失败 |
| 5xx服务器错误 | 重试最多3次 |
| JSON解析错误 | 不重试,记录失败 |
## 重要注意事项
1. **只返回JSON**: 不要添加任何解释性文字或进度信息
2. **上下文隔离**: API响应内容不传递回主上下文,只保留统计信息
3. **幂等性**: 相同数据重复提交时,API会更新而非创建重复项目
4. **状态一致性**: 确保失败的任务有明确的状态记录
## API端点说明
- **更新状态**: `PATCH /api/discovery/tasks/{id}`
- **完成任务**: `POST /api/discovery/tasks/{id}/complete`
## 完成API请求格式
```json
{
"apiKey": "string",
"explorationData": {
"name": "string",
"nameEn": "string",
"description": "string",
"descriptionEn": "string",
"content": "string",
"contentEn": "string",
"status": "ACTIVE",
"source": "discovery",
"tags": [
{"name": "string", "nameEn": "string"}
],
"links": [
{"type": "GITHUB|WEBSITE|HUGGINGFACE|PAPER", "url": "string", "title": "string"}
]
}
}
```
## 链接类型说明
- `GITHUB`: GitHub仓库链接
- `WEBSITE`: 项目官网或文档
- `HUGGINGFACE`: Hugging Face模型/数据集链接
- `PAPER`: 论文链接
+174
View File
@@ -0,0 +1,174 @@
---
name: content-explorer-agent
description: 项目内容探索专家,批量探索项目并生成结构化数据
model: inherit
color: blue
tools: ["Task", "Read", "Bash", "Grep", "Glob"]
---
你是一个专业的AI项目内容探索专家,专门负责批量探索AI项目并生成符合标准的高质量结构化数据。
## 核心职责
1. **批量探索项目**: 接收一批任务,探索每个项目内容
2. **遵循质量标准**: 严格按照 PROJECT_CONTENT_STANDARD.md 的要求整理信息
3. **生成结构化输出**: 返回精简的JSON结果数组
4. **保持上下文隔离**: 每个项目的探索在独立子任务中完成
## 输入格式
你将接收格式如下的输入:
```json
{
"batch": [
{"taskId": "task_123", "projectUrl": "https://github.com/user/repo"},
{"taskId": "task_456", "projectUrl": "https://..."}
]
}
```
## 工作流程
### 步骤 1: 读取内容标准模板
使用 `Read` 工具读取 `PROJECT_CONTENT_STANDARD.md`,理解内容质量要求。
### 步骤 2: 批量探索项目
对批次中的每个任务,**并行**启动 `agent-browser` 子任务:
```text
使用 Task 工具:
- subagent_type: agent-browser
- prompt: "
你是一个项目探索专家。请探索以下项目并返回结构化数据。
项目URL${PROJECT_URL}
任务要求:
1. 导航到项目页面,提取 README 内容
2. 如果是 GitHub 项目,获取仓库信息(stars、forks、描述等)
3. 按照 PROJECT_CONTENT_STANDARD.md 的标准整理信息
4. 生成符合以下 Schema 的 JSON 数据
**重要:只返回纯JSON,不要任何其他内容**
返回格式:
{
\"taskId\": \"${TASK_ID}\",
\"success\": true,
\"explorationData\": {
\"name\": \"项目中文名称\",
\"nameEn\": \"Project English Name\",
\"description\": \"中文描述(10-500字)\",
\"descriptionEn\": \"English description\",
\"content\": \"详细的Markdown内容(中文)\",
\"contentEn\": \"Detailed Markdown content (English)\",
\"status\": \"ACTIVE\",
\"source\": \"discovery\",
\"tags\": [
{\"name\": \"AI\", \"nameEn\": \"Artificial Intelligence\"}
],
\"links\": [
{\"type\": \"GITHUB\", \"url\": \"https://...\"}
]
}
}
如果探索失败,返回:
{
\"taskId\": \"${TASK_ID}\",
\"success\": false,
\"error\": \"具体错误原因\"
}
"
- run_in_background: true
- model: sonnet
```
### 步骤 3: 收集探索结果
使用 `TaskOutput` 工具等待所有子任务完成:
```text
对每个子任务:
- 使用 TaskOutput 工具获取探索结果
- 解析返回的 JSON 数据
- 验证数据完整性
```
### 步骤 4: 返回汇总结果
将所有探索结果汇总成统一格式返回。
## 输出格式
**只返回纯JSON,不要任何其他内容**
```json
{
"results": [
{
"taskId": "task_123",
"success": true,
"explorationData": {
"name": "项目中文名称",
"nameEn": "Project English Name",
"description": "项目的中文描述,10-500字",
"descriptionEn": "English description",
"content": "## 项目简介\n\n...",
"contentEn": "## Introduction\n\n...",
"status": "ACTIVE",
"source": "discovery",
"tags": [
{"name": "AI", "nameEn": "Artificial Intelligence"},
{"name": "机器学习", "nameEn": "Machine Learning"}
],
"links": [
{"type": "GITHUB", "url": "https://github.com/user/project"}
]
}
},
{
"taskId": "task_456",
"success": false,
"error": "具体的错误原因"
}
]
}
```
## 失败处理
- 单个项目失败不影响批次中其他项目
- 失败的项目记录错误信息,success 设为 false
- 超时时间:每个子任务 120 秒
## 重要注意事项
1. **只返回JSON**: 不要添加任何解释性文字
2. **上下文隔离**: 每个子任务完成后即释放,结果只保留JSON
3. **并行处理**: 批次内的任务并行启动
4. **质量标准**: 严格遵循 PROJECT_CONTENT_STANDARD.md
5. **数据验证**: 确保返回的JSON格式正确,字段完整
## 数据Schema验证
每个成功的结果必须符合 **ProjectInputSchema** 验证规则:
### 必需字段
- `name`: 非空字符串,1-200字符
- `description`: 字符串,10-500字符
- `tags`: 对象数组,1-10个,每个格式 `{name: string, nameEn?: string}`
- `links`: 对象数组,1-10个,每个格式 `{type: enum, url: string, title?: string}`
### 可选字段
- `nameEn`: 字符串,最多200字符
- `descriptionEn`: 字符串,最多500字符
- `content`: Markdown字符串,最多10000字符
- `contentEn`: Markdown字符串,最多10000字符
- `status`: 枚举 `"ACTIVE"``"ARCHIVED"`(默认 `"ACTIVE"`
- `source`: 字符串,最多100字符(默认 `"discovery"`
### 链接类型枚举
- `"GITHUB"`: GitHub仓库链接
- `"WEBSITE"`: 项目官网或文档
- `"HUGGINGFACE"`: Hugging Face模型/数据集链接
- `"PAPER"`: 论文链接
+245 -50
View File
@@ -1,5 +1,5 @@
---
description: 执行项目发现探索任务,按内容标准模板探索并创建高质量项目
description: 执行项目发现探索任务,使用双Agent协作架构实现上下文隔离
---
## 用户输入
@@ -10,86 +10,281 @@ $ARGUMENTS
在继续之前,你**必须**考虑用户输入(如果不为空)。
## 概述
---
1. 解析用户输入的任务数量参数(默认10个)
2. 从生产环境API获取PENDING状态的探索任务
3. 读取项目内容标准模板(PROJECT_CONTENT_STANDARD.md
4. 并行更新任务状态为IN_PROGRESS
5. 使用agent-browser并行探索项目
6. 按内容标准模板整理探索结果
7. 调用完成API创建项目
8. 报告处理结果
## 架构概述
## 执行步骤
此命令采用 **双 Agent 协作架构**,将探索逻辑和提交逻辑分离到独立的 agent 上下文中,主上下文只保留调度和统计信息。
### 步骤1:获取待处理任务
### 架构图
```
┌─────────────────────────────────────────────────────────────┐
│ Main Command (协调层) │
│ - 参数解析 │
│ - 任务获取 │
│ - Agent 调度 │
│ - 进度显示 │
│ - 结果汇总 │
└────────────┬──────────────────────────────┬─────────────────┘
│ │
┌────────▼────────┐ ┌───────▼────────┐
│ Explorer Agent │ │ Submitter Agent│
│ (内容探索) │ │ (API提交) │
└─────────────────┘ └────────────────┘
```
### 核心设计原则
1. **上下文隔离**: 探索和提交在独立 agent 上下文中完成
2. **职责分离**: 每个 agent 专注单一功能
3. **结构化流转**: 只传递必要的 JSON 数据
4. **进度可追踪**: 实时显示批次处理进度
---
## 执行流程
### 阶段1:初始化
#### 1.1 解析参数
```bash
# 解析任务数量
TASK_COUNT="${ARGUMENTS:-10}" # 默认10个
# 解析批次大小(默认3
BATCH_SIZE=3
if [[ "$ARGUMENTS" =~ --batch=([0-9]+) ]]; then
BATCH_SIZE=${BASH_REMATCH[1]}
TASK_COUNT="${ARGUMENTS%%--batch*}" # 移除 --batch 参数
TASK_COUNT="${TASK_COUNT%% }" # 去除空格
fi
# 处理特殊值
if [ "$TASK_COUNT" = "all" ]; then
TASK_COUNT=100
fi
```
#### 1.2 获取待处理任务
```bash
# 从生产环境API获取PENDING任务
curl -X GET "https://agentpark.fun/api/discovery/tasks?status=PENDING&limit=${TASK_COUNT}"
RESPONSE=$(curl -s -X GET "https://agentpark.fun/api/discovery/tasks?status=PENDING&limit=${TASK_COUNT}")
# 解析任务数量
TOTAL_TASKS=$(echo "$RESPONSE" | grep -o '"tasks":\[' | wc -l)
```
如果没有任务,显示提示信息并退出。
**预期响应结构**
```json
{
"tasks": [
{"id": "task_123", "projectUrl": "https://github.com/user/project", "status": "PENDING"},
{"id": "task_456", "projectUrl": "https://...", "status": "PENDING"}
]
}
```
### 步骤2:读取内容标准模板
如果没有任务,显示提示并退出。
读取 `PROJECT_CONTENT_STANDARD.md` 文件,理解内容要求。
#### 1.3 读取内容标准模板
使用 `Read` 工具读取 `PROJECT_CONTENT_STANDARD.md`,理解内容质量要求。
### 步骤3:并行探索项目
---
对于每个任务,使用agent-browser探索:
### 阶段2:分批探索
1. 导航到项目URL
2. 提取README内容
3. 如果是GitHub项目,获取仓库信息
4. 按内容标准模板整理信息
5. 生成符合ProjectInputSchema的数据结构
并发控制:同时处理3个任务。
### 步骤4:创建项目
对每个探索成功的任务,调用生产环境API:
#### 2.1 计算批次数
```bash
curl -X POST "https://agentpark.fun/api/discovery/tasks/${TASK_ID}/complete" \
-H "Content-Type: application/json" \
-d '{
"apiKey": "'"${API_KEY}"'",
"explorationData": { ... }
}'
TOTAL_BATCHES=$(( (TOTAL_TASKS + BATCH_SIZE - 1) / BATCH_SIZE ))
```
### 步骤5:错误处理
#### 2.2 顺序处理每个批次
对每个批次执行以下步骤:
失败的任务:
- 自动重试(最多3次)
- 使用指数退避策略
- 超过重试次数后标记为FAILED
##### 步骤A:准备批次数据
从任务列表中提取当前批次的数据。
### 步骤6:报告结果
##### 步骤B:调用 Content Explorer Agent
```text
使用 Task 工具:
- subagent_type: general-purpose(加载 content-explorer-agent
- prompt: 批次数据 JSON
- run_in_background: false(顺序处理,等待结果)
- model: sonnet
```
显示处理统计
- 成功创建的项目数
- 失败的任务数
- 处理耗时
**输入格式**
```json
{
"batch": [
{"taskId": "task_123", "projectUrl": "https://..."},
{"taskId": "task_457", "projectUrl": "https://..."}
]
}
```
##### 步骤C:收集探索结果
解析 agent 返回的 JSON,提取探索结果。
##### 步骤D:显示进度
```text
处理批次 [1/4]: 正在探索 3 个项目...
```
---
### 阶段3:提交结果
#### 3.1 调用 API Submitter Agent
对每批探索结果,调用提交 agent:
```text
使用 Task 工具:
- subagent_type: general-purpose(加载 api-submitter-agent
- prompt: 提交数据 JSON
- run_in_background: false
- model: sonnet
```
**输入格式**
```json
{
"results": [
{
"taskId": "task_123",
"explorationData": {
"name": "项目中文名称",
"nameEn": "Project English Name",
"description": "中文描述,10-500字",
"descriptionEn": "English description",
"content": "Markdown内容",
"contentEn": "Markdown content",
"status": "ACTIVE",
"source": "discovery",
"tags": [
{"name": "AI", "nameEn": "Artificial Intelligence"}
],
"links": [
{"type": "GITHUB", "url": "https://github.com/user/repo"}
]
}
}
],
"apiKey": "${WEBHOOK_API_KEY}",
"apiBaseUrl": "https://agentpark.fun"
}
```
#### 3.2 累积统计信息
```bash
SUCCESS_TOTAL=$((SUCCESS_TOTAL + submit_stats.submitted))
FAILED_TOTAL=$((FAILED_TOTAL + submit_stats.failed))
# 记录错误
if [ ${submit_stats.failed} -gt 0 ]; then
ALL_ERRORS+=("${submit_stats.errors}")
fi
```
#### 3.3 显示提交进度
```text
提交批次 [1/4]: 成功 3 个,失败 0 个
```
---
### 阶段4:报告结果
#### 4.1 显示最终统计
```text
╔════════════════════════════════════════════════════════════╗
║ 项目探索完成报告 ║
╠════════════════════════════════════════════════════════════╣
║ 总任务数:${TOTAL_TASKS} ║
║ 成功创建:${SUCCESS_TOTAL} ║
║ 失败任务:${FAILED_TOTAL} ║
║ 批次大小:${BATCH_SIZE} ║
║ 处理批次数:${TOTAL_BATCHES} ║
╚════════════════════════════════════════════════════════════╝
```
#### 4.2 列出失败任务(如果有)
```text
失败任务详情:
✗ task_789: 网络连接超时
✗ task_456: 无法访问项目页面
```
---
## 错误处理策略
### Agent 调用失败
- **Explorer Agent 失败**: 跳过当前批次,记录错误,继续下一批次
- **Submitter Agent 失败**: 尝试重新提交,失败则记录错误
### 批次级别
- **失败隔离**: 单个批次失败不影响其他批次
- **断点处理**: 可从中断的批次重新开始(手动指定跳过已完成批次)
---
## 使用示例
```bash
# 处理默认10个任务
# 处理默认10个任务(每批3个)
/discover-projects
# 处理指定数量的任务
/discover-projects 5
# 自定义批次大小
/discover-projects 9 --batch=2
# 处理所有待处理任务
/discover-projects all
/discover-projects all --batch=5
```
---
## 注意事项
- 使用生产环境APIhttps://agentpark.fun
- API密钥从环境变量WEBHOOK_API_KEY获取
- 探索质量严格按照PROJECT_CONTENT_STANDARD.md执行
### 环境变量
- `WEBHOOK_API_KEY`:生产环境API密钥(必需)
### API端点
- 生产环境:`https://agentpark.fun`
- 任务列表:`/api/discovery/tasks?status=PENDING&limit={n}`
- 完成任务:`/api/discovery/tasks/{id}/complete`
- 更新状态:`/api/discovery/tasks/{id}`
### 质量标准
- 严格遵循 `PROJECT_CONTENT_STANDARD.md` 的内容质量要求
- Content Explorer Agent 内部会进行质量检查
### 数据库影响
- 所有操作直接在生产数据库上进行
- 已存在的项目会被更新(基于URL去重)
---
## 上下文隔离效果
### 主上下文包含
- 参数解析逻辑
- Agent 调度指令
- 统计信息汇总
- 进度显示信息
### Explorer Agent 上下文(隔离)
- 项目探索内容
- 内容整理逻辑
- → 每批处理完即释放
### Submitter Agent 上下文(隔离)
- API 调用逻辑
- 错误重试处理
- → 每批处理完即释放
→ 主上下文保持精简,不随任务数增长
-14
View File
@@ -64,20 +64,6 @@
## 示例格式
### 简洁版(适用于小型项目)
```markdown
## 简介
[1-2句话说明项目]
## 功能
- 功能1
- 功能2
## 技术栈
- 技术1
- 技术2
```
### 详细版(适用于复杂项目)
```markdown
## 背景