按 docs/v2/05-implementation-plan.md §1 候选迁移表与 claude_use/T00 白名单, 从 55e2cdb 抽取 224 个文件(2.48 MB)到独立目录 F:/mini-OpenClaw-v2。 - 排除:凭据(.env/server-deploy.conf/旧DELIVERY.md)、运行数据(xingbang_data 等 4 个 SQLite)、依赖(venv/node_modules 符号链接)、归档(_backup*/test-evidence/ ori_file)、Office 临时文件 - 目标目录独立 git 仓库,初始恢复点;Gitea 远程与分支待 OQ-06 Q2 定案 - 未部署、未启动服务、未调用模型 Co-Authored-By: Claude Code <noreply@anthropic.com>
324 lines
11 KiB
Markdown
324 lines
11 KiB
Markdown
# mini-OpenClaw 架构说明
|
|
|
|
## 系统架构图
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ 用户界面 │
|
|
│ (Next.js Frontend) │
|
|
│ http://localhost:3000 │
|
|
└───────────────────────┬─────────────────────────────────────┘
|
|
│ HTTP/SSE
|
|
│
|
|
┌───────────────────────▼─────────────────────────────────────┐
|
|
│ FastAPI Backend │
|
|
│ http://localhost:8002 │
|
|
│ ┌──────────────────────────────────────────────────────┐ │
|
|
│ │ API Routes (/api) │ │
|
|
│ │ • /chat - 流式聊天 (SSE) │ │
|
|
│ │ • /sessions - 会话管理 │ │
|
|
│ │ • /files - 文件操作 │ │
|
|
│ │ • /config - 配置管理 │ │
|
|
│ └───────────────────┬──────────────────────────────────┘ │
|
|
│ │ │
|
|
│ ┌───────────────────▼──────────────────────────────────┐ │
|
|
│ │ Agent Manager (LangChain) │ │
|
|
│ │ • build_system_prompt() - 构建系统提示 │ │
|
|
│ │ • astream() - 流式生成 │ │
|
|
│ │ • tool_invocation - 工具调用 │ │
|
|
│ └───────┬──────────────────────────────┬───────────────┘ │
|
|
│ │ │ │
|
|
│ ┌───────▼─────────┐ ┌──────▼──────────┐ │
|
|
│ │ Core Tools │ │ Session Mgr │ │
|
|
│ │ • terminal │ │ • history │ │
|
|
│ │ • python_repl │ │ • persistence │ │
|
|
│ │ • fetch_url │ │ • title_gen │ │
|
|
│ │ • read_file │ └─────────────────┘ │
|
|
│ │ • search_kb │ │
|
|
│ └─────────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────┐ │
|
|
│ │ Knowledge Base (RAG) │ │
|
|
│ │ • LlamaIndex Indexer │ │
|
|
│ │ • BM25 + Embedding Retrieval │ │
|
|
│ │ • memory/ 目录索引 │ │
|
|
│ └──────────────────────────────────────────────────────┘ │
|
|
└───────────────────────────────────────────────────────────────┘
|
|
│
|
|
│ API Calls
|
|
│
|
|
┌───────────────────────▼─────────────────────────────────────┐
|
|
│ DeepSeek Gateway │
|
|
│ http://49.232.133.151/v1 │
|
|
│ (deepseek-v4-flash) │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## 核心流程
|
|
|
|
### 1. 聊天流程
|
|
|
|
```
|
|
用户输入 → Frontend
|
|
↓
|
|
POST /api/chat (SSE stream)
|
|
↓
|
|
Agent Manager
|
|
↓
|
|
┌─ build_system_prompt()
|
|
│ ├─ 读取 IDENTITY.md
|
|
│ ├─ 读取 AGENTS.md
|
|
│ ├─ 加载 SKILLS_SNAPSHOT
|
|
│ └─ (可选) RAG 检索 MEMORY
|
|
│
|
|
┌─ astream(message, history)
|
|
│ ├─ 构建 LangChain messages
|
|
│ ├─ 调用 DeepSeek API
|
|
│ ├─ 流式返回 tokens
|
|
│ └─ 自动工具调用
|
|
│
|
|
↓ SSE events
|
|
├─ {"type": "token", "content": "..."}
|
|
├─ {"type": "tool_start", "tool": "...", "input": "..."}
|
|
├─ {"type": "tool_result", "output": "..."}
|
|
└─ {"type": "done"}
|
|
↓
|
|
Frontend 实时渲染
|
|
```
|
|
|
|
### 2. 技能调用流程
|
|
|
|
```
|
|
用户: "查询北京天气"
|
|
↓
|
|
Agent 识别意图 → 需要 get_weather 技能
|
|
↓
|
|
Agent 调用 read_file("skills/get_weather/SKILL.md")
|
|
↓
|
|
读取技能定义:
|
|
name: get_weather
|
|
description: 获取指定城市的实时天气信息
|
|
步骤:
|
|
1. 提取城市名称
|
|
2. fetch_url("https://wttr.in/{城市}?format=j1")
|
|
3. 解析 JSON
|
|
4. 自然语言汇报
|
|
↓
|
|
Agent 按步骤执行:
|
|
├─ 提取: 北京 (Beijing)
|
|
├─ 调用 fetch_url("https://wttr.in/Beijing?format=j1")
|
|
├─ 解析天气数据
|
|
└─ 回复: "北京当前天气:晴,温度 25°C..."
|
|
↓
|
|
用户收到回复
|
|
```
|
|
|
|
### 3. 记忆系统
|
|
|
|
#### 短期记忆 (Session)
|
|
- 存储位置: `backend/sessions/{session_id}.json`
|
|
- 内容: 对话历史 (role: user/assistant, content: 消息内容)
|
|
- 生命周期: 会话期间持久化
|
|
|
|
#### 长期记忆 (MEMORY.md)
|
|
- 存储位置: `backend/memory/MEMORY.md`
|
|
- 内容: 跨会话的重要信息(用户偏好、重要决策)
|
|
- 更新方式: Agent 使用 terminal 工具追加内容
|
|
|
|
#### RAG 检索记忆
|
|
- 索引位置: `backend/knowledge/.index/`
|
|
- 检索方式: BM25 + Embedding 混合检索
|
|
- 触发条件: config.json 中 `rag_mode: true`
|
|
|
|
## 关键组件说明
|
|
|
|
### AgentManager (backend/graph/agent.py)
|
|
|
|
```python
|
|
class AgentManager:
|
|
def initialize(base_dir):
|
|
# 初始化 LLM (DeepSeek)
|
|
# 加载工具
|
|
# 初始化会话管理器
|
|
|
|
def _build_agent():
|
|
# 构建系统提示
|
|
# 创建 LangChain Agent
|
|
|
|
async def astream(message, history):
|
|
# 流式生成响应
|
|
# 处理工具调用
|
|
# 返回 SSE 事件
|
|
```
|
|
|
|
### PromptBuilder (backend/graph/prompt_builder.py)
|
|
|
|
```python
|
|
def build_system_prompt(base_dir, rag_mode):
|
|
# 读取 IDENTITY.md
|
|
# 读取 AGENTS.md
|
|
# 构建 SKILLS_SNAPSHOT
|
|
# (可选) RAG 检索相关记忆
|
|
# 组装完整系统提示
|
|
```
|
|
|
|
### SessionManager (backend/graph/session_manager.py)
|
|
|
|
```python
|
|
class SessionManager:
|
|
def load_session(session_id):
|
|
# 加载会话历史
|
|
|
|
def save_session(session_id, messages):
|
|
# 保存会话到 JSON
|
|
|
|
def update_title(session_id, title):
|
|
# 更新会话标题
|
|
```
|
|
|
|
### Tools (backend/tools/)
|
|
|
|
每个工具都是一个 LangChain Tool:
|
|
|
|
```python
|
|
from langchain_core.tools import tool
|
|
|
|
@tool
|
|
def terminal(command: str) -> str:
|
|
"""执行 Shell 命令"""
|
|
# 实现...
|
|
|
|
@tool
|
|
def python_repl(code: str) -> str:
|
|
"""运行 Python 代码"""
|
|
# 实现...
|
|
|
|
# 等等...
|
|
```
|
|
|
|
## 前端架构
|
|
|
|
### 组件树
|
|
|
|
```
|
|
App (src/app/page.tsx)
|
|
└── ChatInterface (src/components/chat/)
|
|
├── Sidebar
|
|
│ ├── SessionList
|
|
│ └── NewSessionButton
|
|
│
|
|
└── ChatArea
|
|
├── MessageList
|
|
│ └── Message[]
|
|
│ ├── UserMessage
|
|
│ ├── AssistantMessage
|
|
│ └── ToolCallDisplay
|
|
│
|
|
└── InputBox
|
|
├── TextArea
|
|
└── SendButton
|
|
```
|
|
|
|
### 状态管理 (src/lib/store.tsx)
|
|
|
|
```typescript
|
|
interface ChatState {
|
|
sessions: Session[]
|
|
currentSessionId: string
|
|
messages: Message[]
|
|
isStreaming: boolean
|
|
}
|
|
|
|
// 全局状态通过 Context API 管理
|
|
```
|
|
|
|
### API 客户端 (src/lib/api.ts)
|
|
|
|
```typescript
|
|
// SSE 流式聊天
|
|
async function* streamChat(message, sessionId)
|
|
|
|
// 会话管理
|
|
async function listSessions()
|
|
async function createSession()
|
|
async function deleteSession(id)
|
|
|
|
// 文件操作
|
|
async function readFile(path)
|
|
async function saveFile(path, content)
|
|
```
|
|
|
|
## 配置系统
|
|
|
|
### 后端配置 (.env)
|
|
|
|
```env
|
|
# LLM
|
|
DEEPSEEK_API_KEY=...
|
|
DEEPSEEK_BASE_URL=http://49.232.133.151/v1
|
|
DEEPSEEK_MODEL=deepseek-v4-flash
|
|
|
|
# Embedding
|
|
EMBEDDING_MODEL=text-embedding-3-small
|
|
|
|
# Server
|
|
PORT=8002
|
|
```
|
|
|
|
### 运行时配置 (config.json)
|
|
|
|
```json
|
|
{
|
|
"rag_mode": false
|
|
}
|
|
```
|
|
|
|
可通过 API 动态修改:
|
|
|
|
```bash
|
|
PUT /api/config/rag-mode
|
|
{"enabled": true}
|
|
```
|
|
|
|
## 扩展性设计
|
|
|
|
### 添加新工具
|
|
|
|
1. 在 `backend/tools/` 创建新文件
|
|
2. 实现 `@tool` 装饰的函数
|
|
3. 在 `tools/__init__.py` 注册
|
|
|
|
### 添加新技能
|
|
|
|
1. 在 `backend/skills/` 创建目录
|
|
2. 添加 `SKILL.md` (frontmatter + 步骤)
|
|
3. 重启后端自动加载
|
|
|
|
### 添加新 API 端点
|
|
|
|
1. 在 `backend/api/` 创建新路由文件
|
|
2. 在 `app.py` 中注册路由
|
|
3. 前端 `src/lib/api.ts` 添加客户端函数
|
|
|
|
## 安全考虑
|
|
|
|
- **工具沙箱**: `terminal` 和 `read_file` 限制在 `base_dir` 内
|
|
- **会话隔离**: 每个 session_id 独立存储
|
|
- **API 密钥**: 通过 .env 管理,不提交到 Git (.gitignore)
|
|
- **CORS**: 开发模式允许所有来源,生产环境需配置白名单
|
|
|
|
## 性能优化
|
|
|
|
- **流式响应**: SSE 降低首字延迟
|
|
- **会话缓存**: 内存中缓存活跃会话
|
|
- **RAG 索引**: 预构建知识库索引
|
|
- **前端**: Next.js App Router + React 18 Streaming
|
|
|
|
## 参考资料
|
|
|
|
- OpenClaw: 架构理念和配置组织方式
|
|
- LangChain: Agent 框架和工具系统
|
|
- LlamaIndex: RAG 检索和索引
|
|
- FastAPI: 高性能异步 Web 框架
|
|
- Next.js: React 全栈框架
|