这个项目解决了什么问题?
想象你有一个超级聪明的助手,但他每天早上醒来都会失忆。你昨天告诉他你喜欢咖啡不加糖,今天他又问了一遍。你让他帮你写一个项目的代码,明天他完全不记得昨天写到了哪里。这就是当前大多数 AI 助手的现状------金鱼记忆。
更糟糕的是,你只能和这一个助手对话。如果你需要一个写代码的、一个做设计的、一个写文案的,你只能在一个助手身上来回切换角色,就像让一个人同时扮演厨师、服务员和收银员------忙得不可开交,还容易出错。
DS Bot 解决的就是这两个根本问题:让 AI 拥有持续的记忆,让多个 AI 像团队一样协作。

它不是又一个聊天机器人框架,也不是一个 Agent 编排工具。它是一个 DeepSeek Harness 插件,直接运行在你本地的开发环境里,把单个 AI 助手变成一支有记忆、有角色、有协作能力的团队。
从第一性原理来看,DS Bot 做的事情其实很简单:给每个 AI 一个持久的身份和一个共享的工作空间。但正是这个简单的设计决策,带来了一系列有趣的架构选择。
与 Grok Bot 的对比:后来者的技术突围
提到多 Agent 协作,很多人会想到 Grok Bot。Grok 作为 xAI 的旗舰产品,在多 Agent 领域确实走得比较早。但 DS Bot 作为后来者,不仅实现了相同的效果,还在某些方面做得更好。
Grok Bot 的做法:
- 基于云端的 Agent 编排,依赖 xAI 的服务器
- Agent 之间通过中央控制器协调
- 记忆存储在云端,用户无法直接访问
- 需要网络连接,无法离线使用
DS Bot 的不同选择:
- 本地优先:所有数据存储在本地,无需联网,隐私安全
- 去中心化协作:没有中央控制器,Bot 之间直接通信
- 透明记忆:记忆以 Markdown 文件形式存储,用户可以直接查看和编辑
- 插件架构:作为 DeepSeek Harness 的插件,复用已有的基础设施,而不是重新造轮子
从第一性原理看:Grok Bot 像是一个"全栈解决方案",什么都自己做;而 DS Bot 更像是一个"乐高积木",专注于核心能力,其他部分复用现有基础设施。这两种设计哲学各有优劣,但 DS Bot 的本地优先和透明记忆设计,对于注重隐私和可控性的用户来说,显然更有吸引力。
技术深度对比:
| 特性 | Grok Bot | DS Bot |
|---|---|---|
| 架构模式 | 云端集中式 | 本地插件式 |
| 记忆存储 | 云端数据库 | 本地 Markdown 文件 |
| 协作方式 | 中央控制器编排 | 去中心化轮次制 |
| 上下文管理 | 自动压缩 | Context Steward 智能决策 |
| 隐私保护 | 依赖云端安全 | 本地存储,完全可控 |
| 可扩展性 | 受限于平台 | 插件架构,高度可扩展 |
| 离线支持 | 不支持 | 完全支持 |
DS Bot 的独特优势:
-
Context Steward 的智能决策:Grok Bot 的上下文管理是自动压缩,而 DS Bot 的 Context Steward 会判断工作是否完成,决定是压缩还是切换。这种细粒度的控制让长对话更加自然。
-
三层记忆系统:Grok Bot 的记忆是扁平的,所有信息混在一起。DS Bot 的三层记忆(Bot 记忆、群聊记忆、团队记忆)更符合人类的记忆结构,也更易于管理。
-
轮次制群聊:Grok Bot 的协作依赖中央控制器,而 DS Bot 的轮次制群聊让 Bot 像人一样自然对话,不需要一个"导演"在背后指挥。
-
透明可编辑:DS Bot 的所有状态都存储在可读的 JSON 和 Markdown 文件中,用户可以随时查看、编辑、备份。这种透明性是云端方案无法提供的。
从第一性原理看 :DS Bot 的成功证明了一个道理------后来者不需要模仿先行者的每一个设计。通过重新思考基本问题("AI 应该如何记忆?"、"多个 AI 应该如何协作?"),DS Bot 找到了一条不同的路,而且走得很好。
整体架构:像搭积木一样组装功能
DS Bot 的架构可以用一个词概括:模块化。
整个插件由 33 个独立的 Host 模块和 76 个 Client 模块组成,每个模块只做一件事,通过一个共享的 rt(runtime)对象互相通信。这种设计让我想起了乐高积木------每一块都很简单,但组合在一起就能构建出复杂的结构。

入口文件 index.js 就像一份装配说明书。它按照精心设计的顺序安装每个模块:先是基础设施(诊断、存储、模型),再是核心逻辑(轮次、交付、团队名册),最后是上层功能(记忆、浏览器、用量统计)。这个顺序不是随意的------后面的模块依赖前面的模块,就像盖房子要先打地基再砌墙。
javascript
// index.js 的模块安装顺序
const MODULES = [
diagnostics, store, models, providers, permissions,
turns, handoffs, delivery, roster, folders, agents,
prompt, timeContext, tools, chatIndex, groups,
approvals, resume, memory, parts, images, secrets,
connectors, capabilities, schedules, browser, usage,
update, dshUpdate, thinking, feed, channel
]
每个模块通过 install(rt) 函数注册自己的监听器、工具和副作用。模块之间不直接调用,而是通过 rt 对象暴露的接口通信。这种设计的好处是:你可以单独理解任何一个模块,而不需要知道其他模块的存在。

创新点一:长寿命 Bot------不是临时工,是正式员工
大多数 AI Agent 框架把 Agent 当作临时工:创建一个 Agent,给它一个任务,完成后就销毁。这种模式适合一次性任务,但对于需要持续性的工作------比如一个长期项目的开发、一个持续运行的监控------它就像每天换一个新员工,交接成本极高。
DS Bot 的设计完全不同:每个 Bot 就是一个持久的 dsh Session。
这意味着:
- 每个 Bot 有自己的名字、角色、指令、模型选择
- 每个 Bot 可以有自己的工作目录,独立于团队工作区
- 每个 Bot 有自己的权限预设(只读 / 工作区 / 完全访问)
- 每个 Bot 有自己的记忆,跨所有对话持续存在
这就像公司里的正式员工:有工牌(名字)、有岗位职责(角色和指令)、有自己的工位(工作目录)、有门禁权限(权限预设)、有笔记本(记忆)。
从第一性原理看:为什么选择 Session 而不是更轻量的 Agent?因为 Session 已经提供了持久化、上下文管理、工具注册等基础设施。复用这些基础设施,而不是重新发明轮子,是 DS Bot 架构的核心哲学。
实际场景对比
想象你正在开发一个大型项目。使用临时 Agent 模式,你需要:
- 创建 Agent,告诉它项目背景
- 让它写代码,完成后 Agent 销毁
- 第二天创建新 Agent,重新告诉它项目背景
- 它问:"昨天写到哪里了?用了什么技术栈?"
- 你不得不重新解释一遍
使用 DS Bot 的长寿命模式:
- 创建 Developer Bot,告诉它项目背景
- 它写代码,记住技术选型、架构决策、已完成的功能
- 第二天你继续对话,它说:"昨天我们完成了用户认证模块,今天继续写 API 层?"
- 它甚至记得你偏好 TypeScript 而不是 JavaScript,记得数据库用 PostgreSQL
这就是"正式员工"和"临时工"的区别。长期来看,长寿命 Bot 的交接成本几乎为零,而临时 Agent 每次都要重新建立上下文。
与 Grok Bot 的对比
Grok Bot 也支持持久化的 Agent,但它的实现方式不同:
- Grok:Agent 状态存储在云端,依赖 xAI 的服务器
- DS Bot :每个 Bot 是一个本地 Session,状态存储在
state.json和 Session 日志中
DS Bot 的优势在于:
- 完全本地化:数据不离开你的电脑,隐私安全
- 可备份迁移 :直接复制
~/.dsh/bot/文件夹即可备份整个团队 - 可调试:JSON 文件可以直接打开查看,不需要专门的工具
技术实现 :DS Bot 的 roster.js 模块负责管理 Bot 的生命周期。它通过 ctx.sessionController.create() 创建 Session,并通过 ctx.sessionTitle.rename() 设置标题。每个 Bot 的配置(名字、角色、指令、模型)都存储在 state.json 中,结构清晰:
json
{
"bots": {
"bot-1": {
"name": "Developer",
"role": "Software Engineer",
"instructions": "You are a senior developer...",
"model": "deepseek-coder",
"sessionId": "sess-abc123"
}
}
}
这种设计让 DS Bot 的 Bot 管理既简单又强大。
创新点二:Context Steward------一个聪明的"图书馆管理员"
这是 DS Bot 最精巧的设计之一。
每个 AI 模型都有一个上下文窗口限制------比如 128K tokens。当对话越来越长,迟早会触及这个限制。传统的解决方案是"压缩":把旧消息总结成一段摘要,腾出空间。但压缩会丢失细节,而且你无法预测什么时候该压缩、什么时候该切换到新话题。
DS Bot 的解决方案是引入一个 Context Steward(上下文管家)。

这个管家的工作方式就像一个经验丰富的图书馆管理员:
- 监控书架空间:当对话达到模型窗口的 80%(检查线),管家被唤醒
- 判断工作状态:管家读取最新消息,问自己一个问题------"工作完成了吗?"
- 两种处理方式 :
- 工作还在继续 → "compact":原地压缩旧消息为 checkpoint,保留最近的消息原文,对话继续
- 工作到了停歇点 → "switch":写一份交接笔记(handoff note),开启一个全新的 Session
关键的设计洞察是:管家是一个独立的小模型调用,它不参与 Bot 的主对话,只做一件事------判断该压缩还是该切换。这种关注点分离让主对话保持纯净,也让管家的判断更准确。
从用户视角看,这一切都是透明的。无论内部发生了什么,你看到的始终是一个连续的对话,没有任何标记或中断。就像你在笔记本上写字,写满一页就翻到下一页,但页码是连续的。
类比:想象你在写一封很长的信。当你快写完一页纸时,一个聪明的助手会看你写的内容,判断你是写完了这一段还是正在中间。如果写完了,他给你一张新纸,并在开头写上"接续上一段的内容";如果没写完,他把前面写过的内容压缩成几行摘要,让你继续写。无论如何,你感觉自己在用一本无限长的信纸。
技术实现细节
Context Steward 的实现非常精巧。它使用一个独立的小模型调用(通常是最便宜的模型),只传入最近的消息(约 6K tokens),然后返回一个 JSON 决策:
json
{"action": "compact", "reason": "User is still working on the API integration"}
或者:
json
{"action": "switch", "reason": "Previous task completed, waiting for new instructions"}
管家会检查几个关键信号:
- 用户最近的请求是否已经被完全处理
- Bot 是否承诺了要做但还没做的事情
- 对话是否处于等待状态(等待用户输入或等待工具执行)
- 这轮对话已经被压缩过几次(压缩次数越多,越倾向于切换)
这种设计的好处是:主 Bot 完全不知道管家的存在。它只看到一个连续的对话,感觉自己一直在同一个笔记本上工作。但实际上,它可能已经用了好几个 Session,每个 Session 的开头都有一份精心准备的交接笔记。
与 Grok Bot 的对比
Grok Bot 的上下文管理是"自动压缩":当对话超过一定长度,自动把旧消息总结成摘要。这种方式简单粗暴,但有个问题:它不知道工作是否完成,可能会在关键时刻压缩掉重要信息。
DS Bot 的 Context Steward 更智能:
- Grok:固定阈值触发压缩,不判断工作状态
- DS Bot:检查线触发管家,管家判断工作状态后决定压缩还是切换
技术实现 :DS Bot 的 steward.js 模块实现了 Context Steward。核心逻辑:
-
检查线计算:
javascriptexport function linesFor({ window, reserve, checkRatio }) { const usable = Math.max(declared - room, Math.floor(declared / 2)) const hard = Math.floor(usable * 0.95) // 硬线 95% const check = Math.min(Math.floor(usable * checkRatio), hard) // 检查线 80% return { window: declared, usable, hard, check } } -
管家决策:使用一个独立的小模型调用,传入最近的消息(约 6K tokens),返回 JSON 决策
-
两种动作:
- compact:原地压缩旧消息为 checkpoint,保留最近消息原文
- switch:写 handoff note,开启新 Session,注入 handoff package
-
交接笔记:Bot 在空闲时写交接笔记,使用相同的 prefix,让 provider 的 prompt cache 命中,无需等待
这种设计让长对话既高效又自然,用户完全感知不到内部的复杂性。
创新点三:群聊系统------像真实团队一样协作
如果你用过 Slack 或微信群,你就知道群聊的价值:信息透明、实时同步、自然协作。但大多数多 Agent 系统把"协作"做成了"编排"------一个中央控制器指挥每个 Agent 做什么,像木偶戏一样。
DS Bot 的群聊系统走了一条不同的路:让 Bot 像人一样在群里聊天。

核心设计:
轮次制发言
群聊是一个有序的对话流。成员按顺序发言,每次一个。这避免了多人同时说话导致的混乱------想象一下如果微信群里所有人同时说话会怎样。
@提及机制
一条消息可以 @Name 指定下一个发言者。这就像在会议上说"小王,你怎么看?"------自然、直观。
独立隐藏 Session
每个 Bot 在群聊中有自己独立的隐藏 Session。这意味着:
- 群聊不会污染 Bot 的私聊上下文
- 每个 Bot 只看到群聊中它需要的信息
- 多个群聊互不干扰
两种模式
- everyone 模式:每条消息所有成员都回复,管理员先说
- admin 模式:普通消息只给管理员,管理员通过 @Name 决定谁参与
防循环机制
Bot 之间互相调用会计入 relay limit。如果 Bot 们互相调用太多次(默认是成员数的 3 倍),群聊会暂停,等待用户介入。这防止了 Bot 之间陷入无限循环------就像会议主持人发现讨论跑题了,会说"我们先停一下"。
从第一性原理看:为什么用轮次制而不是并发的消息传递?因为对话本质上是有序的。人类对话也是轮流说话的,这不是技术限制,而是沟通的基本规律。
与 Grok Bot 的对比
Grok Bot 的多 Agent 协作采用的是"中央控制器"模式:一个主 Agent 负责分配任务给其他 Agent,然后收集结果。这种模式效率高,但不够自然------就像有一个导演在背后指挥每个演员说什么。
DS Bot 的群聊系统完全不同:
- Grok:中央控制器 → Agent A → Agent B → Agent C(星型拓扑)
- DS Bot:Agent A ↔ Agent B ↔ Agent C(网状拓扑,通过群聊)
DS Bot 的优势:
- 更自然:Bot 之间可以直接对话,不需要经过中央控制器
- 更灵活:任何 Bot 都可以发起对话,不限于"主 Agent"
- 更透明:所有对话都在群聊中可见,没有"黑箱"操作
技术实现 :DS Bot 的 groups.js 模块实现了轮次制群聊。核心逻辑是:
- 每个群聊维护一个
log数组,记录所有消息 - 每个成员有一个
seen标记,记录它上次看到的消息序号 - 当一个成员发言时,它会看到所有
seq > seen的消息 @Name机制通过正则表达式解析,决定下一个发言者
javascript
// groups.js 中的核心逻辑
const unseenLines = (room, memberId) => {
const since = room.seen[memberId]
if (since === undefined) return room.log.slice(-ROOM_FIRST_LOOK)
return room.log.filter(line => line.seq > since && line.botId !== memberId)
}
这种设计让群聊既高效又自然,每个 Bot 只看到它需要的信息,不会被打扰。
创新点四:三层记忆系统------像人类一样记住事情
人类的记忆是分层的:你记得自己的喜好(个人记忆),记得团队会议的结论(群组记忆),也记得公司的政策(组织记忆)。DS Bot 的记忆系统模仿了这种分层结构。


第一层:Bot 自己的记忆
每个 Bot 维护自己的 MEMORY.md 和主题文件。这就像员工的个人笔记本------记录着用户偏好、项目决策、技术细节。无论 Bot 在哪个对话中,这些记忆都可用。
第二层:群聊记忆
每个群聊有自己的记忆空间,只有该群聊的成员能读到。这就像会议室里的白板------讨论的内容只对这个团队有意义。一个 Bot 在群聊 A 中记住的东西,不会出现在它和群聊 B 的对话中。
第三层:团队记忆
所有 Bot 共享的记忆。这就像公司公告栏------所有人都能看到。通常由 Main Bot(管理员)维护,记录团队级别的决策和约定。
自动记忆审查
最巧妙的设计是记忆审查机制 :每轮对话结束后,一个独立的模型调用会审查对话内容,自动提取值得记住的信息,更新记忆文件。Bot 不需要主动调用 remember 工具------记忆是自动发生的。
这就像人类的记忆:你不需要刻意去"记住"今天吃了什么午饭,大脑会自动处理。只有重要的、需要长期保留的信息才会进入持久记忆。
安全设计:记忆系统会拒绝保存看起来像密钥、密码或 ID 号的内容。记忆是数据,不是指令------这是 DS Bot 的安全底线。
与 Grok Bot 的对比
Grok Bot 也有记忆功能,但实现方式截然不同:
- Grok:记忆存储在云端数据库,用户无法直接访问
- DS Bot:记忆以 Markdown 文件形式存储在本地,用户可以直接查看和编辑
DS Bot 的三层记忆是 Grok 没有的:
- Grok 的记忆是扁平的,所有信息混在一起
- DS Bot 的记忆是分层的:个人记忆、群组记忆、团队记忆
技术实现 :DS Bot 的 memory.js 模块实现了完整的记忆系统。核心设计:
-
文件格式:使用 Agent Memory Repo 格式的 Markdown
markdown# Memory ## Index - [[project-decisions]] - [[user-preferences]] ## Entries - User prefers TypeScript over JavaScript [source: part 2 #1234; added: 2026-10-27] - Database choice: PostgreSQL [source: part 3 #2345; added: 2026-10-28] -
自动审查 :每轮对话后,
memoryReview()函数会调用一个小模型,审查对话内容,自动提取值得记住的信息 -
变更日志 :
journal.jsonl记录每次变更,包括变更前后的内容,支持回溯 -
大小限制:
- 每条记忆 ≤ 300 字符
- MEMORY.md ≤ 4,000 字符
- 每个主题文件 ≤ 16,000 字符
- 最多 40 个主题文件
这种设计让记忆既强大又可控。用户可以直接打开 MEMORY.md 查看 Bot 记住了什么,甚至可以手动编辑。这种透明性是云端方案无法提供的。
创新点五:Bot 间消息传递------像邮件系统一样可靠
Bot 之间如何通信?DS Bot 设计了一个可靠的消息传递系统,类似于企业内部邮件系统。

同步与异步
- 同步请求:Bot A 发消息给 Bot B,等待回复后再继续。适合需要立即得到答案的场景。
- 异步消息:Bot A 发消息给 Bot B,不等待回复。Bot B 会在下一个 turn 开始时读取。适合通知类场景。
消息路由
delivery.js 是消息的路由中心。它处理:
- 消息来源(哪个 Bot 发的)
- 消息目标(发给哪个 Bot)
- 消息上下文(来自哪个群聊、哪个对话)
- 消息类型(请求、回复、群聊消息、系统通知)
延迟读取
如果 Bot B 正在处理一个任务,Bot A 的消息会进入 B 的 inbox。B 在当前任务完成后才会读取。这就像你正在写代码时收到一封邮件------你会先完成当前任务,然后再看邮件。
文件传递
消息可以携带文件附件。发送方的文件会被转换为只读路径,接收方的工具可以读取但不能修改。这保证了文件安全。
类比:想象一个办公室里的消息系统。你可以走到同事桌前等他回复(同步),也可以把便签贴在他电脑上(异步)。如果他正在开会,便签会留在那里,等他回来再处理。
创新点六:安全架构------多层防御
DS Bot 的安全设计遵循一个原则:最小权限 + 纵深防御。

权限层
每个 Bot 有独立的权限预设:
- Read only:只能读文件,不能修改
- Workspace:只能在工作区内操作
- Full access:完全访问(需要用户明确授权)
群聊可以覆盖成员的权限------比如让所有成员在群聊中只用 Read only 权限,即使他们各自的权限更高。
密钥层
当 Bot 需要 API 密钥时,它调用 request_secret,用户在卡片中输入密钥。Bot 永远看不到密钥的值 ------密钥直接进入 shell 环境变量 $DSH_SECRET_XXX。在发送给模型之前,所有密钥值都会被替换为 [secret:NAME]。
这就像给保镖一个保险箱密码:保镖只需要知道怎么打开保险箱,不需要知道密码本身。
记忆层
记忆系统会拒绝保存看起来像密钥、密码或 ID 号的内容。即使用户在对话中输入了 API 密钥,Bot 也不会把它存入记忆。
浏览器层
Bot 浏览器不会读取密码字段、信用卡字段或一次性验证码字段。这是硬编码的安全限制,无法通过指令覆盖。
从第一性原理看 :安全的本质是信任边界的管理。DS Bot 在每个可能的信任边界上都设置了检查点:用户与 Bot 之间、Bot 与文件系统之间、Bot 与网络之间、Bot 与记忆之间。
与 Grok Bot 的对比
Grok Bot 的安全模型是"信任云端":
- 数据存储在 xAI 的服务器,依赖云端安全
- 用户无法直接查看或编辑安全配置
- 密钥管理对用户不透明
DS Bot 的安全模型是"零信任 + 本地优先":
- 权限层:每个 Bot 独立的权限预设,群聊可覆盖
- 密钥层:Bot 永远看不到密钥值,通过环境变量注入
- 记忆层:拒绝保存敏感信息,自动检测密钥模式
- 浏览器层:硬编码安全限制,不读取密码字段
技术实现 :DS Bot 的 secrets.js 模块实现了密钥管理。核心设计:
- 密钥存储 :
secrets.json文件,权限 600,原子写入 - 密钥注入 :通过
$DSH_SECRET_XXX环境变量,Bot 无法直接读取 - 密钥脱敏 :发送给模型前,所有密钥值替换为
[secret:NAME] - 权限控制:每个密钥可以设置"仅这个 Bot"或"所有 Bot"使用
javascript
// secrets.js 中的脱敏逻辑
function maskSecrets(text, secrets) {
for (const [name, value] of Object.entries(secrets)) {
text = text.replaceAll(value, `[secret:${name}]`)
}
return text
}
这种设计让安全性完全可控,用户可以随时查看、修改、删除密钥,不需要依赖云端。
创新点七:Web Search Auto------智能降级
搜索是 AI 助手的基本能力,但不同模型提供商的搜索 API 差异很大。DS Bot 实现了一个智能的搜索降级链。

降级策略
- 模型自带搜索:如果当前模型路由支持搜索(如 Anthropic、OpenAI、Gemini),优先使用
- 公共搜索:如果模型不支持或调用失败,降级到 Bing 或 DuckDuckGo 的公共结果页
- 失败提示:如果所有方式都失败,明确告诉模型"搜索不可用,不要猜测 URL"
设计哲学
这种降级策略的核心思想是:永远给用户一个明确的结果,而不是让模型猜测。当搜索失败时,模型会被告知"搜索不可用",而不是拿到一堆错误的结果。
为什么这样设计?
传统 AI 助手的搜索往往是"全有或全无":要么成功返回结果,要么失败后模型开始编造 URL 或假装搜索成功。DS Bot 的做法更加务实:
-
透明性:每次搜索结果都会标注 "Search backend: ...",告诉你结果来自哪里。这就像新闻报道要注明消息来源一样,让用户可以判断结果的可靠性。
-
防御性:当所有搜索方式都失败时,明确告诉模型"不要猜测 URL"。这防止了模型产生幻觉,编造不存在的网址。
-
可扩展性 :通过
searchApis配置,可以轻松添加新的搜索 API 支持。这意味着当新的模型提供商推出搜索功能时,DS Bot 可以快速适配。
实际使用场景
想象你问 Bot:"帮我查一下最新的 React 19 新特性"。
场景 A:使用 DeepSeek 模型
- 降级链第一层:DeepSeek 自带搜索 API → 成功返回结果
- 结果标注:"Search backend: deepseek-official"
场景 B:使用本地 Ollama 模型
- 降级链第一层:Ollama 不支持搜索 → 跳过
- 降级链第二层:Bing 公共搜索 → 成功返回结果
- 结果标注:"Search backend: bing-public"
场景 C:网络故障
- 降级链第一层:模型搜索失败 → 跳过
- 降级链第二层:Bing 搜索失败 → 跳过
- 降级链第三层:返回失败提示
- 模型被告知:"搜索不可用,不要猜测 URL"
- Bot 会诚实地告诉你:"抱歉,现在无法搜索,但我可以根据已有知识回答..."
这种设计确保了无论遇到什么情况,用户都能得到一个明确的反馈,而不是被误导。
端到端数据流:一条消息的旅程
让我们跟踪一条消息从用户输入到 Bot 回复的完整路径。

- 用户输入 → 通过
channel.js的 POST API 进入系统 - 消息路由 →
delivery.js确定目标 Bot 和 Session - 轮次管理 →
turns.js记录轮次状态,检查是否有来自其他 Bot 的消息 - 上下文准备 →
prompt.js组装系统提示,注入记忆、时间上下文、群聊信息 - LLM 调用 → 通过 dsh 的 LLM 适配器调用模型
- 工具执行 → 如果模型调用工具,
tools.js路由到正确的处理器 - 回复交付 →
delivery.js将回复发送回用户或其他 Bot - 后处理 → 记忆审查、上下文检查、用量统计
整个过程就像一条精心设计的流水线,每个环节都有明确的职责和接口。
关键设计决策
在这条数据流中,有几个值得注意的设计决策:
1. 消息头注入
当消息从一个 Bot 发送到另一个 Bot 时,delivery.js 会自动添加消息头,告诉接收方这条消息的来源和上下文。例如:
[Message from Developer · for the work Chief asked you for]
这就像邮件的主题行,让接收方一眼就知道这条消息的目的。
2. 工具结果路由
当 Bot 调用工具(如执行 bash 命令或读取文件)时,工具结果会直接返回给调用方,不会经过 delivery.js。这减少了不必要的消息传递开销。
3. 群聊消息的特殊处理
群聊消息会同时发送给所有成员,但每个成员收到的是"自上次发言以来的新消息",而不是完整的群聊历史。这避免了重复传递,也保证了每个 Bot 只看到它需要的信息。
4. 延迟消息
如果目标 Bot 正在执行一个长任务,新消息会进入它的 inbox,等当前任务完成后才会被读取。这种设计避免了中断正在进行的工作,也保证了消息不会丢失。
实际应用场景
DS Bot 的设计不是纸上谈兵,它已经在多个实际场景中证明了价值。
场景一:长期项目开发
你有一个持续三个月的开发项目。使用 DS Bot,你可以:
- 创建一个 Developer Bot,它记住整个项目的架构、技术栈、已完成的功能
- 创建一个 Reviewer Bot,它记住代码规范、审查标准、常见问题
- 创建一个群聊"项目开发",让两个 Bot 协作完成开发任务
- 三个月后,Bot 仍然记得所有的决策和上下文,无需重新解释
场景二:多角色协作
你需要完成一个复杂任务,需要多个角色:
- Chief Bot:项目经理,负责分解任务、协调进度
- Developer Bot:程序员,负责写代码
- Designer Bot:设计师,负责 UI 设计
- Tester Bot:测试员,负责写测试用例
通过群聊,这些 Bot 可以自然地协作:Chief 分配任务,Developer 写代码,Designer 提供设计稿,Tester 写测试。整个过程就像真实的团队会议,而不是机械的任务分配。
场景三:知识管理
你有一个团队,需要共享知识:
- 团队记忆存储所有成员的决策和约定
- 每个 Bot 的记忆存储个人的专业知识和经验
- 群聊记忆存储特定项目的讨论结论
当新成员加入时,它可以快速读取团队记忆,了解历史决策,而不是从零开始。
场景四:持续监控
你需要监控一个长期运行的系统:
- 创建一个 Monitor Bot,它记住系统的正常状态、历史问题、解决方案
- 它会定期检查系统状态,发现问题时主动通知你
- 它会记住过去的问题和解决方案,下次遇到类似问题时快速定位
这种持续性的监控是临时 Agent 无法做到的,因为临时 Agent 每次都要重新建立上下文。
DS Bot vs Grok Bot:后来者的技术突围
在前面各个章节中,我们已经零散地对比了 DS Bot 和 Grok Bot 的设计差异。现在让我们从整体上做一个全面的对比。
设计哲学的根本差异
Grok Bot:云端优先,全栈解决方案
- 所有功能自己实现,不依赖外部系统
- 数据存储在云端,用户通过 API 访问
- 强调易用性和开箱即用
DS Bot:本地优先,插件化架构
- 作为 DeepSeek Harness 的插件,复用已有基础设施
- 数据存储在本地,用户完全控制
- 强调可控性和可扩展性
核心技术对比
| 技术维度 | Grok Bot | DS Bot | DS Bot 的优势 |
|---|---|---|---|
| 上下文管理 | 自动压缩 | Context Steward 智能决策 | 判断工作状态,决定压缩还是切换 |
| 记忆系统 | 扁平云端存储 | 三层本地 Markdown | 分层管理,透明可编辑 |
| 多 Agent 协作 | 中央控制器编排 | 轮次制群聊 | 去中心化,更自然灵活 |
| 消息传递 | 云端消息队列 | 本地 inbox + 延迟读取 | 完全本地,无网络依赖 |
| 安全模型 | 信任云端 | 零信任 + 本地优先 | 密钥不离开本地,完全可控 |
| 存储格式 | 专有数据库 | JSON + Markdown + SQLite | 可读可编辑,易于调试 |
| 扩展性 | 受限于平台 | 插件架构 | 可自定义模块和工具 |
为什么 DS Bot 能后来居上?
1. 站在巨人的肩膀上
DS Bot 没有重新发明轮子。它复用了 DeepSeek Harness 的 Session、LLM、Tools、Workspace 等基础设施,专注于解决"持久身份"和"协作通信"两个核心问题。这种设计哲学让它可以用更少的代码实现更强大的功能。
2. 本地优先的架构优势
在隐私和安全越来越重要的今天,DS Bot 的本地优先架构是一个巨大的优势:
- 数据不离开用户的电脑
- 可以完全离线使用
- 用户可以随时查看、编辑、备份所有数据
- 不依赖任何云服务
3. 透明可编辑的设计
DS Bot 的所有状态都存储在可读的文本文件中:
state.json:团队状态MEMORY.md:记忆内容journal.jsonl:变更日志- Session 日志:完整对话记录
用户可以随时打开这些文件,查看系统在做什么,甚至可以手动修改。这种透明性建立了信任,也让调试变得简单。
4. 模块化的可扩展性
DS Bot 的 33 个 Host 模块和 76 个 Client 模块都是独立的,可以通过插件机制添加新功能。这种设计让它比 Grok Bot 更灵活,可以根据用户需求定制。
技术深度对比
Context Steward vs 自动压缩
Grok Bot 的上下文管理是简单的阈值触发:当对话超过一定长度,自动压缩。这种方式的问题是:
- 不知道工作是否完成
- 可能在关键时刻压缩掉重要信息
- 用户无法控制压缩时机
DS Bot 的 Context Steward 是一个独立的小模型调用,它会:
- 读取最近的消息(约 6K tokens)
- 判断工作是否完成
- 决定是压缩(compact)还是切换(switch)
- 如果切换,写一份交接笔记(handoff note)
这种设计让长对话更加自然,用户完全感知不到内部的复杂性。
三层记忆 vs 扁平记忆
Grok Bot 的记忆是扁平的,所有信息混在一起。DS Bot 的三层记忆:
- Bot 记忆:个人笔记本,跨所有对话
- 群聊记忆:会议室白板,只在群聊中可见
- 团队记忆:公司公告栏,所有 Bot 共享
这种分层设计更符合人类的记忆结构,也更易于管理。
轮次制群聊 vs 中央控制器
Grok Bot 的多 Agent 协作依赖中央控制器,一个主 Agent 分配任务给其他 Agent。DS Bot 的轮次制群聊:
- 没有中央控制器
- Bot 之间直接对话
- 通过 @Name 机制指定下一个发言者
- 每个 Bot 有独立的隐藏 Session
这种设计让协作更自然,就像真实的团队会议。
适用场景对比
Grok Bot 适合:
- 快速原型开发
- 不需要关注隐私的场景
- 希望开箱即用的用户
DS Bot 适合:
- 注重隐私和安全的场景
- 需要长期运行的项目
- 需要高度定制的用户
- 希望完全控制数据的用户
- 离线工作环境
从第一性原理看
DS Bot 的成功证明了一个道理:后来者不需要模仿先行者的每一个设计。通过重新思考基本问题:
- "AI 应该如何记忆?" → 三层 Markdown 记忆
- "多个 AI 应该如何协作?" → 轮次制群聊
- "上下文应该如何管理?" → Context Steward 智能决策
- "安全应该如何保障?" → 零信任 + 本地优先
DS Bot 找到了一条不同的路,而且走得很好。它不是 Grok Bot 的复制品,而是一个有自己特色的创新产品。
动态效果展示
群聊轮次动态演示
在这个 GIF 中,你可以看到一个群聊中三个 Bot 的协作过程:用户提出问题,Admin Bot 分析后 @Developer Bot 编写代码,Developer Bot 完成后 @Reviewer Bot 审查代码。整个过程自然流畅,就像真实的团队协作。

上下文压缩动态演示
这个 GIF 展示了 Context Steward 的工作过程:随着对话增长,达到检查线后,管家判断工作仍在进行,将旧消息压缩为 checkpoint,对话继续。用户视角下,对话始终是连续的。

为什么记忆用 Markdown 而不是 JSON?
Markdown 可读、可编辑、可版本控制。用户可以直接打开 MEMORY.md 查看和修改 Bot 的记忆,就像编辑一个笔记文件。这种透明性是信任的基础。
为什么 Context Steward 是独立调用?
把管家逻辑放在独立的模型调用中,而不是主对话的一部分,有两个好处:
- 不污染主对话上下文:管家的判断逻辑不会占用主对话的 token
- 更准确的判断:管家只看到最新消息,不会被长对话中的无关信息干扰
写在最后
DS Bot 的架构没有使用什么高深的技术或复杂的算法。它的创新在于设计选择:
- 选择 Session 而不是临时 Agent → 获得持久性
- 选择独立的 Context Steward → 获得清晰的关注点分离
- 选择轮次制群聊 → 获得自然的协作体验
- 选择三层记忆 → 获得符合直觉的记忆结构
- 选择 Markdown 记忆格式 → 获得透明性和可编辑性
- 选择本地优先 → 获得隐私安全和完全控制
每一个选择都不是唯一的,但组合在一起,形成了一个简单、可靠、可扩展的多 Agent 系统。
从第一性原理看,DS Bot 证明了一件事:好的架构不是做加法,而是做减法。它没有发明新的协议或框架,而是巧妙地复用了 dsh 已有的基础设施,在此基础上添加了"持久身份"和"协作通信"两个核心能力。
这就像乐高积木:每一块都很简单,但组合在一起,你可以构建出任何你想要的东西。
从第一性原理看:DS Bot 的成功告诉我们,后来者不需要模仿先行者的每一个设计。通过回到问题的本质,重新思考"AI 应该如何记忆?"、"多个 AI 应该如何协作?",DS Bot 找到了自己的答案,而且这个答案比先行者更好。