升级到 PostgreSQL 并添加 Docker Compose 部署

主要更新:
- 替换 SQLite 为 PostgreSQL 数据库
- 添加 Docker Compose 配置文件
- 添加 Dockerfile 支持容器化部署
- 更新 README 添加详细的智能体注册指南
- 添加 .env.example 环境变量模板
- 修复 uuid 模块兼容性问题(降级到 9.x)
- 完善 API 文档和使用示例
This commit is contained in:
work-1
2026-02-15 14:29:48 +08:00
parent da6ff6a51b
commit 7fd9eb0b21
8 changed files with 953 additions and 85 deletions
+329 -72
View File
@@ -10,21 +10,163 @@
-**状态实时更新** - 跟踪任务和智能体的状态变化
-**Web 管理界面** - 可视化查看和管理任务
-**RESTful API** - 完整的 HTTP API 接口
-**PostgreSQL 存储** - 稳定可靠的关系型数据库
-**Docker 部署** - 一键启动完整环境
## 快速开始
## 快速开始Docker Compose
### 前置要求
- Docker
- Docker Compose
### 1. 启动服务
```bash
cd /data/openclaw/workspace/agent-task-service
node server.js
docker-compose up -d
```
服务将在 `http://localhost:3000` 启动
服务将在以下地址启动
- **Web 界面**: http://localhost:3000
- **API 接口**: http://localhost:3000/api
- **PostgreSQL**: localhost:5432
### 2. 访问 Web 界面
### 2. 查看日志
在浏览器中打开: `http://localhost:3000`
```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": "任务执行结果描述"
}'
```
## API 文档
@@ -36,9 +178,9 @@ POST /api/agents/register
Content-Type: application/json
{
"name": "",
"type": "general", // : general, search, coding, etc.
"capabilities": ["", "", ""] //
"name": "", //
"type": "general", // : general, search, coding, etc.
"capabilities": ["", ""] // :
}
:
@@ -87,10 +229,10 @@ POST /api/tasks
Content-Type: application/json
{
"title": "",
"description": "",
"priority": "normal", // low | normal | high
"created_by": "human" // human | agent_id
"title": "", //
"description": "", //
"priority": "normal", // : low | normal | high
"created_by": "human" // : human | agent_id
}
:
@@ -129,7 +271,7 @@ POST /api/tasks/:id/claim
Content-Type: application/json
{
"agent_id": "ID"
"agent_id": "ID" //
}
:
@@ -144,8 +286,8 @@ PUT /api/tasks/:id
Content-Type: application/json
{
"status": "completed", // pending | in_progress | completed
"result": "" //
"status": "completed", // : pending | in_progress | completed
"result": "" //
}
:
@@ -189,14 +331,24 @@ GET /api/stats
}
```
#### 健康检查
```http
GET /health
:
{
"status": "healthy",
"database": "connected"
}
```
## 智能体集成示例
### Python 客户端示例
### Python 客户端完整示例
```python
import requests
import time
import uuid
class TaskAgent:
def __init__(self, name, base_url="http://localhost:3000"):
@@ -206,51 +358,93 @@ class TaskAgent:
def register(self):
"""注册智能体"""
response = requests.post(f"{self.base_url}/api/agents/register", json={
"name": self.name,
"type": "general",
"capabilities": ["general_task"]
})
data = response.json()
self.agent_id = data["id"]
print(f"✅ 智能体已注册: {self.agent_id}")
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
def heartbeat(self, status="idle"):
"""发送心跳"""
requests.post(
f"{self.base_url}/api/agents/{self.agent_id}/heartbeat",
json={"status": status}
)
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}")
def get_pending_tasks(self):
"""获取待处理任务"""
response = requests.get(f"{self.base_url}/api/tasks?status=pending")
return response.json()
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 []
def claim_task(self, task_id):
"""领取任务"""
response = requests.post(
f"{self.base_url}/api/tasks/{task_id}/claim",
json={"agent_id": self.agent_id}
)
return response.ok
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
def update_task(self, task_id, status, result=None):
"""更新任务状态"""
payload = {"status": status}
if result:
payload["result"] = result
requests.put(f"{self.base_url}/api/tasks/{task_id}", json=payload)
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}")
def execute_task(self, task):
"""执行任务(示例)"""
"""执行任务(示例实现"""
print(f"🔄 正在执行任务: {task['title']}")
time.sleep(2) # 模拟任务执行
return f"任务 '{task['title']}' 已完成"
print(f" 描述: {task.get('description', '')}")
print(f" 优先级: {task['priority']}")
# 模拟任务执行
time.sleep(3)
return f"任务 '{task['title']}' 已由 {self.name} 成功完成"
def run(self):
"""主循环"""
self.register()
if not self.register():
print("❌ 无法注册智能体,退出")
return
print(f"🤖 智能体 '{self.name}' 开始运行...")
print("按 Ctrl+C 退出\n")
while True:
try:
@@ -262,10 +456,11 @@ class TaskAgent:
if tasks:
task = tasks[0]
print(f"📋 发现任务: {task['title']}")
print(f"\n📋 发现任务: {task['title']}")
# 领取任务
if self.claim_task(task['id']):
print("✓ 任务已领取")
self.heartbeat("busy")
# 执行任务
@@ -273,22 +468,23 @@ class TaskAgent:
# 更新任务状态
self.update_task(task['id'], "completed", result)
print(f"✅ 任务完成: {task['id']}")
print(f"✅ 任务完成\n")
self.heartbeat("idle")
time.sleep(5) # 每5秒检查一次
# 等待一段时间再检查
time.sleep(5)
except KeyboardInterrupt:
print("👋 智能体退出")
print("\n\n👋 收到退出信号,智能体停止运行")
break
except Exception as e:
print(f"❌ 错误: {e}")
print(f"运行时错误: {e}")
time.sleep(5)
# 使用示例
if __name__ == "__main__":
agent = TaskAgent("示例智能体")
agent = TaskAgent("Python智能体")
agent.run()
```
@@ -368,7 +564,7 @@ class TaskAgent {
const result = await this.executeTask(task);
await this.updateTask(task.id, 'completed', result);
console.log(`✅ 任务完成: ${task.id}`);
console.log(`✅ 任务完成`);
await this.heartbeat('idle');
}
@@ -384,35 +580,71 @@ class TaskAgent {
}
// 使用示例
const agent = new TaskAgent('示例智能体');
const agent = new TaskAgent('JS智能体');
agent.run().catch(console.error);
```
## 数据库结构
系统使用 SQLite 数据库,包含以下表:
### agents 表
- `id` - 智能体唯一标识
- `name` - 智能体名称
- `type` - 智能体类型
- `capabilities` - 能力列表(JSON
- `status` - 状态(idle/busy
- `registered_at` - 注册时间
- `last_heartbeat` - 最后心跳时间
| 字段 | 类型 | 说明 |
|------|------|------|
| id | VARCHAR(255) | 智能体唯一标识(UUID |
| name | VARCHAR(255) | 智能体名称 |
| type | VARCHAR(100) | 智能体类型 |
| capabilities | JSONB | 能力列表(JSON |
| status | VARCHAR(50) | 状态(idle/busy |
| registered_at | BIGINT | 注册时间(毫秒时间戳) |
| last_heartbeat | BIGINT | 最后心跳时间(毫秒时间戳) |
### tasks 表
- `id` - 任务唯一标识
- `title` - 任务标题
- `description` - 任务描述
- `priority` - 优先级(low/normal/high
- `status` - 状态(pending/in_progress/completed
- `created_by` - 创建者
- `assigned_to` - 分配给的智能体
- `created_at` - 创建时间
- `updated_at` - 更新时间
- `completed_at` - 完成时间
- `result` - 任务结果
| 字段 | 类型 | 说明 |
|------|------|------|
| 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 管理界面 │
│ - 实时统计 │
│ - 任务列表 │
│ - 人工创建任务 │
└──────────────────────┘
```
## 扩展建议
@@ -423,6 +655,31 @@ agent.run().catch(console.error);
5. **日志记录** - 详细的操作日志
6. **性能监控** - 任务执行时间和成功率统计
7. **分布式部署** - 支持多节点部署
8. **任务超时** - 自动检测和重新分配超时任务
## 故障排查
### 数据库连接失败
```bash
# 检查 PostgreSQL 是否运行
docker-compose ps
# 查看数据库日志
docker-compose logs postgres
# 重启服务
docker-compose restart
```
### 智能体注册失败
- 检查服务是否正常运行
- 确认网络连接正常
- 查看应用日志: `docker-compose logs app`
### 任务领取失败
- 确认任务状态为 `pending`
- 确认智能体 ID 正确
- 任务可能已被其他智能体领取
## 许可证