零框架也能 24/7:拆解 724-office 的三层记忆、热加载工具与 Docker 多租户
说明:微信源页触发验证码,无法直读原文。本文按题意,并基于开源仓库
wangziqi06/724-office的 README、模块源码与config.example.json做工程向改写;版本口径以当前仓库为准(约 1 万行 / 36 工具,早期宣传常见「3500 行 / 26 工具」)。
很多人一提到「能 24/7 跑的 Agent」,第一反应是再叠一层 LangChain / CrewAI / AutoGen。结果呢?抽象层比业务还厚,出了问题只能在框架黑盒里猜。开源项目 724-office(7/24 Office) 走了另一条路:零框架依赖,标准库 + 少量小包,把 Tool Use、三层记忆、定时任务、MCP、多租户 Docker 路由写进一堆可读的 .py 文件里,挂在消息平台 Webhook 上日夜跑。
本地已有不少「给 Claude Code 装 Skill / 桌面 Agent」的文章;本文换切面:不讲提示词玄学,只拆这套 harness 里真正决定稳定性的几块硬骨头——记忆怎么编译、工具怎么熔断、Nudge 怎么纠偏、多租户怎么隔离。

一、它到底是什么:从「3500 行」到可演进的模块化 Agent
仓库自述很直白:生产在跑的个人/多用户 Agent,不绑 LangChain、LlamaIndex、CrewAI。早期版本常被概括为「约 3500 行、26 工具、8 个文件」;当前主干已演进到约 1 万行、36 工具、按域拆分的工具模块,并保留后续 Node 重写分支 xiaowang-v2/。
核心入口与职责可以压成一张表:
| 模块 | 大约职责 |
|---|---|
xiaowang.py |
HTTP 入口、回调、防抖、ASR、群聊门控 |
llm.py |
OpenAI 兼容 Tool Use 循环、预算感知系统提示、Nudge 接入 |
tools_*.py |
消息 / 管理 / 搜索 / 视频 / 页面 / AI Mirror 等域工具 |
memory.py |
会话 + 压缩事实 + LanceDB 向量召回 |
scheduler.py |
Cron / 一次性任务 + 休眠用户跳过 |
router.py |
多租户 Docker 自动开通与对账 |
mcp_client.py |
JSON-RPC MCP(stdio / HTTP)热重载 |
nudge.py |
「有工具却没用」时的结构纠偏 |
依赖也很克制:croniter、lancedb、websocket-client,以及媒体/HTTP 等可选包。设计目标之一是 边缘可部署(文档提到 Jetson Orin Nano、内存预算约 2GB 量级),这和「再装一个重型 Agent 框架」不是同一条赛道。
二、三层记忆:别再把整段聊天史当知识库
724-office 的记忆不是「把对话全塞进 context」。源码注释把它写成三段流水线:
1. 压缩(Compress):溢出的会话交给 LLM,抽出结构化事实(关键信息、人物、时间、关键词)
2. 去重(Dedup):新事实与旧向量做余弦相似;阈值默认约 0.92,过高则跳过
3. 召回(Retrieve):用户消息 → embedding → LanceDB Top-K → 注入系统提示(并做 token 预算跟踪)

对照工程语义:
| 层 | 形态 | 谁写谁读 |
|---|---|---|
| 会话层 | 每会话最近约 40 条 JSON | 即时对话读写;过大触发压缩/归档 |
| 压缩层 | LLM 抽出的长期事实 | Agent 写、检索时读 |
| 向量层 | LanceDB 表(可按 user 分表) | 检索注入 system prompt |
这和「每次提问都从 raw 文档重新 RAG」不同:知识被 编译进可维护的记忆条目,再按需召回。代价也很清楚——你必须配 memory.embedding_api,并接受压缩本身会消耗模型调用。关了 memory,系统仍可跑,只是长期上下文会退化成「会话窗口内能装多少算多少」。
边界:压缩是有损的;阈值过高会漏记,过低会记重复。生产上建议先盯
retrieve_top_k与日志里的注入长度,再调阈值。
三、工具注册、上下文画像与熔断:先把 Token 和失控按住
工具不是「全量塞给模型」。tools_base.py 用装饰器注册 OpenAI function calling 定义,并按 上下文画像 过滤:
| 画像 | 典型剔除 | 意图 |
|---|---|---|
voice |
视频剪辑、审计、热加载工具、部分诊断 | 语音通道省上下文 |
scheduler |
schedule 自身 + 热加载等 |
防止定时任务套娃建定时任务 |
group |
exec / edit_file、热加载、深度诊断 |
群聊降权 |
default |
全量(保守起点) | 私聊/管理场景 |
执行侧还有 连续失败熔断:同一工具连续失败达到阈值(默认 3)后直接返回错误,避免模型在坏工具上死循环烧 Token。这比「在提示词里写请不要重复失败」可靠得多。
内置能力覆盖面很宽(当前 README 口径 36 个),大致包括:
- 核心:
exec、message - 文件:读写改列
- 日程:创建 / 列表 / 删除
- 媒体发送:图/文件/视频/链接/位置/名片
- 视频:剪辑、BGM、生成
- 搜索:多引擎 Web、附近 POI、记忆检索
- 可视化:
render_page(ECharts 线/柱/饼/雷达/表/报告) - AI Mirror:
soul_report、future_self - 插件:
create_tool/ 列表 / 删除,以及reload_mcp
create_tool 是双刃剑:Agent 可以在运行时写 Python 并热加载。这是「自演进」卖点,也是最大攻击面——务必限制 owner、审计目录权限,并默认在群聊画像里关掉。
四、Nudge:别再用更长 Prompt 修补「嘴上答应、手上不调工具」
nudge.py 的定位写得很硬核:不要靠提示词约束行为,用结构让错误难以发生。 在 Tool Use 循环末尾检测一批规则,例如:
- 调了
search_nearby却没send_location - 回复里说了「已记下 / noted」却没
write_file - 嘴上说安排了提醒却没调
schedule
命中后注入一条 hint,让模型 再跑一轮(并限制每会话触发次数,防死循环)。这和「把 system prompt 加到 8K」是两种哲学:前者改 harness,后者继续堆词。

同文件还强调:规则可注册、可计数。你完全可以按自家业务加「说了已发邮件却没调发送工具」一类检查。
五、部署与多租户:Webhook + Docker 路由
最小路径很朴素:
git clone https://github.com/wangziqi06/724-office.git
cd 724-office
cp config.example.json config.json
# 填入 models / messaging / memory 等占位字段(勿提交真实密钥)
pip install croniter lancedb websocket-client pilk numpy httpx beautifulsoup4 pydub jieba fpdf2
mkdir -p workspace/memory workspace/files
python3 xiaowang.py
进程默认起在 8080,把消息平台回调指过去即可。config.example.json 里能看到:多模型 fallback、ASR、视频 API、Tavily/Bocha、MCP stdio 示例(如 Playwright / filesystem)。
多用户场景走 router.py:一用户一容器、健康检查、启动时对账重建缺失容器。这比「一个进程里用 user_id 字段硬隔离」更重,但数据面更干净——也更吃运维。单人自用可以直接跑 xiaowang.py,不必一上来就上 Docker 路由。

六、和常见方案怎么选
| 维度 | 724-office | LangChain 类框架 Agent | Claude Code / 桌面 Coding Agent |
|---|---|---|---|
| 依赖 | 近零框架 | 重抽象栈 | 编辑器/CLI 生态 |
| 主场景 | IM 常驻助理、日程、媒体、自检 | 应用内编排 | 写代码、改仓库 |
| 记忆 | 自研三层 + LanceDB | 插件化各异 | 项目记忆 / 会话压缩 |
| 扩展 | @tool + create_tool + MCP |
Chain/Tool 抽象 | Skill / MCP / Hooks |
| 风险面 | 热加载与 exec |
供应链与版本漂移 | 本机权限与密钥 |
一句话:你要的是「挂在聊天软件上的 24/7 个人助理」,724-office 值得拆;你要的是「在仓库里改代码的 Coding Agent」,它不是替代品。
七、排坑清单(写给准备上生产的人)
1. 密钥:config.json 必须进 .gitignore;文章与仓库只用 YOUR_API_KEY_HERE 占位。
2. 群聊:默认已收紧工具集;不要为了「更聪明」把 exec 重新打开给所有群。
3. 定时任务:scheduler 画像故意去掉建日程工具,就是为了防套娃;改过滤表前先想清楚失败模式。
4. 记忆开关:没 embedding Key 就别开 memory,否则初始化会直接 disable。
5. 版本口径:对外介绍时写清「当前主干约 10k 行 / 36 工具」,避免和早期「3500 行」宣传混读导致预期错位。
6. 后继:仓库已出现 xiaowang-v2(Node + SQLite WAL)方向,选型时确认你跟的是 Python 主干还是 v2。
八、小结
724-office 的价值不在「又一个 Agent 壳」,而在于它把 24/7 常驻 需要的几件实事写进了可审计的代码:记忆先编译再召回、工具按画像裁剪、失败熔断、Nudge 结构纠偏、可选 Docker 多租户。零框架不是复古,是把复杂度留在你能 grep 到的地方。
如果你正在被框架抽象淹没,又不想放弃消息端常驻助理,把这个仓库当 harness 参考实现 读一遍,收获会大于再抄一份「万能 Agent 提示词」。
项目地址:https://github.com/wangziqi06/724-office
💻 配套实训环境与动手练习
本文涉及的相关技术指令、开发环境与工具链已内置在边学边练在线实验室中,无需繁琐安装配置,随时在浏览器中实践体验:
