乐于分享
好东西不私藏

本地27B模型 + 一个"全插件化"Harness,这个组合我觉得被严重低估了

本地27B模型 + 一个"全插件化"Harness,这个组合我觉得被严重低估了

如果你关注AI Agent这个领域,最近一定会被各种"谁家模型更强"的对比刷屏。

但我今天想聊一个更冷门、但可能更重要的东西。

就是当你把Qwen3.8:27b(一个27B参数的本地模型)装进DeepSeek Harness(一个"一切皆插件"的Agent引擎)之后,会发生什么。

这个组合,我觉得是2026年下半年最被低估的一对搭档。

我先说结论:DeepSeek Harness可能是目前所有开源Agent Harness里,最适合本地模型的那个。

不是因为它为本地模型做了什么特殊优化,而是因为它的架构哲学——"一切皆插件"——恰好把"本地模型"这件事的成本和复杂度,降到了最低。

先说清楚:Harness到底是什么

先给不太熟悉的朋友补个课。

所谓Harness,就是Agent的"引擎"——模型负责思考,Harness负责执行。它决定了Agent怎么调用工具、怎么管理会话、怎么保证安全、怎么和外部服务打交道。

如果把模型比作汽车发动机,那Harness就是底盘、变速箱、悬挂系统的总和。

同样是V8发动机,装在跑车上和装在卡车上,是完全不同的东西。

所以我之前写过一篇《AI编程Agent的"引擎"对决》,拆解了Codex CLI、Grok Build、Hermes、Pi四个项目的Harness设计。那篇文章里我提过一个判断:**Harness是Agent的"隐藏护城河"**。

今天这篇文章,算是那个判断的延续。

我要拆的是第五个项目——DeepSeek Harnessdsh)。

DeepSeek Harness:一个"没有核心"的Agent引擎

DeepSeek Harness是DeepSeek AI官方开源的Agent Harness。我第一眼看到它的架构文档时,说实话是有点震惊的。

因为它做了一件绝大多数框架都不敢做的事:它没有"核心"。

你听听它的架构文档是怎么说的:

"Every part of the product is a plugin, including the model adapter, the tool registry, the session log, and the agent loop itself, so every part is replaceable from configuration."

"产品的每一个部分都是插件,包括模型适配器、工具注册表、会话日志,甚至Agent循环本身。所以每一个部分都可以通过配置来替换。"

这句话有多激进?

在Codex CLI里,agent loop是写死在Rust代码里的。在Grok Build里,workspace管理是核心模块。在Hermes里,虽然工具是注册制的,但agent循环仍然是Python类。

但在DeepSeek Harness里,连Agent循环本身都是一个可以卸载的插件。

这个设计的根基,是一个叫Cordis的插件框架。

Cordis:一个"时空可组合"的插件框架

Cordis是DeepSeek Harness vendored(内嵌)的插件框架,它的设计哲学写在它自己的一篇论文里——《A Programming Paradigm for Spatiotemporal Composability》(一种时空可组合性的编程范式)。

听名字很学术,但核心思想其实很简单,就五个概念:

第一,插件就是实现了Service的对象。 一个插件可以是一个函数,或者一个Service子类。它的生命周期由Cordis挂载到当前上下文中。

第二,上下文是服务的仓库。 每个服务都占一个稳定的ctx.<key>位置,比如ctx.toolsctx.llmctx.sessions。其他插件通过key来找到服务,而不是import一个具体的实现。

第三,通过inject声明依赖。 一个插件如果声明了它需要的服务,它就会等那些服务存在后才被加载。加载顺序由服务依赖决定,而不是手动的启动顺序。

第四,类型化事件用于通信。 服务通过TypeScript声明合并来声明事件名,然后用emitwaterfallparallelserial四种模式来派发。

第五,注册是可逆的效应。 Prompt段落、工具schema、适配器、provider、监听器,全部通过ctx.effect()ctx.on()来安装,这样在插件卸载时,它们可以被可预测地回滚。

这五条,听起来像是一套不错的依赖注入框架,对吧?

但真正让DeepSeek Harness与众不同的,是它把这条原则执行到了极致

四种事件派发模式:这是整个系统的"神经系统"

Cordis定义了四种事件派发模式,每种都有明确的语义:

  • emit:异步,不等待,监听器按注册顺序观察,无返回值
  • waterfall:异步,不等待,监听器按顺序观察,有返回值。每个监听器收到next(),调用它就把结果交给下一个监听器,不调用就短路
  • parallel:异步,等待,所有监听器并行观察,无返回值
  • serial:异步,等待,监听器按顺序观察,有返回值

这四个模式,就是整个DeepSeek Harness的"神经系统"。

拿模型调用来说。llm/stream是一个waterfall事件。这意味着:你可以写一个监听器,在请求到达真正的模型适配器之前拦截它——缓存响应、重试、路由到另一个模型,甚至直接自己返回一个流。

再拿工具执行来说。tools/pre-executetools/executetools/post-execute这三个事件都是waterfall。这意味着:你可以在工具执行前拦截它(比如做权限检查),可以在执行后修改结果(比如做格式转换),甚至可以在中间插入一个新的执行路径。

再拿会话持久化来说。session/flush是一个parallel事件。这意味着:所有需要把会话写入持久化存储的监听器——本地文件、远程数据库、云同步——会同时运行,任何一个失败都不会阻塞其他。

这个设计的精妙之处在于:你不需要修改任何核心代码,就能改变系统的行为。 你只需要挂载一个新的插件,监听一个事件,系统就会按照你的逻辑来工作。

五个关键优化:DeepSeek Harness到底在Harness上做了什么

好了,框架哲学讲完了。接下来我们看具体的。

我把DeepSeek Harness在Harness层面做的优化,归纳成五个关键点。这五个点,每一个都值得单独拿出来说。

优化一:事件溯源会话日志——"模型可见即已记录"

这是我认为DeepSeek Harness最优雅的设计之一。

它的会话系统(dsh-session)是一个append-only(只追加)的事件日志。会话中的每一个事实——用户消息、助手回复、工具调用、工具结果、turn的开始和结束——都是追加到这个日志上的一个不可变事件。

然后,模型看到的历史,是从这个日志推导出来的。

架构文档里有一句话我印象特别深:

"Model-visible means logged. Anything that reaches a model request must be reconstructable from the log, and a runtime invariant asserts it."

"模型可见即已记录。任何到达模型请求的内容,都必须能从日志中重建。有一个运行时不变式来断言这一点。"

这句话是什么意思?

它意味着:你永远不可能遇到"模型看到了但日志里没有"的情况。 如果这种情况发生,运行时不变式会直接抛错。

为什么这很重要?

因为在这个基础上,fork(分支)、resume(恢复)、transcript(转录)、telemetry(遥测)、persistence(持久化)——所有这些功能,全部从同一个日志流推导出来。

不需要为每个功能单独维护一份状态。不需要担心状态不一致。会话日志是唯一的事实来源。

这个设计,和Codex CLI的ThreadStore、Grok Build的CheckpointStore、Pi的SQLite后端,都形成了鲜明对比——它们是"多份状态、各自维护",而DeepSeek Harness是"一份日志、处处推导"。

优化二:Per-Call沙箱策略——"策略随调用,不随Provider"

这是DeepSeek Harness在安全模型上做得最漂亮的地方。

它定义了一个SandboxMode,只有三种取值:

  • read-only:只读,后端拒绝写入
  • workspace-write:允许在工作区根目录下写入
  • danger-full-access:完全绕过限制

关键点在于:这个策略是每次调用时解析的,不是固定在沙箱Provider上的。

什么意思?

在Codex CLI里,沙箱是"全局的"——你启动Agent时决定用哪种沙箱模式,然后所有命令都在那个模式下执行。

但在DeepSeek Harness里,两个不同的工具调用可以在同一时刻使用不同的沙箱策略。 一个bash命令可以在read-only模式下运行,而同时一个子Agent需要写它的状态目录,就可以在workspace-write模式下运行。

架构文档里说得非常清楚:

"This permits concurrent sessions, consumers, and one-shot escalated retries to ask the same provider for different boundaries without mutating provider state."

"这允许并发会话、消费者和一次性升级重试,向同一个provider请求不同的边界,而不需要改变provider的状态。"

而且,**执行结果是一个"被报告的事实"**。full意味着后端完整治理了所有承诺的文件效应;partial意味着有部分缺口(比如老版Landlock ABI、Windows ACL的Everyone边界)。消费者如果要求绝对边界,就必须拒绝或显式提示这个区别。

这个设计非常诚实。它不假装安全,而是如实报告安全的程度,让上层根据需求做决策。

优化三:并行工具调用的滚动池调度

DeepSeek Harness在工具执行调度上有一个专门的设计,处理的是Agent领域一个很微妙的问题:并行工具调用怎么调度才安全?

当一个助手回复包含多个工具调用时,这些调用有些可以并行,有些必须串行。

DeepSeek Harness的解法是:**isConcurrencySafe分类器 + 有界滚动池。**

每个工具可以声明一个isConcurrencySafe(args)方法,返回true表示这个调用可以加入并行组。没有声明这个方法的工具,默认是排他的——它必须独占执行。

调度器的逻辑(在tool-calls.ts里)是这样的:

  1. 从模型返回的工具调用列表按顺序排队
  2. 第一个调用先分类——如果是并行的,就尝试把它和后面所有调用组成一个并行组;如果是排他的,就单独执行
  3. 并行组用有界滚动池执行,排他调用形成屏障
  4. 后面的调用在开始前重新分类——因为注册表可能在执行过程中变化
  5. 结果和结果上下文保持模型顺序提交

还有一个细节:中止时的处理。如果步骤被中止,调度器会排空已开始的调用,为未开始的调用记录合成的错误结果,这样replay仍然有效。

这个设计的价值在于:它在并发性能和安全正确性之间找到了一个可配置的平衡点。 工具作者可以精确控制哪些调用可以并行,哪些必须串行,而不是由框架一刀切。

优化四:系统提示的分层组装与缓存安全

DeepSeek Harness的系统提示系统(dsh-system-prompt)把"组装提示词"这件事做成了两个可插拔的层次。

第一层是PromptSection——静态的、按顺序排列的提示词段落。每个段落有唯一的name和order,order决定了拼接顺序。约定是:-100是harness身份,0是部署persona,100-199是工具指南。

第二层是PromptContext——动态的、cache-safe的上下文。文档里明确说了,这是PromptSection的"cache-safe counterpart"。它被物化为一个持久的user-role快照,只在内容变化或compaction移除它时才更新。

为什么这个设计重要?

因为prompt缓存是Agent API成本的大头。在长对话中,如果系统提示每次都变,缓存就失效了,成本会成倍上升。

DeepSeek Harness把"稳定的提示"和"会变的上下文"分开了。稳定部分可以一直命中缓存,动态部分只在变化时才更新。

这个设计,对于本地模型来说,意义甚至更大——因为本地模型的KV cache是有限的内存资源。缓存友好的提示词组装,意味着更少的重复计算、更快的响应。

优化五:统一的LLM适配器接缝——这是Ollama的入口

最后这个,是我认为对今天这个主题最关键的一个。

DeepSeek Harness的LLM层(dsh-llm)定义了一个适配器接缝(adapter seam)ctx.llm。任何模型Provider,只要实现这个接缝,就能接入。

更关键的是,它内置了一个叫**dsh-llm-pi-ai**的适配器,背后是@earendil-works/pi-ai——一个支持30+Provider的通用库。

这个适配器的文档里有一句话,直接点明了本地模型的接入方式:

"A route pi-ai does not ship is declared outright, so an OpenAI-compatible gateway, a self-hosted server, or a provider newer than the installed catalog is configuration rather than a code change."

"pi-ai不提供的路由,可以直接声明。所以一个OpenAI兼容的网关、一个自托管服务器,或者一个比已安装catalog更新的provider,都是配置而不是代码改动。"

配置长什么样?就这么简单:

baseURL:http://localhost:11434/v1

对,你没看错。

Ollama的OpenAI兼容端点,就是DeepSeek Harness接入本地模型的方式。

不需要写新的适配器代码,不需要等官方支持,不需要fork项目。只需要在配置里写一行baseURL

这就是"一切皆插件"架构的真正威力。

把Qwen3.8:27b装进去:本地Agent的完整闭环

现在我们来聊今天的另一个主角:Qwen3.8:27b

这个模型是阿里云通义千问团队最新发布的,在Ollama上的规格是这样的:

  • 27.3B参数,Q4_K_M量化,18GB体积
  • Apache 2.0开源协议,可以随便用
  • 默认开启思考模式,可以按请求关闭,可以用reasoning_effort调节推理深度
  • 原生支持图像和视频理解,从STEM图表到小时级视频
  • 强化了Agent执行能力:更强的自主规划,更好地处理环境反馈
  • 强化了下游兼容性:对主流harness和开发工具有更广泛的支持

注意最后两条。Qwen3.8在官方说明里,专门提到了两个词:Agent Execution(Agent执行)和Downstream Compatibility(下游兼容性)。

这说明什么?说明Qwen团队在训练这个模型时,已经把"在Agent Harness里跑"作为一等公民来优化了。

而且,Ollama给这个模型默认启用了draft_num_predict: 4——这是投机解码(speculative decoding)的参数,意味着本地推理速度会有明显提升。

一个具体的配置流程

我们来看看,怎么把这个组合跑起来。

第一步,在本地启动Ollama:

ollama run qwen3.8:27b

Ollama默认监听http://localhost:11434,并且提供OpenAI兼容的/v1端点。

第二步,在DeepSeek Harness的配置里,加一个LLM路由:

baseURL:http://localhost:11434/v1
api:openai-completions
models:
-id:qwen3.8:27b
contextWindow:131072

第三步,启动Harness:

npx @deepseek-ai/dsh web

然后你的Web UI里就能选到Qwen3.8:27b了。

就这么简单。没有任何代码改动,没有编译,没有fork。

这个组合的真正价值在哪里

我知道很多人会说:"本地27B模型,能力肯定不如云端大模型。"

对,这是事实。但这不是重点。

重点是成本结构和隐私结构的彻底改变。

一个27B的量化模型,在M系列芯片的Mac上,或者一张24GB显存的显卡上,可以流畅运行。这意味着:

  • 零边际成本:没有按token计费。你跑一天和跑一个月,电费差别可以忽略不计。
  • 完全私有:你的代码、你的数据、你的对话,不出你的机器。
  • 无限并发:你想开多少个会话就开多少个,没有速率限制。
  • 无供应商锁定:Apache 2.0协议,模型文件在你自己手里。

而DeepSeek Harness提供的,是给这个本地模型配上一个生产级的执行引擎

它的沙箱保护你不被Agent误操作破坏系统。它的事件溯源日志让你随时能恢复、分支、审计。它的工具调度器让Agent能高效地并行执行。它的插件架构让你能无限扩展。

一个免费的模型,一个开源的引擎,跑在你自己的一台机器上。

这就是"个人AI基础设施"的雏形。

升维:本地模型 + 插件化Harness,正在重新定义Agent的分层

最后,我想做一个判断。

过去两年,AI Agent领域有一个隐含的假设:Agent需要云端大模型才能正常工作。

这个假设正在被打破。

Qwen3.8:27b这样的模型,在Agent执行能力上已经足够处理相当多的真实任务。而DeepSeek Harness这样的框架,把"接入一个本地模型"的成本降到了"一行配置"。

这意味着Agent的架构正在重新分层:

模型层开始分化。云端大模型处理复杂推理,本地模型处理日常执行。两者通过同一个Harness无缝切换。

执行层开始标准化。Harness不再绑定特定的模型Provider,而是通过适配器接缝支持任意后端。

基础设施层开始下沉。一台个人电脑、一张显卡、一个Ollama进程,就能支撑起一个完整的Agent工作流。

这不只是省钱的问题。这是控制权的问题。

当你的模型、你的引擎、你的数据都在自己手里时,你才真正拥有了你的AI。

而这个"拥有"的体验,正是DeepSeek Harness + Qwen3.8:27b这个组合,今天就能给到你的。

以上,既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧,如果想第一时间收到推送,也可以给我个星标⭐~谢谢你看我的文章,我们,下次再见。