1. 摘要
我用 TRAE SOLO 从零搭建了一个 AI Agent 系统——Mini-OpenClaw。它不是一个简单的聊天机器人,而是一个拥有长期记忆、可扩展技能插件、5 种核心工具的智能体。最特别的是,所有记忆和技能都以 Markdown 文件存储,完全透明可控。项目已开源。
2. 背景
我是一名大学生,平时用各种 AI 助手(ChatGPT、Claude 等)的时候,一直在想一个问题:这些 AI 助手到底是怎么工作的?
它们能记住之前的对话、能调用工具查天气、能按照特定流程完成任务——这些能力背后是什么架构?我想自己从零搭一个来搞懂,顺便学习 Agent 开发的核心概念。
市面上有 OpenClaw(原名 Moltbot/Clawdbot)这类开源项目,但我想用 SOLO 自己复刻一个轻量版,搞懂每一个设计决策背后的原因,而不是直接用别人的轮子。
3. 实践过程
3.1 我是怎么拆解任务的
同样用 /plan 先拆阶段,这次拆成了 4 个核心模块:
| 阶段 | 目标 | 怎么验证 |
|---|---|---|
| ① Agent 核心 | LangChain + LangGraph 搭建 Agent 骨架 | 能接收消息并返回回复 |
| ② 记忆系统 | 文件即记忆 + System Prompt 拼接 | Agent 能记住跨会话的信息 |
| ③ 技能系统 | 技能即插件,文件夹结构管理 | Agent 能读取技能文件并执行 |
| ④ 前端 + 用户系统 | IDE 风格界面 + 登录注册 | 完整可用的 Web 应用 |
3.2 技术栈
后端 FastAPI + LangChain 1.x + LangGraph(Agent 编排)+ LlamaIndex(RAG 检索)+ PostgreSQL + Redis前端 Next.js 14 + TypeScript + Tailwind CSS + Monaco Editor
3.3 核心:Agent 的"灵魂"——记忆系统
这是整个项目最有趣的设计。我没有用向量数据库存记忆,而是采用了**“文件即记忆”**的理念——所有记忆都是 Markdown 文件,完全透明、可读、可编辑。
System Prompt 的构成(SOLO 帮我设计的拼接逻辑):
SKILLS_SNAPSHOT.md → 技能列表(Agent 知道自己能做什么)
SOUL.md → 核心设定(系统定位、设计理念)
IDENTITY.md → 自我认知(我是谁、我能做什么)
USER.md → 用户画像(了解用户偏好)
AGENTS.md → 行为准则(技能调用协议、记忆协议、决策流程)
MEMORY.md → 长期记忆(跨会话的重要信息)
SOLO 实现的 MemoryManager 会自动拼接这些文件,还做了 Token 截断保护,防止 System Prompt 超长。
为什么选文件而不是数据库?
完全透明:打开 Markdown 就能看到 AI “记住了什么”
可手动编辑:直接改文件就能调整 AI 的行为
零依赖:不需要额外的数据库服务
可版本控制:用 Git 就能追踪 AI 记忆的变化
3.4 亮点:技能即插件系统
这是借鉴了 Anthropic 的 Agent Skills 范式。每个技能就是一个文件夹,里面放一个 SKILL.md 文件描述技能的步骤和示例。
技能调用流程:
用户说"帮我查一下北京天气"
→ Agent 在 System Prompt 中看到 available_skills 列表
→ 发现 get_weather 技能匹配
→ 用 read_file 工具读取 skills/get_weather/SKILL.md
→ 按照文件中的步骤,调用 fetch_url 工具获取天气数据
→ 解析数据并返回结果
已有的 3 个技能:
| 技能 | 功能 |
|---|---|
get_weather |
查询城市实时天气 |
docker-desktop_windows_operation_guide |
Docker Desktop 常用操作指南 |
summarization_skill |
文本摘要生成 |
开发新技能超简单:在 skills/ 目录下新建文件夹,写一个 SKILL.md 就行,系统会自动加载。
3.5 5 种核心工具
Agent 不只是"会说话",它还能真正做事:
| 工具 | 能力 | 实现方式 |
|---|---|---|
terminal |
执行 Shell 命令 | LangChain ShellTool,限定沙箱目录 |
python_repl |
运行 Python 代码 | LangChain PythonREPLTool |
fetch_url |
抓取网页内容 | 自定义增强版,自动清洗 HTML 转 Markdown |
read_file |
读取本地文件 | LangChain ReadFileTool |
search_knowledge_base |
RAG 知识检索 | LlamaIndex 向量索引 |
其中 fetch_url 是 SOLO 帮我做了增强的——原始版本只返回 HTML 源码,我让 SOLO 加了 BeautifulSoup 清洗 + html2text 转 Markdown,这样 Agent 拿到的就是干净的文本内容。
3.6 前端:IDE 风格三栏布局
前端我用了 Next.js + Monaco Editor,做成了一个类似 IDE 的界面:
- 左侧:导航栏 + 会话列表(Chat / Memory / Skills 三个视图)
- 中间:对话流 + Agent 思考链可视化(能看到它在调用什么工具)
- 右侧:Monaco Editor,实时查看/编辑正在使用的 SKILL.md 或 MEMORY.md
这个三栏设计是我自己画的草图,然后让 SOLO 用 Next.js + Tailwind 实现的。
3.7 从 v1 到 v2 的迭代
项目经历了两个版本的迭代,这也是用 SOLO 做项目的真实过程:
v1(基础版):
- 简单的 FastAPI + LangChain Agent
- 会话存 JSON 文件
- 没有用户系统
v2(完整版):
- 引入 LangGraph 做 Agent 编排,支持流式输出(SSE)
- 会话改用 PostgreSQL 持久化存储
- 加入 Redis 做用户 Token 缓存
- 完整的用户注册/登录/修改密码系统
- 认证中间件 + 白名单机制
经验:先跑通最小可用版本,再逐步迭代加功能。v1 能对话就够了,v2 再考虑持久化和用户系统
3.8 踩过的坑
| 坑 | 解决方式 |
|---|---|
| LangChain 消息序列化失败 | BaseMessage 对象不能直接 JSON 序列化,SOLO 帮我写了 message_to_dict 转换函数 |
| SSE 流式输出格式对不上 | 前端期望的数据格式和后端推送的不一致,联调时逐字段对齐 |
| System Prompt 过长导致 Token 超限 | SOLO 在 MemoryManager 里加了 tiktoken 截断保护 |
| 技能文件路径解析错误 | Agent 读取技能时路径不对,排查后发现是相对路径基准目录的问题 |
| PostgreSQL 连接池配置 | 异步连接池的 autocommit 和 prepare_threshold 参数需要特殊设置 |
4. 成果展示
GitHub 开源:GitHub - jerry-166/mini-openclew: 实现skill和本地session及数据库存储 · GitHub
核心功能一览
| 功能 | 说明 |
|---|---|
| AI Agent 对话 | 基于 LangGraph 编排,支持流式输出,实时展示思考链 |
| 文件即记忆 | 所有记忆以 Markdown 文件存储,完全透明可控 |
| 技能即插件 | 文件夹结构管理技能,新增技能只需写一个 SKILL.md |
| 5 种核心工具 | 终端、Python、网页抓取、文件读取、RAG 检索 |
| IDE 风格前端 | 三栏布局 + Monaco Editor,可实时编辑记忆和技能 |
| 多用户系统 | 注册/登录/会话管理,PostgreSQL + Redis |
5. 效果与总结
提效数据
| 对比项 | 传统方式 | 用 SOLO 后 |
|---|---|---|
| 项目搭建周期 | 2-3 周 | 4-5 天(含 v1→v2 迭代) |
| 核心模块 | — | Agent 核心 + 记忆系统 + 技能系统 + 用户系统 |
| 技能扩展 | — | 新增技能只需 1 个 Markdown 文件 |
SOLO 在流程中做了什么
SOLO 参与了整个项目生命周期:架构设计 → Agent 核心搭建 → 记忆系统设计 → 技能系统实现 → 工具增强 → 前端开发 → v1→v2 迭代 → 用户系统 → 联调修复。
特别值得一提的是,SOLO 不只是帮我写代码,还帮我理解了 Agent 开发的核心概念——比如 System Prompt 拼接策略、工具调用的编排方式、记忆管理的不同方案等。
几条可复用的经验
- 先理解原理,再动手实现 — 在搭 Agent 之前,先让 SOLO 解释清楚 LangChain 和 LangGraph 的区别、Agent 的执行流程,这样写代码时心里有数
- v1 能跑就行,别追求完美 — 我的 v1 连数据库都没有,但能对话就够了。v2 再加 PostgreSQL、Redis、用户系统
- 联调时注意数据格式对齐 — 后端返回的
BaseMessage对象和前端期望的 JSON 格式完全不同,需要写转换函数
项目地址:GitHub - jerry-166/mini-openclew: 实现skill和本地session及数据库存储 · GitHub 欢迎大家 Star
交流讨论!


