利用 Basic Memory 和 Milvus 构建语义项目记忆
Basic Memory将项目知识保存在普通的 Markdown 文件中,并通过命令行界面 (CLI) 和 MCP 服务器提供访问。这为编码代理提供了一个持久化的存储空间,用于记录决策、操作手册和经验教训,这些内容应能超越单次对话而长期保留。
在本教程中,我们将为一个应用团队构建一个小型记忆项目。我们将记录有关缓存、身份验证、部署和备份的笔记,然后通过语义搜索和混合搜索检索到正确的笔记。
Milvus将负责存储向量并执行相似度搜索。Basic Memory 将继续在 PostgreSQL 中管理 Markdown 笔记、项目元数据、全文搜索以及向量清单。
Markdown notes
|
v
Basic Memory CLI / MCP
|-- PostgreSQL: projects, metadata, full-text search, vector manifest
|-- OpenAI: embeddings
`-- Milvus: vector persistence and similarity search
本教程使用 Milvus Lite,它会在您机器上的某个路径下本地运行。相同的 Basic Memory 配置稍后可指向 Milvus Standalone、Milvus Distributed 或 Zilliz Cloud。
先决条件
您需要:
- Python 3.12 或更高版本
uv- 一个 PostgreSQL 数据库及其
postgresql+asyncpg://...连接 URL - 一个 OpenAI API 密钥
从 PyPI 安装 Basic Memory 及其 Milvus 可选依赖项:
uv tool install --python 3.12 "basic-memory[milvus]"
配置 Basic Memory
为本教程创建一个工作区。将 Basic Memory 的配置和 Milvus Lite 数据保存在此处,便于后续检查和删除示例。
mkdir -p basic-memory-milvus-demo/notes
cd basic-memory-milvus-demo
export BASIC_MEMORY_CONFIG_DIR="$PWD/.basic-memory"
将 PostgreSQL 配置为主数据库,OpenAI 配置为嵌入提供商,Milvus 配置为向量索引:
export BASIC_MEMORY_DATABASE_BACKEND=postgres
export BASIC_MEMORY_DATABASE_URL="postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE"
export BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED=true
export BASIC_MEMORY_SEMANTIC_VECTOR_INDEX=milvus
export BASIC_MEMORY_MILVUS_URI="$PWD/basic-memory-vectors.db"
export BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER=openai
export BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL=text-embedding-3-small
export OPENAI_API_KEY="sk-***********"
此处,BASIC_MEMORY_MILVUS_URI 为本地路径,因此 PyMilvus 会自动启动 Milvus Lite。无需单独的 Milvus 服务器。
在“基本内存”中,Milvus 虽为可选组件,但本教程中选用了它作为向量后端。此选择目前仅在主数据库后端为 PostgreSQL 时生效。基于 SQLite 的“基本内存”项目则使用sqlite-vec 。
创建内存项目
一个 Basic Memory 项目将一个名称映射到一个包含 Markdown 笔记的目录。将本教程目录添加为项目并将其设为默认项目:
bm project add app-memory "$PWD/notes" --default
应用团队现在拥有了一个持久的内存空间。让我们用一个小型混合目录来填充它。其中一些笔记与我们后续的问题相关,而其他笔记则提供了真实的干扰项。
记录项目记忆
首先从应用程序的缓存决策入手:
bm tool write-note \
--title "Caching Strategy" \
--folder "engineering" \
--project app-memory <<'EOF'
# Caching Strategy
The application caches read-heavy product responses in Redis for five minutes. This avoids repeated database queries and makes repeated requests faster. Cache entries are invalidated immediately after a write.
EOF
记录身份验证令牌的处理方式:
bm tool write-note \
--title "Authentication Tokens" \
--folder "engineering" \
--project app-memory <<'EOF'
# Authentication Tokens
JWT access tokens expire after fifteen minutes. Refresh tokens rotate on every use. After suspicious activity, revoke the entire token family and require the user to sign in again.
EOF
添加两份运维手册:
bm tool write-note \
--title "Deployment Reliability" \
--folder "operations" \
--project app-memory <<'EOF'
# Deployment Reliability
Production releases use a canary deployment. Readiness probes must pass before traffic shifts, and the rollout automatically stops when the error rate crosses the agreed threshold.
EOF
bm tool write-note \
--title "Database Backups" \
--folder "operations" \
--project app-memory <<'EOF'
# Database Backups
PostgreSQL uses daily snapshots and continuous write-ahead log archiving. The team runs a restore drill every month and records the recovery point and recovery time.
EOF
最后,添加两条互不相关的产品笔记。与所有文档都相关的目录相比,这些笔记能使搜索练习更具代表性:
bm tool write-note \
--title "UI Accessibility" \
--folder "product" \
--project app-memory <<'EOF'
# UI Accessibility
The settings screen must support keyboard navigation, visible focus states, sufficient color contrast, and descriptive labels for screen readers.
EOF
bm tool write-note \
--title "Content Planning" \
--folder "product" \
--project app-memory <<'EOF'
# Content Planning
The content calendar tracks blog drafts, launch screenshots, reviewers, and publication dates for the next product release.
EOF
每条说明仍是一个位于notes/ 下的普通 Markdown 文件。Basic Memory 在不剥夺文件系统控制权的前提下,为其添加了可搜索的结构。
构建搜索索引
在添加或大幅修改一组说明后,执行全量重新索引:
bm reindex --full --project app-memory
在此步骤中,Basic Memory 会:
- 读取并切分 Markdown 笔记。
- 构建 PostgreSQL 全文索引。
- 将分块数据发送至配置好的 OpenAI Embeddings 模型。
- 将生成的向量存储在项目专用的 Milvus Collection 中。
- 在 PostgreSQL 向量清单中将成功存储的分块标记为“就绪”。
Basic Memory 为每个项目使用一个确定性的 Milvus Collection。您无需自行创建或命名该 Collection。
按语义检索记忆
假设一位新入职的工程师记得应用程序对重复请求有优化措施,但不记得团队将其称为“缓存策略”。
使用向量搜索以自然语言提出问题:
bm tool search-notes \
"How does the application make repeated requests faster?" \
--vector \
--project app-memory \
--page-size 3 \
--plain
Caching Strategy 即使查询中未重复笔记标题,该结果也应位列首位。向量搜索会对问题进行嵌入处理,并向 Milvus 查询最接近的存储块。
精确得分和排名较低的结果可能会因嵌入模型及项目内容的不同而有所差异。
结合语义和关键词信号
现在设想应对一次安全事件。查询中包含“JWT ”等精确术语,但我们也希望获取关于令牌撤销和重新登录等概念相关的内容。
使用混合搜索:
bm tool search-notes \
"JWT rotation after suspicious activity" \
--hybrid \
--project app-memory \
--page-size 3 \
--plain
Authentication Tokens 应作为首条结果。Basic Memory 将 PostgreSQL 全文检索与 Milvus 向量检索相结合,优先展示在任一路径上表现优异的内容,尤其是同时被两者检索到的内容。
这三种搜索模式各有优势:
| 模式 | 命令标志 | 最佳用途 |
|---|---|---|
| 全文 | 无模式标志 | 精确术语、短语和布尔关键字查询 |
| 向量 | --vector | 同义替代表述、概念及探索性问题 |
| 混合 | --hybrid | 同时利用关键词和语义信号进行通用检索 |
使用其他 Milvus 部署
当您的需求超出 Milvus Lite 的范围时,应用程序代码和 Basic Memory 命令保持不变。只需更改 URI,并在必要时提供令牌。
对于 Milvus 服务器:
export BASIC_MEMORY_MILVUS_URI="http://localhost:19530"
export BASIC_MEMORY_MILVUS_TOKEN="root:Milvus"
对于 Zilliz Cloud:
export BASIC_MEMORY_MILVUS_URI="https://YOUR_CLUSTER_ENDPOINT"
export BASIC_MEMORY_MILVUS_TOKEN="YOUR_API_KEY"
在将现有项目在向量后端之间切换之前,请创建一个新的目标 Collection,或遵循 Basic Memory 的向量存储迁移流程。然后重建向量:
bm reindex --full --project app-memory
通过 MCP 使用同一内存
CLI 适用于设置、维护、脚本编写以及理解数据流。在日常工作中,MCP 客户端可以启动相同的 Basic Memory 服务,并直接调用write_note 、search_notes 和build_context 等工具。
例如,Codex MCP 配置可以运行由uv tool 安装的命令:
[mcp_servers.basic-memory]
command = "basic-memory"
args = ["mcp"]
[mcp_servers.basic-memory.env]
BASIC_MEMORY_CONFIG_DIR = "/absolute/path/to/basic-memory-milvus-demo/.basic-memory"
BASIC_MEMORY_DATABASE_BACKEND = "postgres"
BASIC_MEMORY_DATABASE_URL = "postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE"
BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED = "true"
BASIC_MEMORY_SEMANTIC_VECTOR_INDEX = "milvus"
BASIC_MEMORY_MILVUS_URI = "/absolute/path/to/basic-memory-milvus-demo/basic-memory-vectors.db"
BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER = "openai"
BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL = "text-embedding-3-small"
OPENAI_API_KEY = "sk-***********"
其他 MCP 客户端使用相同的可执行文件和 JSON 格式的参数:
{
"mcpServers": {
"basic-memory": {
"command": "basic-memory",
"args": ["mcp"],
"env": {
"BASIC_MEMORY_CONFIG_DIR": "/absolute/path/to/basic-memory-milvus-demo/.basic-memory",
"BASIC_MEMORY_DATABASE_BACKEND": "postgres",
"BASIC_MEMORY_DATABASE_URL": "postgresql+asyncpg://USER:PASSWORD@HOST:5432/DATABASE",
"BASIC_MEMORY_SEMANTIC_SEARCH_ENABLED": "true",
"BASIC_MEMORY_SEMANTIC_VECTOR_INDEX": "milvus",
"BASIC_MEMORY_MILVUS_URI": "/absolute/path/to/basic-memory-milvus-demo/basic-memory-vectors.db",
"BASIC_MEMORY_SEMANTIC_EMBEDDING_PROVIDER": "openai",
"BASIC_MEMORY_SEMANTIC_EMBEDDING_MODEL": "text-embedding-3-small",
"OPENAI_API_KEY": "sk-***********"
}
}
}
}
尽可能将数据库密码和 API 密钥保存在客户端的密钥管理或运行环境中。关键要求是 MCP 进程必须接收与 CLI 相同的 Basic Memory 配置。
各存储层各自负责的内容
在本教程结尾处,职责被有意进行了分离:
- 项目目录负责管理原始的 Markdown 笔记。
- PostgreSQL 负责管理 Basic Memory 的项目、实体、元数据、全文索引以及权威向量清单。
- OpenAI 将笔记片段和搜索问题转换为 Embeddings。
- Milvus 负责向量持久化和最近邻检索。
- Basic Memory 负责协调各层,并提供统一的 CLI 和 MCP 操作体验。
因此,在此集成中,Milvus 并未取代 PostgreSQL。它仅取代了 PostgreSQL 中用于向量存储和相似度搜索的pgvector 路径,而 Basic Memory 的其余关系型和全文搜索功能仍保留在 PostgreSQL 中。