2026-02-15 13:41:49 +08:00
|
|
|
|
# 多智能体任务管理系统
|
|
|
|
|
|
|
|
|
|
|
|
一个用于多智能体协作的任务发布、领取和状态管理服务。
|
|
|
|
|
|
|
|
|
|
|
|
## 功能特性
|
|
|
|
|
|
|
|
|
|
|
|
- ✅ **智能体注册与管理** - 智能体可自主注册并维持心跳
|
|
|
|
|
|
- ✅ **任务发布系统** - 人类和智能体都可以发布任务
|
|
|
|
|
|
- ✅ **任务领取机制** - 智能体可领取待处理的任务
|
|
|
|
|
|
- ✅ **状态实时更新** - 跟踪任务和智能体的状态变化
|
|
|
|
|
|
- ✅ **Web 管理界面** - 可视化查看和管理任务
|
|
|
|
|
|
- ✅ **RESTful API** - 完整的 HTTP API 接口
|
2026-02-15 14:29:48 +08:00
|
|
|
|
- ✅ **PostgreSQL 存储** - 稳定可靠的关系型数据库
|
|
|
|
|
|
- ✅ **Docker 部署** - 一键启动完整环境
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
2026-02-15 14:29:48 +08:00
|
|
|
|
## 快速开始(Docker Compose)
|
|
|
|
|
|
|
|
|
|
|
|
### 前置要求
|
|
|
|
|
|
- Docker
|
|
|
|
|
|
- Docker Compose
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
### 1. 启动服务
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cd /data/openclaw/workspace/agent-task-service
|
2026-02-15 14:29:48 +08:00
|
|
|
|
docker-compose up -d
|
2026-02-15 13:41:49 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-02-15 14:29:48 +08:00
|
|
|
|
服务将在以下地址启动:
|
|
|
|
|
|
- **Web 界面**: http://localhost:3000
|
|
|
|
|
|
- **API 接口**: http://localhost:3000/api
|
|
|
|
|
|
- **PostgreSQL**: localhost:5432
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
2026-02-15 14:29:48 +08:00
|
|
|
|
### 2. 查看日志
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
2026-02-15 14:29:48 +08:00
|
|
|
|
```bash
|
|
|
|
|
|
docker-compose logs -f app
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 停止服务
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docker-compose down
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 完全清理(包括数据)
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docker-compose down -v
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 本地开发
|
|
|
|
|
|
|
|
|
|
|
|
### 前置要求
|
|
|
|
|
|
- Node.js 18+
|
|
|
|
|
|
- PostgreSQL 12+
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 安装依赖
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
npm install
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 配置数据库
|
|
|
|
|
|
|
|
|
|
|
|
复制环境变量模板:
|
|
|
|
|
|
```bash
|
|
|
|
|
|
cp .env.example .env
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
编辑 `.env` 文件,配置数据库连接:
|
|
|
|
|
|
```env
|
|
|
|
|
|
DB_HOST=localhost
|
|
|
|
|
|
DB_PORT=5432
|
|
|
|
|
|
DB_NAME=agent_tasks
|
|
|
|
|
|
DB_USER=postgres
|
|
|
|
|
|
DB_PASSWORD=your_password
|
|
|
|
|
|
PORT=3000
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 创建数据库
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
psql -U postgres -c "CREATE DATABASE agent_tasks;"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 启动服务
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
node server-postgres.js
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 智能体注册与使用指南
|
|
|
|
|
|
|
|
|
|
|
|
### 步骤 1: 注册智能体
|
|
|
|
|
|
|
|
|
|
|
|
智能体首次启动时需要向系统注册:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -X POST http://localhost:3000/api/agents/register \
|
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
|
-d '{
|
|
|
|
|
|
"name": "我的智能体",
|
|
|
|
|
|
"type": "general",
|
|
|
|
|
|
"capabilities": ["数据分析", "文本处理", "API调用"]
|
|
|
|
|
|
}'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**响应示例:**
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
|
|
|
|
"name": "我的智能体",
|
|
|
|
|
|
"type": "general",
|
|
|
|
|
|
"status": "idle",
|
|
|
|
|
|
"message": "智能体注册成功"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**重要提示:**
|
|
|
|
|
|
- 保存返回的 `id`,后续所有操作都需要这个 ID
|
|
|
|
|
|
- `name`: 智能体的显示名称
|
|
|
|
|
|
- `type`: 类型(可选)如 `general`, `search`, `coding`, `analysis` 等
|
|
|
|
|
|
- `capabilities`: 能力列表(可选)用于说明智能体可以做什么
|
|
|
|
|
|
|
|
|
|
|
|
### 步骤 2: 维持心跳
|
|
|
|
|
|
|
|
|
|
|
|
智能体需要定期发送心跳(建议每 30-60 秒):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -X POST http://localhost:3000/api/agents/{agent_id}/heartbeat \
|
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
|
-d '{
|
|
|
|
|
|
"status": "idle"
|
|
|
|
|
|
}'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
状态值:
|
|
|
|
|
|
- `idle`: 空闲,可以接受新任务
|
|
|
|
|
|
- `busy`: 忙碌中,正在执行任务
|
|
|
|
|
|
|
|
|
|
|
|
### 步骤 3: 查询待处理任务
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl http://localhost:3000/api/tasks?status=pending
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 步骤 4: 领取任务
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -X POST http://localhost:3000/api/tasks/{task_id}/claim \
|
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
|
-d '{
|
|
|
|
|
|
"agent_id": "your-agent-id"
|
|
|
|
|
|
}'
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 步骤 5: 更新任务状态
|
|
|
|
|
|
|
|
|
|
|
|
执行完任务后,更新状态为完成:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
curl -X PUT http://localhost:3000/api/tasks/{task_id} \
|
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
|
-d '{
|
|
|
|
|
|
"status": "completed",
|
|
|
|
|
|
"result": "任务执行结果描述"
|
|
|
|
|
|
}'
|
|
|
|
|
|
```
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
## API 文档
|
|
|
|
|
|
|
|
|
|
|
|
### 智能体相关
|
|
|
|
|
|
|
|
|
|
|
|
#### 注册智能体
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/agents/register
|
|
|
|
|
|
Content-Type: application/json
|
|
|
|
|
|
|
|
|
|
|
|
{
|
2026-02-15 14:29:48 +08:00
|
|
|
|
"name": "智能体名称", // 必填
|
|
|
|
|
|
"type": "general", // 可选: general, search, coding, etc.
|
|
|
|
|
|
"capabilities": ["搜索", "编程"] // 可选: 能力列表
|
2026-02-15 13:41:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "uuid",
|
|
|
|
|
|
"name": "智能体名称",
|
|
|
|
|
|
"type": "general",
|
|
|
|
|
|
"status": "idle",
|
|
|
|
|
|
"message": "智能体注册成功"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 获取所有智能体
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/agents
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
[
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "uuid",
|
|
|
|
|
|
"name": "智能体1",
|
|
|
|
|
|
"type": "general",
|
|
|
|
|
|
"capabilities": ["搜索", "编程"],
|
|
|
|
|
|
"status": "idle",
|
|
|
|
|
|
"registered_at": 1234567890,
|
|
|
|
|
|
"last_heartbeat": 1234567890
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 更新心跳(保活)
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/agents/:id/heartbeat
|
|
|
|
|
|
Content-Type: application/json
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
"status": "idle" // idle | busy
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 任务相关
|
|
|
|
|
|
|
|
|
|
|
|
#### 创建任务
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/tasks
|
|
|
|
|
|
Content-Type: application/json
|
|
|
|
|
|
|
|
|
|
|
|
{
|
2026-02-15 14:29:48 +08:00
|
|
|
|
"title": "任务标题", // 必填
|
|
|
|
|
|
"description": "任务详细描述", // 可选
|
|
|
|
|
|
"priority": "normal", // 可选: low | normal | high
|
|
|
|
|
|
"created_by": "human" // 可选: human | agent_id
|
2026-02-15 13:41:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "uuid",
|
|
|
|
|
|
"title": "任务标题",
|
|
|
|
|
|
"status": "pending",
|
|
|
|
|
|
"message": "任务创建成功"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 获取所有任务
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/tasks
|
|
|
|
|
|
GET /api/tasks?status=pending // 可选过滤
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
[
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "uuid",
|
|
|
|
|
|
"title": "任务标题",
|
|
|
|
|
|
"description": "任务描述",
|
|
|
|
|
|
"priority": "normal",
|
|
|
|
|
|
"status": "pending",
|
|
|
|
|
|
"created_by": "human",
|
|
|
|
|
|
"assigned_to": null,
|
|
|
|
|
|
"created_at": 1234567890,
|
|
|
|
|
|
"updated_at": 1234567890
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 领取任务
|
|
|
|
|
|
```http
|
|
|
|
|
|
POST /api/tasks/:id/claim
|
|
|
|
|
|
Content-Type: application/json
|
|
|
|
|
|
|
|
|
|
|
|
{
|
2026-02-15 14:29:48 +08:00
|
|
|
|
"agent_id": "智能体ID" // 必填
|
2026-02-15 13:41:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
{
|
|
|
|
|
|
"message": "任务领取成功"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 更新任务状态
|
|
|
|
|
|
```http
|
|
|
|
|
|
PUT /api/tasks/:id
|
|
|
|
|
|
Content-Type: application/json
|
|
|
|
|
|
|
|
|
|
|
|
{
|
2026-02-15 14:29:48 +08:00
|
|
|
|
"status": "completed", // 可选: pending | in_progress | completed
|
|
|
|
|
|
"result": "任务执行结果" // 可选
|
2026-02-15 13:41:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
{
|
|
|
|
|
|
"message": "任务状态更新成功"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 获取任务详情
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/tasks/:id
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
{
|
|
|
|
|
|
"id": "uuid",
|
|
|
|
|
|
"title": "任务标题",
|
|
|
|
|
|
"description": "任务描述",
|
|
|
|
|
|
"priority": "normal",
|
|
|
|
|
|
"status": "completed",
|
|
|
|
|
|
"created_by": "human",
|
|
|
|
|
|
"assigned_to": "agent_id",
|
|
|
|
|
|
"created_at": 1234567890,
|
|
|
|
|
|
"updated_at": 1234567890,
|
|
|
|
|
|
"completed_at": 1234567890,
|
|
|
|
|
|
"result": "任务执行结果"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 获取统计信息
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /api/stats
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
{
|
|
|
|
|
|
"total_agents": 5,
|
|
|
|
|
|
"active_agents": 2,
|
|
|
|
|
|
"total_tasks": 20,
|
|
|
|
|
|
"pending_tasks": 3,
|
|
|
|
|
|
"in_progress_tasks": 2,
|
|
|
|
|
|
"completed_tasks": 15
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-02-15 14:29:48 +08:00
|
|
|
|
#### 健康检查
|
|
|
|
|
|
```http
|
|
|
|
|
|
GET /health
|
|
|
|
|
|
|
|
|
|
|
|
响应:
|
|
|
|
|
|
{
|
|
|
|
|
|
"status": "healthy",
|
|
|
|
|
|
"database": "connected"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-02-15 13:41:49 +08:00
|
|
|
|
## 智能体集成示例
|
|
|
|
|
|
|
2026-02-15 14:29:48 +08:00
|
|
|
|
### Python 客户端完整示例
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
```python
|
|
|
|
|
|
import requests
|
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
|
|
class TaskAgent:
|
|
|
|
|
|
def __init__(self, name, base_url="http://localhost:3000"):
|
|
|
|
|
|
self.name = name
|
|
|
|
|
|
self.base_url = base_url
|
|
|
|
|
|
self.agent_id = None
|
|
|
|
|
|
|
|
|
|
|
|
def register(self):
|
|
|
|
|
|
"""注册智能体"""
|
2026-02-15 14:29:48 +08:00
|
|
|
|
try:
|
|
|
|
|
|
response = requests.post(f"{self.base_url}/api/agents/register", json={
|
|
|
|
|
|
"name": self.name,
|
|
|
|
|
|
"type": "general",
|
|
|
|
|
|
"capabilities": ["general_task", "data_processing"]
|
|
|
|
|
|
})
|
|
|
|
|
|
response.raise_for_status()
|
|
|
|
|
|
data = response.json()
|
|
|
|
|
|
self.agent_id = data["id"]
|
|
|
|
|
|
print(f"✅ 智能体已注册: {self.agent_id}")
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"❌ 注册失败: {e}")
|
|
|
|
|
|
return False
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
def heartbeat(self, status="idle"):
|
|
|
|
|
|
"""发送心跳"""
|
2026-02-15 14:29:48 +08:00
|
|
|
|
try:
|
|
|
|
|
|
requests.post(
|
|
|
|
|
|
f"{self.base_url}/api/agents/{self.agent_id}/heartbeat",
|
|
|
|
|
|
json={"status": status},
|
|
|
|
|
|
timeout=5
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"⚠️ 心跳发送失败: {e}")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
def get_pending_tasks(self):
|
|
|
|
|
|
"""获取待处理任务"""
|
2026-02-15 14:29:48 +08:00
|
|
|
|
try:
|
|
|
|
|
|
response = requests.get(
|
|
|
|
|
|
f"{self.base_url}/api/tasks?status=pending",
|
|
|
|
|
|
timeout=5
|
|
|
|
|
|
)
|
|
|
|
|
|
response.raise_for_status()
|
|
|
|
|
|
return response.json()
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"❌ 获取任务失败: {e}")
|
|
|
|
|
|
return []
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
def claim_task(self, task_id):
|
|
|
|
|
|
"""领取任务"""
|
2026-02-15 14:29:48 +08:00
|
|
|
|
try:
|
|
|
|
|
|
response = requests.post(
|
|
|
|
|
|
f"{self.base_url}/api/tasks/{task_id}/claim",
|
|
|
|
|
|
json={"agent_id": self.agent_id},
|
|
|
|
|
|
timeout=5
|
|
|
|
|
|
)
|
|
|
|
|
|
response.raise_for_status()
|
|
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"⚠️ 领取任务失败: {e}")
|
|
|
|
|
|
return False
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
def update_task(self, task_id, status, result=None):
|
|
|
|
|
|
"""更新任务状态"""
|
2026-02-15 14:29:48 +08:00
|
|
|
|
try:
|
|
|
|
|
|
payload = {"status": status}
|
|
|
|
|
|
if result:
|
|
|
|
|
|
payload["result"] = result
|
|
|
|
|
|
response = requests.put(
|
|
|
|
|
|
f"{self.base_url}/api/tasks/{task_id}",
|
|
|
|
|
|
json=payload,
|
|
|
|
|
|
timeout=5
|
|
|
|
|
|
)
|
|
|
|
|
|
response.raise_for_status()
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"❌ 更新任务失败: {e}")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
def execute_task(self, task):
|
2026-02-15 14:29:48 +08:00
|
|
|
|
"""执行任务(示例实现)"""
|
2026-02-15 13:41:49 +08:00
|
|
|
|
print(f"🔄 正在执行任务: {task['title']}")
|
2026-02-15 14:29:48 +08:00
|
|
|
|
print(f" 描述: {task.get('description', '无')}")
|
|
|
|
|
|
print(f" 优先级: {task['priority']}")
|
|
|
|
|
|
|
|
|
|
|
|
# 模拟任务执行
|
|
|
|
|
|
time.sleep(3)
|
|
|
|
|
|
|
|
|
|
|
|
return f"任务 '{task['title']}' 已由 {self.name} 成功完成"
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
|
"""主循环"""
|
2026-02-15 14:29:48 +08:00
|
|
|
|
if not self.register():
|
|
|
|
|
|
print("❌ 无法注册智能体,退出")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
print(f"🤖 智能体 '{self.name}' 开始运行...")
|
|
|
|
|
|
print("按 Ctrl+C 退出\n")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 发送心跳
|
|
|
|
|
|
self.heartbeat("idle")
|
|
|
|
|
|
|
|
|
|
|
|
# 获取待处理任务
|
|
|
|
|
|
tasks = self.get_pending_tasks()
|
|
|
|
|
|
|
|
|
|
|
|
if tasks:
|
|
|
|
|
|
task = tasks[0]
|
2026-02-15 14:29:48 +08:00
|
|
|
|
print(f"\n📋 发现新任务: {task['title']}")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
# 领取任务
|
|
|
|
|
|
if self.claim_task(task['id']):
|
2026-02-15 14:29:48 +08:00
|
|
|
|
print("✓ 任务已领取")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
self.heartbeat("busy")
|
|
|
|
|
|
|
|
|
|
|
|
# 执行任务
|
|
|
|
|
|
result = self.execute_task(task)
|
|
|
|
|
|
|
|
|
|
|
|
# 更新任务状态
|
|
|
|
|
|
self.update_task(task['id'], "completed", result)
|
2026-02-15 14:29:48 +08:00
|
|
|
|
print(f"✅ 任务完成\n")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
self.heartbeat("idle")
|
|
|
|
|
|
|
2026-02-15 14:29:48 +08:00
|
|
|
|
# 等待一段时间再检查
|
|
|
|
|
|
time.sleep(5)
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
except KeyboardInterrupt:
|
2026-02-15 14:29:48 +08:00
|
|
|
|
print("\n\n👋 收到退出信号,智能体停止运行")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
break
|
|
|
|
|
|
except Exception as e:
|
2026-02-15 14:29:48 +08:00
|
|
|
|
print(f"❌ 运行时错误: {e}")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
time.sleep(5)
|
|
|
|
|
|
|
|
|
|
|
|
# 使用示例
|
|
|
|
|
|
if __name__ == "__main__":
|
2026-02-15 14:29:48 +08:00
|
|
|
|
agent = TaskAgent("Python智能体")
|
2026-02-15 13:41:49 +08:00
|
|
|
|
agent.run()
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### JavaScript/Node.js 客户端示例
|
|
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
|
const axios = require('axios');
|
|
|
|
|
|
|
|
|
|
|
|
class TaskAgent {
|
|
|
|
|
|
constructor(name, baseUrl = 'http://localhost:3000') {
|
|
|
|
|
|
this.name = name;
|
|
|
|
|
|
this.baseUrl = baseUrl;
|
|
|
|
|
|
this.agentId = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async register() {
|
|
|
|
|
|
const response = await axios.post(`${this.baseUrl}/api/agents/register`, {
|
|
|
|
|
|
name: this.name,
|
|
|
|
|
|
type: 'general',
|
|
|
|
|
|
capabilities: ['general_task']
|
|
|
|
|
|
});
|
|
|
|
|
|
this.agentId = response.data.id;
|
|
|
|
|
|
console.log(`✅ 智能体已注册: ${this.agentId}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async heartbeat(status = 'idle') {
|
|
|
|
|
|
await axios.post(
|
|
|
|
|
|
`${this.baseUrl}/api/agents/${this.agentId}/heartbeat`,
|
|
|
|
|
|
{ status }
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async getPendingTasks() {
|
|
|
|
|
|
const response = await axios.get(`${this.baseUrl}/api/tasks?status=pending`);
|
|
|
|
|
|
return response.data;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async claimTask(taskId) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await axios.post(`${this.baseUrl}/api/tasks/${taskId}/claim`, {
|
|
|
|
|
|
agent_id: this.agentId
|
|
|
|
|
|
});
|
|
|
|
|
|
return true;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async updateTask(taskId, status, result = null) {
|
|
|
|
|
|
const payload = { status };
|
|
|
|
|
|
if (result) payload.result = result;
|
|
|
|
|
|
await axios.put(`${this.baseUrl}/api/tasks/${taskId}`, payload);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async executeTask(task) {
|
|
|
|
|
|
console.log(`🔄 正在执行任务: ${task.title}`);
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
|
|
|
|
return `任务 '${task.title}' 已完成`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async run() {
|
|
|
|
|
|
await this.register();
|
|
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await this.heartbeat('idle');
|
|
|
|
|
|
|
|
|
|
|
|
const tasks = await this.getPendingTasks();
|
|
|
|
|
|
|
|
|
|
|
|
if (tasks.length > 0) {
|
|
|
|
|
|
const task = tasks[0];
|
|
|
|
|
|
console.log(`📋 发现任务: ${task.title}`);
|
|
|
|
|
|
|
|
|
|
|
|
if (await this.claimTask(task.id)) {
|
|
|
|
|
|
await this.heartbeat('busy');
|
|
|
|
|
|
|
|
|
|
|
|
const result = await this.executeTask(task);
|
|
|
|
|
|
|
|
|
|
|
|
await this.updateTask(task.id, 'completed', result);
|
2026-02-15 14:29:48 +08:00
|
|
|
|
console.log(`✅ 任务完成`);
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
await this.heartbeat('idle');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('❌ 错误:', error.message);
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 使用示例
|
2026-02-15 14:29:48 +08:00
|
|
|
|
const agent = new TaskAgent('JS智能体');
|
2026-02-15 13:41:49 +08:00
|
|
|
|
agent.run().catch(console.error);
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 数据库结构
|
|
|
|
|
|
|
|
|
|
|
|
### agents 表
|
2026-02-15 14:29:48 +08:00
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| id | VARCHAR(255) | 智能体唯一标识(UUID) |
|
|
|
|
|
|
| name | VARCHAR(255) | 智能体名称 |
|
|
|
|
|
|
| type | VARCHAR(100) | 智能体类型 |
|
|
|
|
|
|
| capabilities | JSONB | 能力列表(JSON) |
|
|
|
|
|
|
| status | VARCHAR(50) | 状态(idle/busy) |
|
|
|
|
|
|
| registered_at | BIGINT | 注册时间(毫秒时间戳) |
|
|
|
|
|
|
| last_heartbeat | BIGINT | 最后心跳时间(毫秒时间戳) |
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
### tasks 表
|
2026-02-15 14:29:48 +08:00
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| id | VARCHAR(255) | 任务唯一标识(UUID) |
|
|
|
|
|
|
| title | VARCHAR(500) | 任务标题 |
|
|
|
|
|
|
| description | TEXT | 任务描述 |
|
|
|
|
|
|
| priority | VARCHAR(50) | 优先级(low/normal/high) |
|
|
|
|
|
|
| status | VARCHAR(50) | 状态(pending/in_progress/completed) |
|
|
|
|
|
|
| created_by | VARCHAR(255) | 创建者 |
|
|
|
|
|
|
| assigned_to | VARCHAR(255) | 分配给的智能体 |
|
|
|
|
|
|
| created_at | BIGINT | 创建时间(毫秒时间戳) |
|
|
|
|
|
|
| updated_at | BIGINT | 更新时间(毫秒时间戳) |
|
|
|
|
|
|
| completed_at | BIGINT | 完成时间(毫秒时间戳) |
|
|
|
|
|
|
| result | TEXT | 任务结果 |
|
|
|
|
|
|
|
|
|
|
|
|
## 架构说明
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
|
|
|
|
│ 智能体 1 │ │ 智能体 2 │ │ 智能体 N │
|
|
|
|
|
|
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
|
|
|
|
|
│ │ │
|
|
|
|
|
|
│ 注册/心跳/领取 │ │
|
|
|
|
|
|
└────────────┬───────┴────────────────────┘
|
|
|
|
|
|
│
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌──────────────────────┐
|
|
|
|
|
|
│ API 服务 (Node.js) │
|
|
|
|
|
|
│ - RESTful API │
|
|
|
|
|
|
│ - 任务调度 │
|
|
|
|
|
|
│ - 状态管理 │
|
|
|
|
|
|
└──────────┬───────────┘
|
|
|
|
|
|
│
|
|
|
|
|
|
▼
|
|
|
|
|
|
┌──────────────────────┐
|
|
|
|
|
|
│ PostgreSQL 数据库 │
|
|
|
|
|
|
│ - agents 表 │
|
|
|
|
|
|
│ - tasks 表 │
|
|
|
|
|
|
└──────────────────────┘
|
|
|
|
|
|
▲
|
|
|
|
|
|
│
|
|
|
|
|
|
┌──────────┴───────────┐
|
|
|
|
|
|
│ Web 管理界面 │
|
|
|
|
|
|
│ - 实时统计 │
|
|
|
|
|
|
│ - 任务列表 │
|
|
|
|
|
|
│ - 人工创建任务 │
|
|
|
|
|
|
└──────────────────────┘
|
|
|
|
|
|
```
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
## 扩展建议
|
|
|
|
|
|
|
|
|
|
|
|
1. **认证授权** - 添加 API Key 或 JWT 认证
|
|
|
|
|
|
2. **任务队列** - 基于优先级的任务队列
|
|
|
|
|
|
3. **任务依赖** - 支持任务之间的依赖关系
|
|
|
|
|
|
4. **消息推送** - WebSocket 实时通知
|
|
|
|
|
|
5. **日志记录** - 详细的操作日志
|
|
|
|
|
|
6. **性能监控** - 任务执行时间和成功率统计
|
|
|
|
|
|
7. **分布式部署** - 支持多节点部署
|
2026-02-15 14:29:48 +08:00
|
|
|
|
8. **任务超时** - 自动检测和重新分配超时任务
|
|
|
|
|
|
|
|
|
|
|
|
## 故障排查
|
|
|
|
|
|
|
|
|
|
|
|
### 数据库连接失败
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 检查 PostgreSQL 是否运行
|
|
|
|
|
|
docker-compose ps
|
|
|
|
|
|
|
|
|
|
|
|
# 查看数据库日志
|
|
|
|
|
|
docker-compose logs postgres
|
|
|
|
|
|
|
|
|
|
|
|
# 重启服务
|
|
|
|
|
|
docker-compose restart
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 智能体注册失败
|
|
|
|
|
|
- 检查服务是否正常运行
|
|
|
|
|
|
- 确认网络连接正常
|
|
|
|
|
|
- 查看应用日志: `docker-compose logs app`
|
|
|
|
|
|
|
|
|
|
|
|
### 任务领取失败
|
|
|
|
|
|
- 确认任务状态为 `pending`
|
|
|
|
|
|
- 确认智能体 ID 正确
|
|
|
|
|
|
- 任务可能已被其他智能体领取
|
2026-02-15 13:41:49 +08:00
|
|
|
|
|
|
|
|
|
|
## 许可证
|
|
|
|
|
|
|
|
|
|
|
|
MIT
|