1. 为什么要在本地跑一套 memobase 用户画像系统
memobase 是一个开源的用户画像(User Profile)记忆层,它能做什么?简单说,它把用户和 AI 的多轮对话、行为日志,自动抽取成结构化的画像条目(比如“喜欢喝美式”“住在杭州”“正在学 Rust”),再通过一个 memory prompt 塞回你的大模型上下文里。适合谁?适合正在做 AI 陪伴、AI 客服、个性化推荐、Agent 长期记忆的开发者——只要你希望 AI 记住用户,而不是每次对话都从零开始。
我试过把 memobase 直接跑在云服务器上,用 Docker 拉起后端,Redis 做并发锁和缓存,Postgres 存画像和事件,模型调用 endpoint 统一改到 TaoToken 的 Key/API 通道。整套链路跑通之后,写入一条对话、flush、再读 profile,全程不到 10 秒。这篇就把 docker-compose、环境变量、config.yaml、验证脚本、以及我踩过的 401 和 local proxy failed 报错,一次性讲清楚。
核心检索词先摆出来:memobase 用户画像 Docker 部署、Redis Postgres 配置、TaoToken 统一 Key 接入。你跟着做,能拿到一个可复制、可验证、可排障的端到端方案。
memobase 的架构分三层:API 层(FastAPI,默认 8019 端口)、存储层(Postgres 持久化 + Redis 缓存/锁)、模型层(调用 LLM 做抽取、合并、总结)。它的记忆生成流程在src/server/api/memobase_server/controllers/modal/chat/下,包含 extract_topics(抽取主题)、merge_or_add_new_memos(合并或新增)、handle_session_event(事件创建)、organize_profiles(组织画像)几个阶段。每个阶段都可能调 LLM,所以模型 endpoint 配错,整个画像就出不来。
这也是为什么我要把模型通道统一到 TaoToken:一个 Key、一个 Base URL,省得在 config.yaml 里到处换 provider。下面从 Docker 部署开始。
2. TaoToken 前置准备:Key、Base URL 与模型 ID 三件套
在动 Docker 之前,先把模型通道准备好。memobase 的config.yaml里需要三个东西:llm_api_key、llm_base_url、best_llm_model。这三个就是所谓的三件套,缺一个都跑不起来。
第一步,去 TaoToken 控制台拿 Key。打开 https://taotoken.net/console ,登录后进 API Keys 页面创建一个新 Key,复制出来形如sk-xxxx。这个 Key 就是后面填进llm_api_key的值。
第二步,确认 Base URL。TaoToken 的 API 入口是 https://taotoken.net/api ,注意这里不加任何 UTM 参数,直接写这个地址。memobase 走的是 OpenAI 兼容格式,所以llm_style保持openai即可,Base URL 填https://taotoken.net/api/v1。
第三步,选模型 ID。TaoToken 支持多种模型,你可以先在模型对话页面 https://taotoken.net/models 试一下哪个模型抽取效果好。实测下来,做画像抽取这种结构化任务,用中等规模的模型就够,不必上最贵的。把选好的模型 ID 填进best_llm_model。
如果你后面还要接 Claude Code 或者做长期编码 Agent,可以顺手看下 Coding Plan:https://taotoken.net/coding-plan ,它和 memobase 用的是同一套 Key 体系,配置逻辑一致。
注意:TaoToken 是合规的 API 聚合通道,不是任何形式的非法中转。你只需要把它当成一个统一的 OpenAI 兼容 endpoint 来用就行。
三件套准备好之后,记下来:
| 配置项 | 值 |
|---|---|
| Base URL | https://taotoken.net/api/v1 |
| API Key | sk-你的Key |
| Model ID | 你在模型对话页选定的模型 |
这三行后面会原样出现在config.yaml里。别急着关页面,Docker 部署时还要回来核对。
3. Docker 部署 memobase:docker-compose 与 config.yaml 可复制配置
现在进入正题。先把 memobase 源码拉下来,进到 server 目录:
git clone https://github.com/memodb-io/memobase.git cd memobase/src/server cp .env.example .env cp ./api/config.yaml.example ./api/config.yamlcp这两步很关键,.env管数据库和 Redis 的连接信息,config.yaml管模型通道。先改config.yaml,把三件套填进去:
llm_api_key: sk-你的TaoTokenKey llm_base_url: https://taotoken.net/api/v1 llm_style: openai best_llm_model: 你的模型ID这里有个坑:memobase 默认的 provider 适配文件可能只认 openrouter 之类的路径。如果你发现调用报错说 provider 不支持,就去src/server/api/memobase_server/下找 provider 适配目录,确认 openai 风格的适配器存在。因为 TaoToken 走的是标准 OpenAI 格式,llm_style: openai通常直接可用,不需要额外写适配文件。
接着改.env,重点是 Postgres 和 Redis 的连接串。默认值一般是这样:
POSTGRES_USER=memobase POSTGRES_PASSWORD=memobase POSTGRES_DB=memobase POSTGRES_HOST=memobase-server-db POSTGRES_PORT=5432 REDIS_HOST=memobase-server-redis REDIS_PORT=6379 REDIS_PASSWORD=helloworld如果你要自定义,改完记得和 docker-compose 里的服务名对齐。下面是可复制的docker-compose.yml核心片段(放在src/server下):
services: memobase-server-db: image: postgres:16 environment: POSTGRES_USER: memobase POSTGRES_PASSWORD: memobase POSTGRES_DB: memobase volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" memobase-server-redis: image: redis:7 command: redis-server --requirepass helloworld ports: - "6379:6379" memobase-server-api: build: . env_file: .env depends_on: - memobase-server-db - memobase-server-redis ports: - "8019:8019" volumes: pgdata:三个服务:db存画像,redis做锁和缓存,api是对外入口。注意memobase-server-api的env_file指向.env,这样容器里能读到数据库和 Redis 的地址。
配置好之后构建并启动:
docker-compose build && docker-compose up -d第一次 build 会拉依赖,耐心等几分钟。起来之后用docker ps看三个容器是不是都 Up。如果 api 容器反复重启,多半是.env里的 host 名写错了,或者 Postgres 还没初始化完 api 就抢跑——加个depends_on的健康检查能缓解。
启动成功后,浏览器访问http://你的公网IP:8019/docs,能看到 FastAPI 的 Swagger 文档页,说明 API 层通了。这一步是整个链路的地基,文档页打不开,后面全白搭。
4. 验证请求:写入对话、flush、读取画像的完整动作
API 通了之后,用 Python SDK 跑一次端到端验证。先装依赖:
pip install memobase openai rich然后写一个最小验证脚本。注意PROJECT_URL换成你的地址,PROJECT_TOKEN默认是secret(在.env或项目配置里能找到):
from memobase import MemoBaseClient, ChatBlob PROJECT_URL = "http://你的公网IP:8019" PROJECT_TOKEN = "secret" client = MemoBaseClient(project_url=PROJECT_URL, api_key=PROJECT_TOKEN) assert client.ping(), "Memobase server is not running" messages = [ {"role": "user", "content": "Hello, I'm Gus", "created_at": "2025-01-14"}, {"role": "assistant", "content": "Hi, nice to meet you, Gus!", "alias": "HerAI"}, ] blob = ChatBlob(messages=messages) uid = client.add_user() u = client.get_user(uid) bid = u.insert(blob) print("User ID is", uid) print("Blob ID is", bid) print("Start processing...") u.flush() print("\nBelow is your profile:") print(u.profile(need_json=True)) print("\nRecent events:") for e in u.event(): print(e.created_at) for i in e.event_data.profile_delta: print("-", i.attributes["topic"], i.attributes["sub_topic"], i.content, sep="::") print("\nMemory context:") print(u.context())跑起来之后,你会看到User ID、Blob ID,然后flush()触发后台的 LLM 抽取流程。等几秒,profile(need_json=True)会返回结构化的画像 JSON,event()返回这次对话产生的事件条目,context()返回一段可以直接塞进大模型 prompt 的记忆文本。
这里的关键动作是flush()。memobase 有个BufferZone机制:它不会每来一条 blob 就立刻调 LLM,而是先缓存,等达到最大 token 数或者空闲超时,才批量处理。这样能省 token、提效率。所以如果你insert完立刻读 profile,可能还是空的——必须flush()强制触发。
验证成功的标志:profile 里出现从对话中抽取的事实,event 里有对应的 profile_delta,context 返回非空字符串。如果 profile 是空的,先检查config.yaml的三件套,再看 api 容器日志有没有 LLM 调用报错。
5. 常见报错排查:401、local proxy failed、reading choices、OAuth
这一段是我踩坑最多的地方,按真实报错对照着排。
401 Unauthorized。最常见的原因是llm_api_key填错,或者 Key 前后带了空格。TaoToken 的 Key 是sk-开头,复制时别漏字符。还有一种情况是 Base URL 写成了https://taotoken.net/api(少了/v1),OpenAI 兼容客户端会拼出错误的路径导致鉴权失败。正确写法是https://taotoken.net/api/v1。改完config.yaml记得重启 api 容器:docker-compose restart memobase-server-api。
local proxy failed。这个报错通常出现在容器内访问外部 endpoint 时。原因可能是容器网络没配好,或者你在.env里设了HTTP_PROXY之类的环境变量但代理不可达。检查.env里有没有残留的 proxy 配置,有就删掉。另外确认 api 容器能解析外网域名,docker exec -it memobase-server-api /bin/bash进去curl https://taotoken.net/api/v1/models试一下。
reading choices 报错(类似KeyError: 'choices'或reading 'choices')。这说明模型返回的 JSON 结构里没有choices字段,通常是 endpoint 返回了错误信息而不是正常响应。八成是模型 ID 写错了,或者该模型在 TaoToken 上不可用。回到模型对话页确认模型 ID 拼写,再核对best_llm_model。也有可能是llm_style和实际返回格式不匹配,保持openai一般没问题。
OAuth 相关报错。如果你在配置里误开了某些需要 OAuth 的 provider 选项,会看到 token 获取失败的提示。memobase 用 API Key 模式就够了,不需要 OAuth。检查config.yaml里有没有多余的 auth 字段,删掉即可。
排查顺序建议:先看 api 容器日志docker-compose logs -f memobase-server-api,日志里会打印具体的 LLM 调用错误;再进 Redis 容器看锁和缓存状态:
docker exec -it memobase-server-redis /bin/bash redis-cli AUTH helloworld keys *你会看到memobase_telemetry::__root__::llm_input_tokens::2025-04这类键,说明 LLM 调用确实发生了。如果只有insert_blob_request没有insert_blob_success_request,说明写入成功但处理失败,问题在模型通道。
进 Postgres 容器核对数据:
docker exec -it memobase-server-db /bin/bash psql -U memobase -d memobase \dt SELECT * FROM user_profile LIMIT 10;表里有数据,说明画像落库成功。表是空的,回到模型通道排查。
提示:每次改完
config.yaml或.env,都要重启对应容器,配置不会热加载。
6. 把模型通道统一到 TaoToken:长期维护与 CTA
跑通之后,你会发现 memobase 的画像质量高度依赖模型通道的稳定性。把 endpoint 统一到 TaoToken 的好处是:一个 Key 管所有模型调用,换模型只改best_llm_model一行,不用动 provider 适配代码。对于长期运行的画像系统,这能省掉大量维护成本。
如果你要做的是长期编码或 Agent 场景,建议直接上 Coding Plan:https://taotoken.net/coding-plan ,它和 memobase 共用同一套 Key,配置逻辑一致,省得再开一套鉴权。
日常排障和接入细节,收藏这两个入口:API Keys 管理在 https://taotoken.net/api-keys ,接入文档在 https://taotoken.net/doc 。模型效果对比去模型对话页 https://taotoken.net/models 实测。
最后说个实用技巧:memobase 的 BufferZone 参数可以在配置里调。如果你的场景对话频率高,把最大 token 阈值调小一点,让 flush 更频繁,画像更新更及时;如果追求省 token,就调大阈值,攒一批再处理。这个权衡没有标准答案,取决于你的业务对画像实时性的要求。跑通链路之后,先观察几天 Redis 里的 telemetry 键,看看 token 消耗和处理频率,再决定怎么调。