10 KiB
10 KiB
title, source, author, published, created, description, tags
| title | source | author | published | created | description | tags |
|---|---|---|---|---|---|---|
| AgentBase 项目设计文档 | shenwei |
AgentBase 项目设计文档
设计日期:2026-04-05 状态:已确认,等待实施 项目位置:
~/Workspace/agentbase/
1. 项目概述
项目名:agentbase 项目类型:Django Web 应用 + 数据归档系统 核心目标:遍历 OpenClaw Agent 的 session JSONL 文件,解析并保存到 MariaDB,通过 Django Admin 提供 Web 查询界面。
使用场景:
- 查找某个 Agent 在某天的所有对话记录
- 查找某个 Agent 在处理任务时调用了哪些工具(特别是
exec命令的具体内容) - 查看 Agent 的思考过程(thinking block)
- 增量解析,只解析未处理过的文件
2. 数据库设计
2.1 服务器与 Agent 映射
| 服务器 | 标识 | Session 根目录 |
|---|---|---|
| Mac Mini | macmini |
/Users/weishen/.openclaw/agents/ |
| Ubuntu1 | ubuntu1 |
/home/shenwei/.openclaw/agents/ |
| Ubuntu2 | ubuntu2 |
/home/shenwei/.openclaw/agents/ |
纳入的 Agent:main、xingyao、xinghui、xingjiang、opencode、sisyphus
2.2 Session 文件类型
所有 .jsonl 文件均需解析,包括:
*.jsonl— 正常 session*.jsonl.reset.*— reset 快照*.jsonl.deleted.*— 删除快照*-topic-*.jsonl— 线程 session
session_type 判定:
- 文件名含
.reset.→reset - 文件名含
.deleted.→deleted - 文件名含
-topic-→topic - 默认 →
normal
忽略文件:sessions.json(索引文件,不解析)
2.3 数据库 Schema
表:parsed_files(增量解析控制)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
INT AUTO_INCREMENT | 主键 |
server |
VARCHAR(32) | 服务器标识 |
agent_id |
VARCHAR(64) | Agent ID |
file_path |
VARCHAR(512) | 文件绝对路径 |
file_mtime |
BIGINT | 文件最后修改时间(Unix timestamp) |
file_size |
BIGINT | 文件大小(字节) |
status |
VARCHAR(16) | pending / success / failed |
parsed_at |
DATETIME | 本次解析时间 |
error_message |
TEXT | 失败时的错误信息(可空) |
UNIQUE 约束:UNIQUE(server, agent_id, file_path)
增量解析逻辑:
-- 插入前检查:同一文件 + 同一修改时间是否已解析
WHERE NOT EXISTS (
SELECT 1 FROM parsed_files
WHERE server=? AND agent_id=? AND file_path=?
AND file_mtime=? AND file_size=? AND status='success'
)
表:sessions(Session 根记录)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
INT AUTO_INCREMENT | 主键 |
server |
VARCHAR(32) | 服务器标识 |
agent_id |
VARCHAR(64) | Agent ID |
session_uuid |
VARCHAR(64) | Session UUID(文件名去掉.jsonl等后缀) |
file_path |
VARCHAR(512) | 来源文件路径 |
session_type |
VARCHAR(32) | normal / topic / reset / deleted |
cwd |
VARCHAR(512) | Session 工作目录 |
started_at |
DATETIME(3) | Session 开始时间 |
first_message_at |
DATETIME(3) | 第一条 message 的时间 |
last_message_at |
DATETIME(3) | 最后一条 message 的时间 |
message_count |
INT | 该 session 的消息总数 |
created_at |
DATETIME | 记录创建时间 |
UNIQUE 约束:UNIQUE(session_uuid, server, agent_id)
表:messages(消息内容)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
INT AUTO_INCREMENT | 主键 |
session_id |
INT | 外键 → sessions.id |
server |
VARCHAR(32) | 服务器标识 |
agent_id |
VARCHAR(64) | Agent ID |
session_uuid |
VARCHAR(64) | Session UUID(冗余存储,方便查询) |
message_uuid |
VARCHAR(64) | 消息 UUID |
parent_message_uuid |
VARCHAR(64) | 父消息 UUID(可空) |
role |
VARCHAR(32) | user / assistant / toolResult |
content_blocks |
JSON | 原文:原始 content 数组 |
text_preview |
VARCHAR(512) | 纯文本摘要(前512字符) |
first_tool_call |
VARCHAR(128) | 首个 toolCall name |
tool_call_count |
INT | toolCall 总数 |
tool_calls_json |
JSON | 拆出:所有 toolCall block |
thinking_text |
TEXT | 拆出:首个 thinking block |
has_thinking |
TINYINT | 是否有 thinking(0/1) |
has_tool_calls |
TINYINT | 是否有 toolCall(0/1) |
is_error |
TINYINT | 整条 isError 标记 |
provider |
VARCHAR(64) | AI Provider(如 minimax) |
model |
VARCHAR(128) | 模型 ID(如 MiniMax-M2.7) |
api |
VARCHAR(64) | API 类型(如 anthropic-messages) |
stop_reason |
VARCHAR(64) | stopReason 字段值 |
input_tokens |
INT | 输入 token 数 |
output_tokens |
INT | 输出 token 数 |
cache_read_tokens |
BIGINT | Cache Read token 数 |
cache_write_tokens |
BIGINT | Cache Write token 数 |
total_tokens |
INT | 总 token 数 |
cost_usd |
DECIMAL(12,8) | 该消息美元成本 |
timestamp |
DATETIME(3) | 消息时间 |
created_at |
DATETIME | 记录创建时间 |
Indexes:
idx_agent_timestampON(agent_id, timestamp)idx_first_tool_callON(first_tool_call)idx_session_idON(session_id)idx_roleON(role)
2.4 Content Block 结构
JSONL 中每条 type:message 的 content 数组,成员类型如下:
| content block type | 关键提取字段 |
|---|---|
text |
text(纯文本) |
thinking |
thinking、thinkingSignature |
toolCall |
id、name、arguments(JSON 对象) |
toolResult |
toolCallId、toolName、content、isError、details |
text_preview 提取规则(按优先级):
- 找第一个
type=="text"的text字段 - 找不到则找
type=="thinking"的thinking字段 - 再找不到则找
type=="toolResult"里第一个子type=="text"的内容 - 截取前512字符,strip HTML
3. Django 项目结构
~/Workspace/agentbase/ # Git 仓库根目录
├── manage.py
├── agentbase/ # Django 项目
│ ├── __init__.py
│ ├── settings.py # 数据库配置在此
│ ├── urls.py
│ └── wsgi.py
├── messages/ # Django App
│ ├── __init__.py
│ ├── models.py # ParsedFile / Session / Message
│ ├── admin.py # Django Admin 配置
│ ├── views.py # Web 查询视图
│ ├── urls.py
│ ├── management/
│ │ └── commands/
│ │ └── parse_sessions.py # Django command
│ └── templates/
│ └── messages/
│ └── message_list.html
├── scripts/
│ └── parse_and_import.py # OpenClaw cron 调用的入口脚本
├── tests/
├── requirements.txt
└── README.md
3.1 配置方式
数据库连接信息直接写在 settings.py 中(不使用 config.yaml)。
3.2 Django Admin 预期界面
Messages(核心):
- 列表页支持按
agent_id+timestamp范围 +role+first_tool_call过滤 - 详情页展示
content_blocks原始 JSON、thinking_text、tool_calls_json - 适合查找"某 Agent 某天所有对话和思考记录"
Sessions:列出所有 session,按 server/agent_id 过滤。
ParsedFiles:记录已解析文件列表,支持按 server/agent_id/file_path 搜索。
4. 解析脚本设计
4.1 入口脚本
scripts/parse_and_import.py
- OpenClaw cron 任务调用此脚本
- 也可单独运行:
python parse_and_import.py --server macmini --agent xingyao - 内部加载 Django settings,调用 Django ORM 写入数据库
4.2 解析流程
- 遍历服务器和 Agent:macmini/ubuntu1/ubuntu2 → 各 Agent 目录
- 扫描 session 文件:列出所有
.jsonl文件,跳过sessions.json - 增量检查:查
parsed_files表,文件 mtime+size 未变且 status=success → 跳过 - 解析 JSONL:逐行读取,提取
type:session和type:message记录 - 写入数据库:先插入
sessions,再批量插入messages - 更新
parsed_files:status=success 或 status=failed + error_message
4.3 OpenClaw Cron 任务
每日 00:05 执行(00:00 照片整理完成后错开):
python ~/Workspace/agentbase/scripts/parse_and_import.py
- 在 Mac Mini 上执行
- 通过 SSH 访问 ubuntu1/2 的 session 目录
- 所有 Agent 的当日新 session 均被解析
5. 典型查询示例
5.1 查某 Agent 某天的所有消息
SELECT id, message_uuid, role, text_preview, has_thinking, first_tool_call, timestamp
FROM messages
WHERE agent_id = 'xingyao'
AND timestamp BETWEEN '2026-04-05 00:00:00' AND '2026-04-05 23:59:59'
ORDER BY timestamp;
5.2 查某 Agent 某天调用过的所有 exec 命令
SELECT m.id, m.timestamp, m.text_preview, m.session_uuid
FROM messages m
WHERE m.agent_id = 'xingyao'
AND m.timestamp BETWEEN '2026-04-05 00:00:00' AND '2026-04-05 23:59:59'
AND m.first_tool_call = 'exec';
5.3 查包含 thinking 的消息
SELECT id, message_uuid, role, thinking_text, timestamp
FROM messages
WHERE agent_id = 'xingyao'
AND has_thinking = 1
AND timestamp BETWEEN '2026-04-05 00:00:00' AND '2026-04-05 23:59:59';
6. 待确认事项
- 数据库类型:MariaDB?SQLite(开发测试用)?
- 数据库名称
- MariaDB 部署在哪里?(Mac Mini 本地?NAS?独立服务器?)
7. 后续步骤
- 用户确认以上设计
- 创建 Git 仓库
~/Workspace/agentbase/ - 初始化 Django 项目
- 编写
settings.py(含数据库配置) - 编写
messages/models.py(三张表) - 编写
messages/admin.py(Admin 配置) - 编写
scripts/parse_and_import.py(解析入口) - 编写
messages/management/commands/parse_sessions.py(Django command) - 配置 Django Admin 模板(message_list.html)
- 创建 OpenClaw cron 任务