Deuz SDK:把会话之外的那一半工程交给框架
Zero-dependency TypeScript framework for production AI agents: durable execution, long-term memory, hybrid RAG, MCP tool calling, human-in-the-loop approval, planning and CodeAct sandboxes. One streaming API for Claude, GPT, Gemini, Grok, Mistral and DeepSeek — Node, Bun, Deno, serverless and edge.
秒懂
- 它是什么?
- Deuz SDK 是一个零运行时依赖的 TypeScript 智能体框架,把长期记忆、上下文压缩、检查点续跑、人工审批和 MCP 连接收进一个包。它解决的是模型调用之外那些没人替你写、又必须写对的代码,代价是你要接受它的一整套接缝约定。
- 适合谁用?
- 适合已经在生产里跑智能体、并且被三件事反复咬过的人:第四十轮对话撑爆上下文、进程中途挂掉后整条运行丢失、某个不可逆的工具调用没人拦。不适合只想调一次模型拿一段文本的场景,也不适合已经深度绑定某个工作流引擎、不打算把检查点搬进自己数据库的团队。
- 能商用吗?
- 可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 33 天前。
- 用什么语言写的?
- 主要是 TypeScript(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它补的不是模型调用,是调用之外的那一圈
README 开头把话说得很直:调用模型是已经解决的问题,没解决的是围绕它的一切。跨会话记住一个用户、在第四十轮还待在上下文窗口里、在不可逆操作前问一下人、进程中途死掉后接着跑、接一个工具服务器而不用手写 OAuth。多数 SDK 把这些留给使用者,Deuz 的选择是自己发货。
目标读者因此很明确:已经在生产里跑智能体、并且被上述某一项反复咬过的 TypeScript 工程师。如果你只是写个脚本调一次模型打印一段文本,这个框架的绝大部分表面积对你没有价值,反而增加理解成本。它的定位不是让第一次调用变简单,而是让第一百次调用之后仍然可控。
README 里那句自我定位值得原样引用:不是在建 ASI,而是那条路上诚实的基础设施。这种自我设限在同类项目里不常见,至少它没有把长期记忆包装成通用智能。
零依赖和全注入,是同一个约束的两面
包描述写着零运行时依赖,README 的徽章也标着 runtime deps 为 0。这不是省安装体积的营销点,它直接决定了可移植性:没有依赖意味着没有只能跑在 Node 上的原生模块,所以同一份代码可以落在 Node、Bun、Deno、serverless 和 edge 上。
配套的是注入式设计。README 说时钟、随机数、fetch、密钥和日志全部由外部注入,没有环境里悄悄摸的东西。好处有两个:一是边缘运行时没有 Node 的那些全局对象时不会突然崩;二是测试可以完全确定化,不需要打桩全局变量。代价也很直接,你必须显式传这些接缝,写惯了就一个 process.env 走天下的代码,迁移时会觉得啰嗦。
可选依赖是另一条线:zod(或任何 Standard Schema 实现)、@modelcontextprotocol/sdk、react、pg / redis、unpdf / mammoth / xlsx、playwright、@opentelemetry/api,都只在你真正用到对应功能时才需要。这意味着核心包很轻,但能力边界要靠你自己按需拼装。
记忆不是消息数组,是一条带增删改的流水线
这是 Deuz 与多数同类框架差别最大的地方。README 明确说长期记忆不是消息数组,而是一条流水线:从对话里抽取持久事实,与已有记忆做对账(add / update / delete,从不盲目追加),按重要性打分,设置过期,并在下一次调用时把相关的那几条拉回来。存储可以落在向量库、Postgres 表或 Obsidian 库上。
配置形态在 README 的示例里给得很清楚:memory 下分 seams、scope、recall、writePolicy 四块。seams 传 store、embedder 和 llm;scope 通常给 userId;recall 控制 topK、maxChars 和 expandLinks;writePolicy 示例取值为 each-turn。recall 里的 maxChars 和 expandLinks 值得留意,它们说明召回结果要经过字符预算裁剪和链接展开,不是把 topK 条原样塞进提示词。
对账而非追加这个设计选择,我认为是这个项目最实在的一处。盲目追加的记忆最终会变成一堆互相矛盾的旧事实,模型在第四十轮读到三个月前的偏好和上周的偏好同时存在,行为就开始漂。代价是每轮都要额外跑一次抽取和对账的模型调用,延迟和成本都要算进预算。README 没有给出这部分的开销数据,选型时应当自己压测。
压缩是一条会自我更新的摘要,不是越堆越高的栈
长跑的第二道关是上下文窗口。README 描述的策略分三层:剪掉过期的工具输出、丢掉旧的推理过程、把最早的若干轮折叠成一条持续更新的运行摘要。注意措辞,是一条被更新的块,不是不断增长的栈。这个区别在长会话里会放大成完全不同的提示词形状。
更关键的是失败兜底。当提供方仍然以请求过长拒绝时,循环会强制压缩并重试该步,而不是让整条运行失败。示例里的用法是 generateText 传 maxSteps: 30 配合 compaction: 'auto'。
我的判断是,强制压缩重试这一条比压缩算法本身更有工程价值。上下文超限是长跑里最常见的偶发失败,把它降级为一次内部重试,意味着上层不需要为这类错误写恢复逻辑。但 README 没有说明强制压缩在极端情况下会不会丢关键信息,也没有说明重试次数上限,这两点属于文档没覆盖的部分,只能从源码确认。
从安装到第一次带记忆的调用
安装命令来自 README:npm install @deuz-sdk/core 是运行时,npm install @deuz-sdk/react 是可选的 useChat、useObject 和无头 UI。环境要求写明 Node 22 及以上,或者任何带 fetch 的边缘运行时。
最小调用示例用的是 streamChat,从 @deuz-sdk/core 导入,模型通过 @deuz-sdk/core/anthropic 的 createAnthropic 构造,密钥来自 process.env.ANTHROPIC_API_KEY。README 强调这个调用同步返回且从不抛异常,失败会以带类型的流片段到达。取文本用 res.textStream 异步迭代,用量从 await res.usage 拿。
带记忆的版本换成 generateText,messages 之外多一个 memory 字段,形如 seams: { store, embedder, llm: model }、scope: { userId }、recall: { topK: 6, maxChars: 2000, expandLinks: 1 }、writePolicy: 'each-turn'。
再往上一层是 README 里那段组合示例:createPostgresStores 传 connectionString 得到 stores,然后 generateText 同时给 tools(含 handoff 和 search)、guardrails(onInput 用 promptInjectionGuardrail,onOutput 用 maxOutputLength(4000))、mcp 数组、chat 的 store 与 chatId、session 的 store 与 runId,以及 runtimeContext。注意 runtimeContext 的定位:它随调用走,不是每次请求现包的闭包。
检查点落在你的数据库,这是取舍不是缺点
README 把断点续跑描述为:步骤检查点写进你自己的数据库,之后用 resumeFromCheckpoint 恢复,不需要工作流厂商。同一段示例里 session 的 store 和 runId 同时承担对话记录和检查点,共用一条连接。
这个选择把持久化的所有权交给你。好处是数据不出自己的库,没有额外的托管服务,恢复逻辑和业务表在同一个事务边界内。代价是你要自己保证那张表的可用性、迁移和清理策略。框架给了接缝,运维责任没有跟着转移。
需要说清楚的是,README 只写到检查点存在你的数据库以及存在 resumeFromCheckpoint 这个入口,没有给出表结构、写入频率、以及恢复时的语义保证(比如某一步已经产生的副作用会不会重放)。这几项在长跑系统里恰恰是最容易出问题的地方,采用前应当从源码或文档的对应页面确认,而不是从这段描述推断。
人工审批、护栏与 MCP:三处默认从严的设计
needsApproval 可以加在任意深度,令牌是 HMAC 签名且带过期时间。README 里有一句很硬的约定:缺少裁决即视为拒绝。这是 fail-closed,不是 fail-open。在审批链路上,这个默认值决定了系统在异常时是停下来还是放行,选错方向的后果通常不可逆。
护栏分三个位置:输入、每次工具调用、最终回答,动作是 pass / block / rewrite。示例里 onInput 用 promptInjectionGuardrail,onOutput 用 maxOutputLength(4000)。把工具调用单独作为一层拦截点,比只在输入输出两端设卡更贴近实际风险,因为提示注入的破坏力往往在工具调用那一刻才兑现。
MCP 侧,README 说支持 OAuth 2.0、重连、sampling 和 roots,配置只要 mcp: [{ url: 'https://mcp.example.com/mcp' }],连接、命名空间隔离和关闭都由框架处理。工具循环本身还带并行调用、错误自愈、失控保护、成本与 token 预算以及子智能体。这些能力堆在一起意味着可配置项很多,默认值是否合适需要逐个确认,尤其是预算类参数。
谁该换、谁不该换,以及迁移表之外要自己验的东西
README 提供了从 Vercel AI SDK 迁移的文档路径,以及一个名为 migrate-from-ai-sdk 的 Agent Skill,声称是从 ai 与 @ai-sdk/* 的逐名对照。这个 Skill 的验证方式值得一提:文档里每个 @deuz-sdk 符号在每次提交时都对真实导出表解析,每个代码示例都对构建产物编译,版本或锁定的 API 契约一变就触发新鲜度检查失败。README 还给了一组数字,九个构建任务在没有该 Skill 时产生了 19 个不存在的导入,分布在九个答案中的八个里。这组数字说明的是文档漂移问题,不是框架质量。
替代方案方面,最直接的对照是 Vercel AI SDK。差别不在模型覆盖,而在职责边界:AI SDK 提供的是调用与流式抽象的通用层,长期记忆、压缩、检查点续跑、审批令牌这些要么自己做,要么接别的服务;Deuz 把它们作为默认发货项,代价是接受它的接缝约定(store、embedder、注入的时钟与 fetch)。如果你的运行本来就是短请求、无状态、失败重试由上游网关兜底,那么引入这套约定是纯粹的负担。
维护与许可:MIT 许可,商用与修改的门槛很低,但 MIT 不提供专利授权条款,也不对商标做任何授予,涉及这两点的团队需要自己的判断,这里不构成法律意见。版本节奏上,仓库最近三个发布是 v2.0.0(2026-08-10)、v1.9.0(2026-07-28)和 v1.8.0(2026-07-22,标题为 Autonomous Agent Runtime),两个月内跨了一个大版本,README 里专门有 What's new in 2.0 页面,说明 1.x 到 2.x 存在需要阅读的变更。升级成本因此主要落在两处:大版本之间的 API 契约变化,以及你依赖的存储包(SQLite、Redis、Postgres)是否同步跟进。
编辑结论
适合已经在生产里跑智能体、并且被三件事反复咬过的人:第四十轮对话撑爆上下文、进程中途挂掉后整条运行丢失、某个不可逆的工具调用没人拦。不适合只想调一次模型拿一段文本的场景,也不适合已经深度绑定某个工作流引擎、不打算把检查点搬进自己数据库的团队。动手前先确认三件事:Node 版本是否达到 README 写明的 22 以上;记忆与检查点要落在哪个存储后端(SQLite、Redis 还是 Postgres 包),以及这些表由谁负责建;再打开 docs/content/docs/migration/from-vercel-ai-sdk.mdx,逐条比对你现在用的 ai 与 @ai-sdk/* 符号是否都在迁移表里。这三步走完,再决定要不要把 streamChat 换成生产入口。
社区笔记