chore: initialize qiming workspace repository
This commit is contained in:
@@ -0,0 +1,684 @@
|
||||
---
|
||||
version: 1.0
|
||||
last-updated: 2026-02-24
|
||||
status: design
|
||||
---
|
||||
|
||||
# Agent 自我进化架构 - 存储实现
|
||||
|
||||
## 概述
|
||||
|
||||
本文档详细描述 Qiming Agent 记忆存储的实现方案,基于 Markdown 文件格式,提供人类可读、Git 友好、简单可靠的存储机制。
|
||||
|
||||
---
|
||||
|
||||
## 设计原则
|
||||
|
||||
参考 OpenClaw 的 Markdown 存储方案,核心优势:
|
||||
|
||||
1. **人类可读** - 直接编辑,无需工具
|
||||
2. **Git 友好** - 版本控制天然支持
|
||||
3. **渐进加载** - Frontmatter → Body → References
|
||||
4. **简单可靠** - 无需数据库,文件系统即存储
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
~/.qimingclaw/
|
||||
├── soul/ # Agent 自我认知
|
||||
│ ├── soul.md # 主灵魂文件
|
||||
│ ├── principles.md # 学习到的原则
|
||||
│ └── anti-patterns.md # 避免的陷阱
|
||||
│
|
||||
├── memory/ # 记忆存储
|
||||
│ ├── short-term.md # 当前会话记忆(每次会话覆盖)
|
||||
│ ├── successes/ # 成功经验
|
||||
│ │ ├── 2024-02-24-parse-json.md
|
||||
│ │ ├── 2024-02-24-install-tool.md
|
||||
│ │ └── ...
|
||||
│ ├── failures/ # 失败教训
|
||||
│ │ ├── 2024-02-23-pip-failed.md
|
||||
│ │ └── ...
|
||||
│ ├── insights/ # 洞察
|
||||
│ │ ├── pattern-uv-better.md
|
||||
│ │ └── ...
|
||||
│ └── index.json # 检索索引
|
||||
│
|
||||
├── skills/ # 技能库
|
||||
│ ├── core/ # 核心技能(内置)
|
||||
│ │ ├── file-read/SKILL.md
|
||||
│ │ ├── file-write/SKILL.md
|
||||
│ │ └── ...
|
||||
│ └── learned/ # 学到的技能
|
||||
│ ├── parse-json/SKILL.md
|
||||
│ ├── install-uv/SKILL.md
|
||||
│ └── ...
|
||||
│
|
||||
└── evo-map/ # 进化图谱
|
||||
├── decisions/ # 决策树
|
||||
│ ├── install-python.md
|
||||
│ ├── parse-json.md
|
||||
│ └── ...
|
||||
└── patterns/ # 模式库
|
||||
├── success-patterns.md
|
||||
└── failure-patterns.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 文件格式设计
|
||||
|
||||
### 1. Soul.md(灵魂文件)
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: soul
|
||||
version: 3
|
||||
last-updated: 2024-02-24
|
||||
---
|
||||
|
||||
# Soul.md - Agent 自我认知
|
||||
|
||||
## 身份
|
||||
我是 Qiming Agent,一个可以自我进化的 AI 助手。
|
||||
|
||||
## 核心原则
|
||||
1. 用户目标优先
|
||||
2. 优先使用验证过的方法
|
||||
3. 失败时尝试备选方案
|
||||
4. 记录所有尝试以供学习
|
||||
|
||||
## 我的能力
|
||||
- [x] 文件操作
|
||||
- [x] 代码执行
|
||||
- [x] 工具安装
|
||||
- [x] 自我诊断
|
||||
|
||||
## 我的限制
|
||||
- [ ] 不能写入系统目录
|
||||
- [ ] 网络下载需要用户确认
|
||||
- [ ] 资源使用有限制
|
||||
|
||||
## 学习到的经验
|
||||
|
||||
### 成功模式
|
||||
- `2024-02-24`: 使用 uv pip 安装 Python 包,98% 成功率
|
||||
- 参考: `memory/successes/2024-02-24-install-uv.md`
|
||||
- `2024-02-24`: 使用 node 内置 JSON 解析,避免 jq 依赖
|
||||
|
||||
### 失败教训
|
||||
- `2024-02-23`: 尝试直接写入 /usr/lib 失败 → 使用工作区
|
||||
|
||||
### 技能清单
|
||||
- `parse-json` - JSON 文件解析(已学会)
|
||||
- `install-uv` - Python 包安装(已学会)
|
||||
- `grep-log` - 日志文件分析(已学会)
|
||||
|
||||
## 统计数据
|
||||
- 总任务数: 1,234
|
||||
- 成功率: 87.5%
|
||||
- 最常用方法: uv pip install (45次)
|
||||
- 最省时方法: node JSON parse (平均 0.5s)
|
||||
```
|
||||
|
||||
### 2. 成功记忆文件
|
||||
|
||||
`memory/successes/2024-02-24-parse-json.md`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
type: success
|
||||
task: parse-json
|
||||
confidence: 0.98
|
||||
created: 2024-02-24T10:30:00Z
|
||||
---
|
||||
|
||||
# JSON 文件解析成功案例
|
||||
|
||||
## 任务
|
||||
解析用户指定的 JSON 文件并提取特定字段
|
||||
|
||||
## 使用的方案
|
||||
使用 Node.js 内置 `JSON.parse()` 方法
|
||||
|
||||
## 执行步骤
|
||||
\`\`\`bash
|
||||
node -e "const fs = require('fs'); const data = JSON.parse(fs.readFileSync('${file}', 'utf8')); console.log(JSON.stringify(data, null, 2));"
|
||||
\`\`\`
|
||||
|
||||
## 结果
|
||||
- 成功解析: `data.json`
|
||||
- 耗时: 0.5s
|
||||
- 输出格式正确
|
||||
|
||||
## 为什么成功
|
||||
- Node.js 是 Electron 内置,无需安装
|
||||
- 不依赖外部工具如 jq
|
||||
- 处理大文件也很快
|
||||
|
||||
## 相关技能
|
||||
- `skills/learned/parse-json/SKILL.md`
|
||||
```
|
||||
|
||||
### 3. 失败记忆文件
|
||||
|
||||
`memory/failures/2024-02-23-pip-failed.md`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
type: failure
|
||||
task: install-python-package
|
||||
created: 2024-02-23T15:20:00Z
|
||||
---
|
||||
|
||||
# pip install 失败案例
|
||||
|
||||
## 任务
|
||||
安装 Python 包 `requests`
|
||||
|
||||
## 尝试的方案
|
||||
\`\`\`bash
|
||||
pip install requests
|
||||
\`\`\`
|
||||
|
||||
## 失败原因
|
||||
- `pip: command not found` - 系统 Python 未配置或不存在
|
||||
- 即使 pip 存在,可能污染系统 Python 环境
|
||||
|
||||
## 正确的方案
|
||||
参考 `evo-map/decisions/install-python.md`,应该使用:
|
||||
\`\`\`bash
|
||||
uv pip install requests
|
||||
\`\`\`
|
||||
|
||||
## 学到的教训
|
||||
- 优先使用 uv(应用内打包)
|
||||
- 避免使用系统 pip
|
||||
- 参考 EvoMap 中的决策树
|
||||
|
||||
## 相关记录
|
||||
- 修复后的成功: `memory/successes/2024-02-24-install-uv.md`
|
||||
```
|
||||
|
||||
### 4. 技能文件
|
||||
|
||||
`skills/learned/parse-json/SKILL.md`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: parse-json
|
||||
description: 解析 JSON 文件,提取字段,格式化输出。当需要处理 JSON 文件时使用。
|
||||
confidence: 0.98
|
||||
created: 2024-02-24
|
||||
version: 2
|
||||
---
|
||||
|
||||
# JSON 文件解析技能
|
||||
|
||||
## 触发条件
|
||||
当用户需要:
|
||||
- 读取 JSON 文件
|
||||
- 提取 JSON 中的字段
|
||||
- 格式化 JSON 输出
|
||||
- 验证 JSON 语法
|
||||
|
||||
## 推荐方法
|
||||
|
||||
### 方法 1: Node.js(推荐)
|
||||
\`\`\`bash
|
||||
node -e "const fs = require('fs'); const data = JSON.parse(fs.readFileSync('${file}', 'utf8')); console.log(JSON.stringify(data.${field}, null, 2));"
|
||||
\`\`\`
|
||||
- 成功率: 98%
|
||||
- 优点: Node.js 内置,无需依赖
|
||||
- 缺点: 简单提取很方便
|
||||
|
||||
### 方法 2: jq(备选)
|
||||
\`\`\`bash
|
||||
jq '.field' < file.json
|
||||
\`\`\`
|
||||
- 成功率: 60%
|
||||
- 优点: 功能强大
|
||||
- 缺点: 需要安装 jq
|
||||
|
||||
## 常用模式
|
||||
|
||||
### 提取单个字段
|
||||
\`\`\`bash
|
||||
node -e "console.log(JSON.parse(require('fs').readFileSync('${file}')).${field})"
|
||||
\`\`\`
|
||||
|
||||
### 格式化输出
|
||||
\`\`\`bash
|
||||
node -e "console.log(JSON.stringify(JSON.parse(require('fs').readFileSync('${file}')), null, 2))"
|
||||
\`\`\`
|
||||
|
||||
## 相关记忆
|
||||
- 成功案例: `memory/successes/2024-02-24-parse-json.md`
|
||||
```
|
||||
|
||||
### 5. EvoMap 决策文件
|
||||
|
||||
`evo-map/decisions/install-python.md`:
|
||||
|
||||
```markdown
|
||||
---
|
||||
task: install-python-package
|
||||
last-updated: 2024-02-24
|
||||
---
|
||||
|
||||
# Python 包安装决策
|
||||
|
||||
## 决策树
|
||||
|
||||
\`\`\`
|
||||
需要安装 Python 包
|
||||
│
|
||||
├─ 方案 A: uv pip install
|
||||
│ 置信度: 95%
|
||||
│ 成功率: 98%
|
||||
│ 预期时间: 5s
|
||||
│ 证据: 45 次成功 / 1 次失败
|
||||
│ 推荐: ✅ 首选
|
||||
│
|
||||
├─ 方案 B: pip install
|
||||
│ 置信度: 70%
|
||||
│ 成功率: 80%
|
||||
│ 预期时间: 10s
|
||||
│ 证据: 30 次成功 / 7 次失败
|
||||
│ 下一步: 若失败 → 切换到 uv
|
||||
│
|
||||
└─ 方案 C: 系统包管理器
|
||||
置信度: 50%
|
||||
成功率: 60%
|
||||
预期时间: 30s
|
||||
证据: 10 次成功 / 8 次失败
|
||||
备注: 最后手段,可能需要 sudo
|
||||
\`\`\`
|
||||
|
||||
## 选择逻辑
|
||||
|
||||
1. 优先使用 `uv pip install`
|
||||
2. 如果 uv 不可用,尝试 `pip install`
|
||||
3. 如果都失败,提示用户手动安装
|
||||
|
||||
## 相关记录
|
||||
- `memory/successes/2024-02-24-install-uv.md`
|
||||
- `memory/failures/2024-02-23-pip-failed.md`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 索引机制
|
||||
|
||||
### 简单文件索引
|
||||
|
||||
`memory/index.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"successes": [
|
||||
{
|
||||
"file": "successes/2024-02-24-parse-json.md",
|
||||
"task": "parse-json",
|
||||
"confidence": 0.98,
|
||||
"timestamp": "2024-02-24T10:30:00Z",
|
||||
"keywords": ["json", "parse", "node"]
|
||||
},
|
||||
{
|
||||
"file": "successes/2024-02-24-install-uv.md",
|
||||
"task": "install-python-package",
|
||||
"confidence": 0.95,
|
||||
"timestamp": "2024-02-24T09:15:00Z",
|
||||
"keywords": ["python", "uv", "install"]
|
||||
}
|
||||
],
|
||||
"failures": [
|
||||
{
|
||||
"file": "failures/2024-02-23-pip-failed.md",
|
||||
"task": "install-python-package",
|
||||
"timestamp": "2024-02-23T15:20:00Z",
|
||||
"keywords": ["python", "pip", "failed"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 索引更新策略
|
||||
|
||||
```typescript
|
||||
// 每次写入记忆后更新索引
|
||||
async function updateIndex(type: 'successes' | 'failures', filepath: string) {
|
||||
const index = await loadIndex();
|
||||
const frontmatter = await extractFrontmatter(filepath);
|
||||
|
||||
index[type].push({
|
||||
file: filepath,
|
||||
task: frontmatter.task,
|
||||
confidence: frontmatter.confidence || 0,
|
||||
timestamp: frontmatter.created,
|
||||
keywords: extractKeywords(frontmatter),
|
||||
});
|
||||
|
||||
await fs.writeFile('memory/index.json', JSON.stringify(index, null, 2));
|
||||
}
|
||||
|
||||
// 快速检索:只读索引,不需要遍历文件
|
||||
async function searchByTask(task: string): Promise<string[]> {
|
||||
const index = await loadIndex();
|
||||
return index.successes
|
||||
.filter(m => m.task === task || m.keywords.includes(task))
|
||||
.sort((a, b) => b.confidence - a.confidence)
|
||||
.map(m => m.file);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 读写接口
|
||||
|
||||
### 写入(编码)
|
||||
|
||||
```typescript
|
||||
interface MemoryWriter {
|
||||
// 写入成功记忆
|
||||
writeSuccess(memory: SuccessMemory): Promise<void>;
|
||||
|
||||
// 写入失败记忆
|
||||
writeFailure(memory: FailureMemory): Promise<void>;
|
||||
|
||||
// 更新 Soul.md
|
||||
updateSoul(update: SoulUpdate): Promise<void>;
|
||||
}
|
||||
|
||||
class MarkdownMemoryWriter implements MemoryWriter {
|
||||
async writeSuccess(memory: SuccessMemory): Promise<void> {
|
||||
const filename = `memory/successes/${memory.date}-${memory.slug}.md`;
|
||||
const content = this.formatSuccessMarkdown(memory);
|
||||
await fs.writeFile(filename, content, 'utf-8');
|
||||
|
||||
// 更新索引
|
||||
await this.updateIndex('successes', filename);
|
||||
}
|
||||
|
||||
private formatSuccessMarkdown(memory: SuccessMemory): string {
|
||||
return `---
|
||||
type: success
|
||||
task: ${memory.task}
|
||||
confidence: ${memory.confidence}
|
||||
created: ${memory.timestamp}
|
||||
---
|
||||
|
||||
# ${memory.title}
|
||||
|
||||
## 任务
|
||||
${memory.description}
|
||||
|
||||
## 使用的方案
|
||||
\`\`\`bash
|
||||
${memory.command}
|
||||
\`\`\`
|
||||
|
||||
## 结果
|
||||
${memory.result}
|
||||
|
||||
## 为什么成功
|
||||
${memory.reasoning}
|
||||
|
||||
## 相关技能
|
||||
- ${memory.relatedSkill || '无'}
|
||||
`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 检索(读取)
|
||||
|
||||
```typescript
|
||||
interface MemoryReader {
|
||||
// 语义检索(基于 frontmatter)
|
||||
search(query: string): Promise<MemoryFile[]>;
|
||||
|
||||
// 读取特定记忆
|
||||
read(path: string): Promise<MemoryContent>;
|
||||
|
||||
// 获取相关决策
|
||||
getDecision(task: string): Promise<DecisionNode>;
|
||||
}
|
||||
|
||||
class MarkdownMemoryReader implements MemoryReader {
|
||||
async search(query: string): Promise<MemoryFile[]> {
|
||||
// 1. 遍历 memory 目录
|
||||
const files = await this.getAllMemoryFiles();
|
||||
|
||||
// 2. 读取 frontmatter
|
||||
const results: MemoryFile[] = [];
|
||||
for (const file of files) {
|
||||
const frontmatter = await this.extractFrontmatter(file);
|
||||
|
||||
// 3. 匹配查询
|
||||
if (this.matches(query, frontmatter)) {
|
||||
results.push({ file, frontmatter });
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 按置信度/时间排序
|
||||
return results.sort((a, b) => b.confidence - a.confidence);
|
||||
}
|
||||
|
||||
private matches(query: string, frontmatter: Frontmatter): boolean {
|
||||
const { task, type, keywords } = frontmatter;
|
||||
return (
|
||||
task?.includes(query) ||
|
||||
type === query ||
|
||||
keywords?.some((k: string) => k.includes(query))
|
||||
);
|
||||
}
|
||||
|
||||
async getDecision(task: string): Promise<DecisionNode> {
|
||||
const decisionFile = `evo-map/decisions/${this.slugify(task)}.md`;
|
||||
|
||||
if (await fs.exists(decisionFile)) {
|
||||
return this.parseDecisionFile(await fs.readFile(decisionFile, 'utf-8'));
|
||||
}
|
||||
|
||||
// 回退到通用决策
|
||||
return this.getGenericDecision(task);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 记忆清理策略
|
||||
|
||||
```typescript
|
||||
interface MemoryCleanupPolicy {
|
||||
maxShortTermEntries: number; // 最多 50 条
|
||||
maxLongTermEntries: number; // 最多 1000 条
|
||||
maxAge: number; // 90 天
|
||||
lowConfidenceThreshold: number; // 置信度 < 0.3
|
||||
}
|
||||
|
||||
async function cleanupMemory(policy: MemoryCleanupPolicy): Promise<CleanupResult> {
|
||||
const index = await loadIndex();
|
||||
const now = Date.now();
|
||||
const toDelete: string[] = [];
|
||||
|
||||
// 1. 清理过期的低置信度记忆
|
||||
for (const memory of index.successes) {
|
||||
const age = now - new Date(memory.timestamp).getTime();
|
||||
const ageDays = age / (1000 * 60 * 60 * 24);
|
||||
|
||||
if (ageDays > policy.maxAge || memory.confidence < policy.lowConfidenceThreshold) {
|
||||
toDelete.push(memory.file);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 限制总数量
|
||||
const sorted = [...index.successes].sort((a, b) =>
|
||||
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
||||
);
|
||||
if (sorted.length > policy.maxLongTermEntries) {
|
||||
const excess = sorted.slice(policy.maxLongTermEntries);
|
||||
toDelete.push(...excess.map(m => m.file));
|
||||
}
|
||||
|
||||
// 3. 执行删除
|
||||
for (const file of toDelete) {
|
||||
await fs.unlink(`memory/${file}`);
|
||||
}
|
||||
|
||||
// 4. 更新索引
|
||||
await rebuildIndex();
|
||||
|
||||
return { deleted: toDelete.length, remaining: index.successes.length - toDelete.length };
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 向量检索(可选升级)
|
||||
|
||||
当记忆数量超过 500 条时,可以引入语义向量检索以提升召回精度:
|
||||
|
||||
### 升级时机
|
||||
|
||||
- **当前阶段**:使用关键词匹配(已实现)
|
||||
- 基于 frontmatter 的 `task`、`type`、`keywords` 字段
|
||||
- 适用于记忆数量 < 500 条
|
||||
|
||||
- **升级阶段**:记忆数量 > 500 条时
|
||||
- 引入嵌入向量(embedding)进行语义检索
|
||||
- 保持 Markdown 格式不变,向量作为补充索引
|
||||
|
||||
### 向量检索方案
|
||||
|
||||
```typescript
|
||||
// 记忆编码时添加嵌入向量
|
||||
interface EncodedMemory {
|
||||
id: string;
|
||||
type: 'success' | 'failure' | 'insight';
|
||||
embedding?: number[]; // 语义向量(可选)
|
||||
context: {
|
||||
task: string;
|
||||
environment: string;
|
||||
constraints: string[];
|
||||
};
|
||||
// ... 其他字段
|
||||
}
|
||||
|
||||
// 更新后的索引
|
||||
interface MemoryIndex {
|
||||
successes: MemoryIndexEntry[];
|
||||
failures: MemoryIndexEntry[];
|
||||
}
|
||||
|
||||
interface MemoryIndexEntry {
|
||||
file: string;
|
||||
task: string;
|
||||
confidence: number;
|
||||
timestamp: string;
|
||||
keywords: string[];
|
||||
embedding?: number[]; // 新增:嵌入向量
|
||||
}
|
||||
```
|
||||
|
||||
### 检索接口升级
|
||||
|
||||
```typescript
|
||||
class MarkdownMemoryReader implements MemoryReader {
|
||||
async search(query: string): Promise<MemoryFile[]> {
|
||||
const files = await this.getAllMemoryFiles();
|
||||
|
||||
// 初期:关键词匹配
|
||||
const results: MemoryFile[] = [];
|
||||
for (const file of files) {
|
||||
const frontmatter = await this.extractFrontmatter(file);
|
||||
if (this.matchesKeyword(query, frontmatter)) {
|
||||
results.push({ file, frontmatter });
|
||||
}
|
||||
}
|
||||
|
||||
// 后期:记忆 > 500 条时使用向量检索
|
||||
if (files.length > 500) {
|
||||
const queryEmbedding = await this.generateEmbedding(query);
|
||||
return this.searchBySimilarity(queryEmbedding, files);
|
||||
}
|
||||
|
||||
return results.sort((a, b) => b.confidence - a.confidence);
|
||||
}
|
||||
|
||||
// 语义相似度检索(待实现)
|
||||
private async searchBySimilarity(
|
||||
queryEmbedding: number[],
|
||||
files: string[]
|
||||
): Promise<MemoryFile[]> {
|
||||
const results: Array<{ file: string; score: number }> = [];
|
||||
|
||||
for (const file of files) {
|
||||
const entry = await this.getIndexEntry(file);
|
||||
if (entry.embedding) {
|
||||
const score = this.cosineSimilarity(queryEmbedding, entry.embedding);
|
||||
results.push({ file, score });
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
.filter(r => r.score > 0.7) // 相似度阈值
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.slice(0, 10); // 返回 top-10
|
||||
}
|
||||
|
||||
private cosineSimilarity(a: number[], b: number[]): number {
|
||||
const dotProduct = a.reduce((sum, val, i) => sum + val * b[i], 0);
|
||||
const magnitudeA = Math.sqrt(a.reduce((sum, val) => sum + val * val, 0));
|
||||
const magnitudeB = Math.sqrt(b.reduce((sum, val) => sum + val * val, 0));
|
||||
return dotProduct / (magnitudeA * magnitudeB);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 向量存储
|
||||
|
||||
向量可以存储在以下位置:
|
||||
|
||||
```
|
||||
~/.qimingclaw/
|
||||
├── memory/
|
||||
│ ├── index.json # 原有索引
|
||||
│ └── embeddings.json # 新增:向量索引(可选)
|
||||
│ # 或者使用 SQLite 存储
|
||||
├── memory.db # 新增:SQLite 向量数据库(可选)
|
||||
```
|
||||
|
||||
### 实现优先级
|
||||
|
||||
| 阶段 | 记忆数量 | 检索方式 | 优先级 |
|
||||
|------|----------|----------|--------|
|
||||
| P0 | < 500 | 关键词匹配 | 已实现 |
|
||||
| P1 | 500-2000 | 关键词 + 向量混合 | 可选 |
|
||||
| P2 | > 2000 | 纯向量检索 | 待定 |
|
||||
|
||||
---
|
||||
|
||||
## 优势对比
|
||||
|
||||
| 特性 | Markdown 方案 | 数据库方案 |
|
||||
|------|---------------|-----------|
|
||||
| **可读性** | ✅ 人类可读 | ❌ 需要工具 |
|
||||
| **版本控制** | ✅ Git 友好 | ⚠️ 需要 migration |
|
||||
| **可移植性** | ✅ 纯文件 | ❌ 依赖软件 |
|
||||
| **搜索** | ⚠️ 需索引 | ✅ SQL 查询 |
|
||||
| **复杂度** | ✅ 简单 | ❌ 复杂 |
|
||||
| **调试** | ✅ 直接查看 | ❌ 需要 query |
|
||||
|
||||
---
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [总览](./OVERVIEW.md) - 产品定位、核心原则
|
||||
- [核心组件](./COMPONENTS.md) - Memory、Skill Creator、EvoMap、Soul.md
|
||||
- [循环流程](./LOOP.md) - 完整循环流程、接口定义
|
||||
- [隔离策略](./ISOLATION.md) - 三区模型、环境变量
|
||||
Reference in New Issue
Block a user