🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI
广告☁️ 云服务器特惠阿里云首购 8 折 · 腾讯云合作特惠
DeepSeek Harness Hub
← 返回列表

richardds5/learn-deepseek-harness

DeepSeek Harnessspec-screened扫描:无法判定在 GitHub 查看 ↗
需源码安装

学习 DeepSeek Harness —— 一个从 0 到 1 构建的 nano agent harness

暂不能直接安装(需源码编译或环境不满足):仓库缺少 package.json,无法用 dsh 插件安装命令安装。 · 最近上游提交 2026/9/8 · 已提供中文文档

学习 DeepSeek Harness——一个从 0 到 1 构建的纳米级智能体框架

综合分
31.7
GitHub 分
31.7
用户评分
—
★ Stars
4
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add richardds5/learn-deepseek-harness
仓库缺少 package.json,无法用 dsh 插件安装命令安装,改用 GitHub 源安装
信任档位:已验证本站已于 3 天前真实安装成功(L4 · 真实安装)
是什么
dsh 原生插件 · chat
装得上吗
本站已真实安装成功(L4 · 真实安装,非静态推断)
安全吗
本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
还在维护吗
活跃:最近一次提交在 17 天前

档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →

🟢实装验证通过· 2026/9/23
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/20(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查需源码安装

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包learn-deepseek-harness(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

仓库缺少 package.json,无法用 dsh 插件安装命令安装

验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/20 18:51:03

用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

由 DeepSeek 最新模型翻译生成
DeepSeek Harness(dsh)是 DeepSeek AI 开源的 agent harness。
它构建于 一切皆插件 的架构之上,并由 Cordis 驱动,
后者是一个元框架,其设计阐述于论文
A Programming Paradigm for Spatiotemporal Composability 之中。
它为 agent 代码带来的词汇是真正全新的:

- 可回滚副作用(Revertible effects) —— 每一次注册都携带一个由运行时持有的逆操作,因此卸载插件会将其副作用一并回滚。
- 响应式辅助效应(Reactive coeffects) —— 插件声明它需要什么;运行时仅在这些需求被满足时才激活它,因此挂载顺序不再重要。
- 单一上下文(One context) 同时协调二者,在其中 agent 循环本身也只是一个插件,被瀑布式监听器包裹。
- 仅追加的会话日志(An append-only session log),messages[] 不过是它的一个投影;持久化是一个监听器,恢复是一次重放。
- 能力接缝(Capability seams)(ctx.llm、ctx.shell、ctx.fs)配有可替换的提供者,因此策略挂在事件上,而工具保持纯粹。
- 由分层配置行组装而成的产物(Products)(bundles、profiles、patches),而非由代码组装。

这些理念本身就值得学习,但生产级代码库在其之上承载了大量工程实现。
本仓库剥离了那些工程实现,用纯 Python 从 0 到 1 重建这些理念:
12 个部分共 28 个渐进式会话,从一个裸循环到一个可自我延续、可组合的 harness。
每个会话添加一个机制(至多两个彼此相关的机制)。每个机制都有一句座右铭。
每个会话都是相对上一个会话的一个 diff,你可以一口气读完。

THE HARNESS PATTERN
===================

config rows      ----->  ctx.plugin(fn, config)  x N
|
+-----------------------+-----------------------+
v                       v                       v
ctx.llm  (seam)        ctx.tools (pipeline)     ctx.sessions (log)
\                       |                       /
+------- agent loop (also just a plugin) ------+
|
inbox --> turn/start --> pre-step --> request --> tool calls --> turn/end
|
every boundary is an event in the session log
model-visible    logged

The loop is a plugin on a context, wrapped by waterfall
listeners, and replayed from an append-only log. Nobody edits it.

快速开始

git clone https://github.com/richardds5/learn-deepseek-harness.git
cd learn-deepseek-harness
pip install -r requirements.txt
cp .env.example .env   # DEEPSEEK_API_KEY=... ; MODEL_ID=deepseek-chat
python agents/s01_agent_loop.py              # 从这里开始
python agents/s13_runtime_context_and_turn_stopping.py   # 内核已完成;之后每个会话都复制它
python agents/s20_bundles_and_profiles.py --profile headless --task "list the bundles/ dir"
python agents/s28_jobs_and_schedule.py       # 目标 / 任务 / 定时器
python agents/s_full.py                      # 集大成:所有机制都由一个 profile 组合而成

每个会话文件都是自包含的(彼此之间没有导入):打开一个,从头读到尾。
s01–s13 构成一条链:每个会话在前一个文件的基础上增加一个机制,直到内核在 s13 处完成。
s14–s28 各自复制 s13 内核并恰好增加一个机制;每一部分的第二个会话建立在该部分的第一个会话之上。

核心模式
python
root = Context()                                   # 一个共享上下文
root.plugin(llm_deepseek, {"model": MODEL})        # 提供 ctx.llm
root.plugin(tools_registry)                        # 提供 ctx.tools
root.plugin(sessions_plugin)                       # 提供 ctx.sessions
root.plugin(tool_bash)                             # ctx.effect(lambda: ctx.tools.register(...))
root.plugin(approval_policy, {"deny": [...]})      # ctx.on("tools/pre-execute", gate)
root.plugin(agent_loop)                            # 提供 ctx.agents —— 循环本身只是一个插件

def run_step(self, turn, step):                    # 位于 agent-loop 插件内部
request = self.ctx.waterfall("agent/request",
{"system": SYSTEM, "messages": self.session.derive_messages(),   #  tools/execute -> tools/post-execute
self.session.append("tool/result", {...})

s13 之后的每个会话要么监听某个事件(agent/pre-step、tools/pre-execute、agent/status、
session/event),要么提供某个服务(ctx.compaction、ctx.subagents、ctx.goals)。它们都不修改循环。

范围(重要)

这是一个 0->1 学习项目,也是一个独立代码库。它的设计理念借鉴自 DeepSeek Harness;它保留了理念,舍弃了使其达到生产级水准的工程实现:

- 无流式,无异步:每次调用都是同步的;wake() 会运行一个回合直至完成。
- 插件上下文被压缩到约 70 行:没有 fiber 状态机,没有热重载,没有隔离领域,没有类型化事件。
- 会话事件是裸字典;没有格式版本、zstd 或 SQLite 投影。
- s17 的“沙箱”仅在 sandbox-exec / bwrap 存在时才进行隔离;否则它会打印一条警告。
- 无 Web UI,无 SDK / ACP 服务器,无 agent 预设,无 agent 团队,无自我修改工具。

这里的每个 Python 类都是教学草图。本仓库中的任何内容都不映射到、也不对任何其他代码库作出声明。

学习路径

第 1 部分  内核               第 2 部分  插件               第 3 部分  工具流水线
s01 Agent 循环       [1]     s03 上下文与插件     [4]    s07 瀑布流           [4]
s02 工具表           [4]     s04 效果与销毁       [4]    s08 工具流水线       [4]
s05 注入与待处理     [4]
s06 事件             [4]

第 4 部分  会话日志          第 5 部分  驱动器            第 6 部分  提示词与作用域
s09 会话日志         [4]     s11 轮次与步骤       [4]    s14 提示词分节       [4]
s10 持久化与恢复     [4]     s12 收件箱           [4]    s15 作用域           [4]
s13 运行时上下文     [4]
与轮次停止

第 7 部分  能力接缝          第 8 部分  配置              第 9 部分  压缩
s16 LLM 接缝         [4]     s19 从行启动         [4]    s21 表面替换         [4]
s17 Shell 接缝       [4]     s20 捆绑包/配置文件  [4]    s22 压缩策略         [4]
s18 文件系统接缝     [4]

第 10 部分 子 agent          第 11 部分 记录状态          第 12 部分 延续
s23 生成             [5]     s25 命令与投影       [5]    s27 目标             [6]
s24 分叉与后台       [5]     s26 计划模式         [6]    s28 作业与调度       [12]

[N] = 模型可见的工具

项目结构

learn-deepseek-harness/
|
|-- agents/                 # Python 参考实现(s01-s28 + s_full 综合项目)
|-- docs/{zh,en}/           # 实践优先的文档,每个会话一份(中文 + 英文)
|-- bundles/                # s20: base.yml / repl.yml / headless.yml(配置行)
|-- profiles/               # s20: repl/ 和 headless/(捆绑包列表 + 补丁层)
|-- scripts/smoke_all.sh    # 针对真实 API 将每个会话运行一次
+-- .sessions/              # 运行时:每个会话一个 JSONL 日志(gitignored)

文档

心智模型优先:问题、解决方案、ASCII 图、最小代码,然后映射到真实代码。

第 1 部分 · 内核:循环与工具

| 会话 | 主题 | 格言 | 新增内容 |
|---------|-------|-------|--------------|
| s01 | Agent 循环 | 循环是你开始的地方,而不是你结束的地方 | 一个工具 + 一个循环 = 一个 agent;后续会话不会修改它,而是包装它 |
| s02 | 工具表 | 添加一个工具;循环不变 | 给模型的 schema 列表,给循环的处理器映射;循环只查找名称 |

第 2 部分 · 插件系统

| 会话 | 主题 | 格言 | 新增内容 |
|---------|-------|-------|--------------|
| s03 | 上下文与插件 | 一切皆插件,循环也不例外 | 一个共享的 ctx;服务位于 ctx. 上;插件是 fn(ctx, config) |
| s04 | 副作用与销毁 | 注册即副作用;卸载即回滚 | ctx.effect() 记住一个清理器;dispose() 按相反顺序展开 |
| s05 | 注入与等待 | 缺失的依赖不是错误,而是一种等待 | fn.inject 声明需求;未满足即 PENDING;挂载顺序不再重要 |
| s06 | 事件 | 观察者只监听;它们从不触碰循环 | ctx.on / ctx.emit;监听器本身就是一个副作用 |

第 3 部分 · 工具流水线

| 会话 | 主题 | 格言 | 新增内容 |
|---------|-------|-------|--------------|
| s07 | 瀑布流 | 跳过 next(),你就完成了拦截 | 瀑布流 = 环绕中间件;策略从工具中移出,放到 tools/pre-execute 上 |
| s08 | 工具流水线 | 把关、包装、转换、观察:四个席位 | pre-execute / execute / post-execute / result,每个席位一种监听器形态 |

第 4 部分 · 会话日志

| 会话 | 主题 | 格言 | 新增内容 |
|---------|-------|-------|--------------|
| s09 | 会话日志 | 消息不是状态,而是日志的投影 | 仅追加事件;derive_messages() 是纯函数 |
| s10 | 持久化与恢复 | 持久化是监听器;恢复是重放 | JSONL 监听 session/event;open() = 重放 + repair() |

第 5 部分 · 驱动器

| 会话 | 主题 | 格言 | 新增内容 |
|---------|-------|-------|--------------|
| s11 | 轮次与步骤 | 一个轮次,多个步骤,每个边界都是一个事件 | run_turn / run_step;agent/pre-step 决定进入还是拒绝 |
| s12 | 收件箱 | 所有输入都通过一扇门进入 | followup / steer / inject 是 send(target, wakeup) 的三种预设 |
| s13 | 运行时上下文与轮次停止 | 在轮次关闭之前,插件获得最后一次发言权 | pre-step 追加运行时上下文;agent/turn-stopping 不是投票,只有收件箱才算数 |

第 6 部分 · 提示词与作用域

| 会话 | 主题 | 格言 | 新增内容 |
|---------|-------|-------|--------------|
| s14 | 提示词分节 | 提示词是组装出来的,而非硬编码的 | 每个插件贡献一个分节;每一步都重建;变更会记录 request/header |
| s15 | 作用域 | 每个智能体一个作用域:遮蔽,而非替换 | 作用域分节按名称遮蔽全局分节;作用域工具逃逸限制 |

第 7 部分 · 能力接缝

| 会话 | 主题 | 格言 | 新增内容 |
|---------|-------|-------|--------------|
| s16 | LLM 接缝 | 定义、提供者、消费者:单独一个角色不构成接缝 | ctx.llm 是一个注册表:deepseek 和 replay 共存;model_router 只重写调用配置 |
| s17 | Shell 接缝 | 换一个提供者,换整个世界 | ctx.shell 同一时刻只有一个提供者:local 或 sandbox;tool_bash 对两者一无所知 |
| s18 | FS 接缝 | 策略挂在接缝的事件上;工具保持原样 | fs/write-intent 可以拒绝;fs/observed 记录被读取的内容 |

第 8 部分 · 配置

| 会话 | 主题 | 箴言 | 它添加了什么 |
|---------|-------|-------|--------------|
| s19 | 从行启动 | 启动不是一个函数,而是一个行的列表 | 一个插件名注册表 + {id, name, config} 的行;未知名称会大声失败 |
| s20 | 包与配置档 | 一个产品是一叠配置层 | 一个空列表 + 包补丁 + 配置档补丁 + 主目录补丁 + --patch = 一个产品 |

第 9 部分 · 压缩

| 会话 | 主题 | 箴言 | 它添加了什么 |
|---------|-------|-------|--------------|
| s21 | 表面替换 | 压缩替换表面,从不替换日志 | 一个带 surfaceOp: replace 的 user/message 遮蔽一段跨度;日志只增长 |
| s22 | 压缩策略 | 何时何地压缩是策略,不是内核 | token 估算、阈值、保留尾部、安全切点:全都在一个 ctx.compaction 提供者内部 |

第 10 部分 · 子代理

| 会话 | 主题 | 箴言 | 它添加了什么 |
|---------|-------|-------|--------------|
| s23 | 子代理:生成 | 一个子代理是另一个会话,而不是另一个 messages[] | 它有自己的日志、自己的轮次/步骤机器;答案作为 tool_result 返回 |
| s24 | 分叉与后台 | 结果作为 tool_result 返回,或通过父级的收件箱返回 | 分叉继承已完成的轮次;后台子级通过 followup 或 inject 结算 |

第 11 部分 · 已记录状态

| 会话 | 主题 | 箴言 | 它添加了什么 |
|---------|-------|-------|--------------|
| s25 | 命令与投影 | 模式不是一个变量,而是已记录状态 | /commands 从不到达模型;todo 是一个 todo/write 事件加上一个纯折叠 |
| s26 | 计划模式 | 绝不在轮次中途重写历史;排队到下一步 | plan/mode 只在下一个步骤前写入 |

第 12 部分 · 延续

| 会话 | 主题 | 箴言 | 它添加了什么 |
|---------|-------|-------|--------------|
| s27 | 目标 | 轮次结束不是任务结束 | 一个目标在 agent/status 空闲时 followup() 它的下一轮;驱动器保持原样 |
| s28 | 作业与调度 | 后台只能通过收件箱回来 | 一个作业完成、一个定时器触发:两者都只是 followup / inject |

综合项目

| 会话 | 主题 | 格言 | 它添加了什么 |
|---------|-------|-------|--------------|
| s_full | 一个 profile 组合了所有机制 | 没有需要修补的核心 | 每个 # === SECTION 标题都标明了它来自哪个会话 |

learn-claude-code 与 learn-deepseek-harness 对比

相同的循环,不同的问题。learn-claude-code 问的是“agent 做什么?”;
本仓库问的是“你如何在不改动它的情况下改变它的行为?”

| 关注点 | learn-claude-code | learn-deepseek-harness |
|---|---|---|
| 循环 | 每个会话都要编辑的函数 | 没人编辑的插件;监听器包裹它 |
| 工具 | 一个 TOOL_HANDLERS 字典 | ctx.tools.register() 返回一个 disposer;三个 waterfall 阶段 |
| 策略 | 工具内部的 if dangerous in cmd | 一个 tools/pre-execute 监听器;工具保持纯净 |
| 对话 | 一个 messages[] 列表 | 仅追加的会话日志;derive_messages() 投影它 |
| 输入 | input() -> messages.append | 一个收件箱:followup / steer / inject |
| 上下文压缩 | 就地重写 messages[] | 一个带 surfaceOp: replace 的 user/message;日志不被改动 |
| 子代理 | 一个全新的 messages=[] | 一个带 parentSession 的全新会话;一个 provider 注册表 |
| 配置 | 文件顶部的常量 | YAML 中的行,按 id 打补丁,分层到 profiles 中 |

读完之后

- 带着这二十八条格言从头到尾阅读 agents/s_full.py:每个 # === SECTION 标题都标明了它来自哪个会话。
- 编写你自己的插件——一个新的 tools/pre-execute 策略、一个 prompt 片段、一个子代理 provider——并从 bundle 行挂载它,而不触碰循环。
- 运行 python agents/s_full.py --profile headless --dump-config,并将每一行追溯回产生它的 bundle 或 patch 层。

致谢

本仓库受 learn-claude-code 启发,并借鉴了它的教学风格:一个会话,一个机制,一条格言。
那个仓库教的是agent 循环。本仓库教的是循环周围的 harness:真正实现一切皆插件需要什么。

设计思想本身来自 DeepSeek Harness 和 Cordis(见参考文献)。这里的所有代码都是独立的、从零开始的教学草图。

参考文献

- DeepSeek Harness —— 官方仓库:
- 论文 —— Yifan Shi, Wei Zhang, Tianyi Cui. A Programming Paradigm for Spatiotemporal Composability. arXiv:2608.25512, 2026.
bibtex
@misc{shi2026spatiotemporal,
title         = {A Programming Paradigm for Spatiotemporal Composability},
author        = {Shi, Yifan and Zhang, Wei and Cui, Tianyi},
year          = {2026},
eprint        = {2608.25512},
archivePrefix = {arXiv},
url           = {https://arxiv.org/abs/2608.25512}
}

许可证

MIT

没有需要修补的核心。将你的插件挂载到其他插件旁边即可。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入社群

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

DPharness QQ 群二维码,QQ 扫码进群
QQ 扫码进群
DPharness 飞书群二维码,飞书扫码进群
飞书扫码进群