Skip to content

Commit e624b3b

Browse files
committed
docs(blog): fix mkdocs strict nav and links
1 parent c5d50fb commit e624b3b

9 files changed

Lines changed: 581 additions & 4 deletions

docs-site/blog/agent-memory-design.md

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,125 @@ def retrieve_context(query: str, max_tokens: int = 8000) -> str:
165165
return truncate_to_token_limit(context, max_tokens)
166166
```
167167

168+
## 完整实现示例
169+
170+
```python
171+
# memory_system.py
172+
from dataclasses import dataclass
173+
from enum import Enum
174+
from typing import Optional
175+
import sqlite3
176+
import time
177+
import pickle
178+
179+
class MemoryType(Enum):
180+
WORKING = "working"
181+
SESSION = "session"
182+
PERSISTENT = "persistent"
183+
184+
@dataclass
185+
class Memory:
186+
id: Optional[int]
187+
memory_type: MemoryType
188+
content: str
189+
embedding: list[float]
190+
created_at: float
191+
workspace_id: str
192+
193+
class MemorySystem:
194+
def __init__(self, db_path: str):
195+
self.conn = sqlite3.connect(db_path)
196+
self._init_db()
197+
198+
def _init_db(self):
199+
self.conn.execute("""
200+
CREATE TABLE IF NOT EXISTS memories (
201+
id INTEGER PRIMARY KEY,
202+
memory_type TEXT NOT NULL,
203+
content TEXT NOT NULL,
204+
embedding BLOB,
205+
created_at REAL NOT NULL,
206+
workspace_id TEXT NOT NULL
207+
)
208+
""")
209+
self.conn.commit()
210+
211+
def save_memory(
212+
self,
213+
memory_type: MemoryType,
214+
content: str,
215+
embedding: list[float],
216+
workspace_id: str
217+
) -> int:
218+
"""保存记忆"""
219+
cursor = self.conn.execute("""
220+
INSERT INTO memories (memory_type, content, embedding, created_at, workspace_id)
221+
VALUES (?, ?, ?, ?, ?)
222+
""", (
223+
memory_type.value,
224+
content,
225+
pickle.dumps(embedding),
226+
time.time(),
227+
workspace_id
228+
))
229+
self.conn.commit()
230+
return cursor.lastrowid
231+
232+
def retrieve(
233+
self,
234+
query_embedding: list[float],
235+
workspace_id: str,
236+
memory_types: list[MemoryType] = None,
237+
top_k: int = 5
238+
) -> list[Memory]:
239+
"""检索记忆"""
240+
if memory_types is None:
241+
memory_types = [MemoryType.PERSISTENT]
242+
243+
type_values = [t.value for t in memory_types]
244+
placeholders = ",".join("?" * len(type_values))
245+
246+
cursor = self.conn.execute(f"""
247+
SELECT id, memory_type, content, embedding, created_at
248+
FROM memories
249+
WHERE workspace_id = ? AND memory_type IN ({placeholders})
250+
ORDER BY created_at DESC
251+
LIMIT ?
252+
""", [workspace_id] + type_values + [top_k])
253+
254+
return [
255+
Memory(
256+
id=row[0],
257+
memory_type=MemoryType(row[1]),
258+
content=row[2],
259+
embedding=pickle.loads(row[3]) if row[3] else [],
260+
created_at=row[4],
261+
workspace_id=workspace_id
262+
)
263+
for row in cursor
264+
]
265+
266+
def build_context(self, query: str, workspace_id: str) -> str:
267+
"""构建完整上下文"""
268+
query_embedding = self._simple_embed(query)
269+
270+
# 检索持久记忆 + 会话记忆
271+
persistent = self.retrieve(query_embedding, workspace_id, [MemoryType.PERSISTENT], top_k=3)
272+
session = self.retrieve(query_embedding, workspace_id, [MemoryType.SESSION], top_k=5)
273+
274+
parts = ["## 相关记忆"]
275+
for m in persistent + session:
276+
parts.append(f"- [{m.memory_type.value}] {m.content[:200]}")
277+
278+
return "\n".join(parts)
279+
280+
def _simple_embed(self, text: str) -> list[float]:
281+
"""简化版 embedding"""
282+
import hashlib
283+
h = hashlib.sha256(text.encode()).digest()
284+
return [b / 255.0 for b in h[:32]]
285+
```
286+
168287
## LoopForge 的记忆设计
169288

170289
作为本地优先的 Agent OS,LoopForge 实现了完整的多层记忆系统:
@@ -238,6 +357,6 @@ Agent 的记忆不是"记住所有事情",而是**在对的时刻想起对的
238357

239358
**相关链接**
240359

241-
- [LoopForge 记忆模块源码](../explanation/memory-subsystem.md)
242-
- [向量检索最佳实践](../how-to/vector-search.md)
360+
- [LoopForge 记忆模块源码(rexos-memory)](https://github.com/rexleimo/LoopForge/tree/main/meos/crates/rexos-memory)
361+
- [LoopForge 概念与记忆模型](../explanation/concepts.md)
243362
- [Harness 教程:长任务执行](../tutorials/harness-long-task.md)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Editorial Calendar
2+
3+
Use this template to ship one reproducible, execution-focused post every week.
4+
5+
## Weekly Cadence
6+
7+
1. Monday: pick one real user pain point.
8+
2. Tuesday: collect reproducible commands and evidence screenshots.
9+
3. Wednesday: draft the post (problem -> commands -> verification -> pitfalls).
10+
4. Thursday: run internal technical review.
11+
5. Friday: publish and sync updates to changelog/community channels.
12+
13+
## Post Template
14+
15+
~~~markdown
16+
# [Outcome-first title]
17+
18+
## Problem
19+
- Who is blocked?
20+
- Where does it fail in a real workflow?
21+
22+
## Reproduce
23+
$ [minimal reproducible commands]
24+
25+
## Fix Pattern
26+
$ [stable command sequence]
27+
28+
## Verification
29+
- Which command proves success?
30+
- Which artifact proves success?
31+
32+
## Common Pitfalls
33+
- Typical configuration mistakes
34+
- Site/provider instability notes
35+
~~~
36+
37+
## Suggested 4-Week Topics
38+
39+
1. Layered smoke strategy for stable vs dynamic websites.
40+
2. One-command onboarding and failure recovery.
41+
3. Provider routing strategy for cost vs performance.
42+
4. Harness checkpoint-driven long-task refactoring.

docs-site/blog/mcp-integration-guide.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,107 @@ loopforge agent run \
159159
--prompt "阅读 src/main.rs,分析代码结构,写一份500字的架构说明"
160160
```
161161

162+
## 进阶:自定义 MCP Server
163+
164+
如果官方 Server 不满足需求,可以自己写:
165+
166+
### 1. Python 实现
167+
168+
```python
169+
# my_mcp_server.py
170+
from mcp.server import Server
171+
from mcp.server.stdio import stdio_server
172+
from pydantic import AnyUrl
173+
import json
174+
175+
app = Server("my-custom-server")
176+
177+
@app.list_resources()
178+
async def list_resources():
179+
return [
180+
Resource(
181+
uri=AnyUrl("myapp://config"),
182+
name="app_config",
183+
description="Application configuration"
184+
)
185+
]
186+
187+
@app.read_resource()
188+
async def read_resource(uri: AnyUrl):
189+
if uri == "myapp://config":
190+
with open("config.json") as f:
191+
return json.load(f)
192+
raise ValueError(f"Unknown resource: {uri}")
193+
194+
@app.list_tools()
195+
async def list_tools():
196+
return [
197+
Tool(
198+
name="analyze_code",
199+
description="Analyze Python code for issues",
200+
inputSchema={
201+
"type": "object",
202+
"properties": {
203+
"file_path": {"type": "string"}
204+
},
205+
"required": ["file_path"]
206+
}
207+
)
208+
]
209+
210+
@app.call_tool()
211+
async def call_tool(name: str, arguments: dict):
212+
if name == "analyze_code":
213+
# 实现代码分析逻辑
214+
return analyze_python(arguments["file_path"])
215+
raise ValueError(f"Unknown tool: {name}")
216+
217+
if __name__ == "__main__":
218+
stdio_server.run(app)
219+
```
220+
221+
### 2. 注册到 LoopForge
222+
223+
```json
224+
{
225+
"servers": {
226+
"my-custom": {
227+
"command": "python",
228+
"args": ["/path/to/my_mcp_server.py"]
229+
}
230+
}
231+
}
232+
```
233+
234+
### 3. 更多官方 MCP Server
235+
236+
| Server | 功能 |
237+
|--------|------|
238+
| `@modelcontextprotocol/server-filesystem` | 文件系统操作 |
239+
| `@modelcontextprotocol/server-git` | Git 操作 |
240+
| `@modelcontextprotocol/server-github` | GitHub API |
241+
| `@modelcontextprotocol/server-brave-search` | 网页搜索 |
242+
| `@modelcontextprotocol/server-sqlite` | SQLite 数据库 |
243+
| `@modelcontextprotocol/server-postgres` | PostgreSQL |
244+
| `@modelcontextprotocol/server-memory` | 知识图谱记忆 |
245+
246+
## 常见问题
247+
248+
### Q: MCP 和 API 有什么区别?
249+
250+
API 是"你问我答",MCP 是"我知我能"。MCP 让 AI 知道自己有什么工具可用,不需要每次都通过 prompt 告知。
251+
252+
### Q: 安全吗?
253+
254+
MCP 本身是协议,安全取决于 Server 实现。建议:
255+
- 本地开发用 filesystem server
256+
- 生产环境用细粒度权限控制
257+
- 不推荐直接暴露 MCP Server 到公网
258+
259+
### Q: 支持流式输出吗?
260+
261+
支持。MCP 基于 JSON-RPC 2.0,支持 `server->client` 通知,可以实现实时进度更新。
262+
162263
## 总结
163264

164265
MCP 不仅仅是一个协议——它是 AI 从"问答助手"进化到"执行引擎"的关键一步。

0 commit comments

Comments
 (0)