DeepSeek Harness爆火之后:Model + Harness = Agent,到底该怎么工程化落地?
摘要:
最近“DeepSeek Harness”这个词在Agent和Coding Agent圈里快速升温。
但真正值得开发者研究的,不是某个项目是不是“国产Claude Code”。
更重要的问题是:为什么同一个DeepSeek V4模型,放进不同Agent工具里,实际完成任务的能力会差这么多?
答案在Harness。
本文从插件协议、任务状态机、上下文管理、工具注册、沙箱、验证闭环、模型适配与多模型路由几个角度,拆解Model + Harness = Agent背后的工程实现。
FACT-001|先把“官方信息”和“第三方项目”分开
DeepSeek官方目前可以确认的是:V4明确强化了Agentic Coding能力,并提供Claude Code、OpenCode、OpenClaw、Copilot CLI、Pi等Agent与Coding Assistant的官方接入文档。
DeepSeek官方GitHub中也存在awesome-deepseek-agent仓库,用于整理V4 Pro / Flash与不同Agent工具的集成方案。
但“DeepSeek官方独立Harness产品、MIT协议、npx @deepseek-ai/dsh web、4小时34K stars”等说法,目前没有在DeepSeek官方组织仓库或API文档里找到对应页面。
当前公开的deepseek-harness项目来自第三方开发者,因此本文不会把第三方项目属性写成DeepSeek官方产品事实。
1. Harness到底是什么?先别把它理解成一个“Agent App”
用汽车做类比其实非常准确。
大模型更像发动机。
它提供推理、理解和生成能力。
但只有发动机,没有方向盘、刹车、仪表盘、传动系统和车身,仍然不能真正上路。
Harness负责的就是“整车系统”。
Agent =
Model
+ Context
+ Planner
+ Tools
+ State
+ Memory
+ Guardrails
+ Verifier
+ Retry / Recovery
所以Harness不是简单包一层UI。
它真正控制的是模型如何拿到上下文、如何调用工具、如何执行、如何验证以及什么时候停止。
2. DeepSeek V4为什么特别适合拿来讨论Harness
DeepSeek V4官方发布时,就把Agentic Coding单独列为重点能力。
V4 Pro面向更复杂的Agent任务。
V4 Flash则强调更低成本和更快速度,并且在简单Agent任务上接近Pro。
两者都支持1M上下文和工具调用。
这给Harness留下了很大的调度空间。
User Task
↓
Harness
├── Simple Search → V4 Flash
├── File Summary → V4 Flash
├── Main Planning → V4 Pro
├── Deep Debug → V4 Pro
└── Result Check → Flash / Pro
同一个用户任务内部,可以同时使用多个模型层级。
这已经不是传统Chatbot的调用方式。
3. Harness的第一层:Plugin Contract,而不是“所有代码写死”
真正可扩展的Harness,需要把模型、工具、记忆、工作流甚至UI能力抽象成插件。
否则每增加一种Agent场景,都要复制整套代码。
from dataclasses import dataclass
from typing import Protocol, Any
class Plugin(Protocol):
name: str
version: str
async def setup(self, context: dict) -> None:
...
async def invoke(self, payload: dict) -> Any:
...
async def teardown(self) -> None:
...
@dataclass
class PluginMeta:
name: str
version: str
kind: str
permissions: set[str]
enabled: bool = True
有了统一Plugin Contract以后,模型适配、网页工具、知识库、终端、视觉理解都可以挂在同一个运行时上。
PLUGIN-101|NO_CONTRACT
插件只靠约定调用,没有统一输入输出、生命周期和权限声明,插件数量一多就无法治理。
4. 第二层:Model Adapter,让Harness和模型解耦
插件化系统最重要的一个能力,是不能把Agent逻辑写死在某一家模型SDK上。
DeepSeek官方同时提供OpenAI兼容和Anthropic兼容接口。
这意味着Harness完全可以做统一Model Adapter。
class ModelAdapter(Protocol):
async def generate(
self,
messages: list[dict],
tools: list[dict],
) -> dict:
...
class DeepSeekAdapter:
def __init__(self, client, model: str):
self.client = client
self.model = model
async def generate(self, messages, tools):
return await self.client.chat(
model=self.model,
messages=messages,
tools=tools,
)
如果以后换成其他兼容模型,只需要新增Adapter。
Planner、Tool Registry和Task State都不需要重写。
5. 第三层:Task State,专门解决“目标遗忘”和“任务跑偏”
长任务最怕的不是模型不会做,而是做了十几轮以后开始忘记最初目标。
from dataclasses import dataclass, field
from enum import Enum
class Phase(str, Enum):
PLAN = "plan"
EXECUTE = "execute"
VERIFY = "verify"
DONE = "done"
FAILED = "failed"
@dataclass
class TaskState:
task_id: str
goal: str
phase: Phase
plan: list[str] = field(default_factory=list)
completed: list[str] = field(default_factory=list)
observations: list[str] = field(default_factory=list)
iteration: int = 0
max_iterations: int = 20
Goal、Plan、Completed、Observation应该成为结构化状态。
不能只靠模型“自己记住”。
STATE-202|STATE_IN_PROMPT_ONLY
任务状态全部存在自然语言上下文里,上下文压缩、断线恢复或者多Agent协作时都容易丢状态。
6. 第四层:Tool Registry,工具不能等于“无限Shell”
Agent真正开始“干活”,靠的不是回答,而是工具。
读文件、检索网页、调用数据库、运行测试、分析图片,都应该被抽象成受控能力。
from dataclasses import dataclass
from typing import Callable
@dataclass
class Tool:
name: str
handler: Callable
read_only: bool = True
requires_approval: bool = False
timeout_seconds: int = 60
class ToolRegistry:
def __init__(self):
self.tools = {}
def register(self, tool: Tool):
self.tools[tool.name] = tool
def get(self, name: str) -> Tool:
if name not in self.tools:
raise KeyError(f"unknown tool: {name}")
return self.tools[name]
工具必须声明权限。
读操作和写操作不能混在一起。
高风险工具还应该进入审批。
TOOL-303|UNRESTRICTED_TOOL
所有插件都能任意读写本地文件、访问公网或执行命令,插件化会直接变成权限失控。
7. 第五层:“一切皆插件”真正难在权限,不在安装
插件越多,系统越灵活。
但同时攻击面也越大。
所以插件系统必须带Capability声明。
plugin:
name: vision-reviewer
permissions:
- image.read
- model.invoke
network:
allow:
- api.example-model.com
filesystem:
read:
- /workspace/assets
write: []
secrets:
- VISION_PROVIDER_KEY
这样一个视觉插件只能读取素材并调用模型。
它没有权限修改代码,也不能访问任意网络。
8. 第六层:Context Engineering,1M上下文不等于“全塞进去”
DeepSeek V4已经把1M上下文作为默认能力。
但Harness仍然要做上下文选择。
因为Context越大,不代表有效信息比例越高。
@dataclass
class ContextItem:
source: str
relevance: float
freshness: float
token_count: int
content: str
def select_context(items, budget):
items = sorted(
items,
key=lambda x: 0.7 * x.relevance + 0.3 * x.freshness,
reverse=True,
)
result, used = [], 0
for item in items:
if used + item.token_count > budget:
continue
result.append(item)
used += item.token_count
return result
Context Engineering不是“拼Prompt”。
它更像一个实时信息调度系统。
CTX-404|DUMP_EVERYTHING
因为模型支持超长上下文就把全部文件、历史和日志塞进去,最终会同时增加噪声、延迟与成本。
9. 第七层:Plan → Execute → Verify,才是长任务真正的闭环
Harness最重要的设计,不是一次调用有多聪明。
而是失败以后还能不能继续。
async def run_task(state: TaskState):
while state.iteration < state.max_iterations:
if state.phase == Phase.PLAN:
state.plan = await planner(state)
state.phase = Phase.EXECUTE
elif state.phase == Phase.EXECUTE:
observation = await executor(state)
state.observations.append(observation)
state.phase = Phase.VERIFY
elif state.phase == Phase.VERIFY:
passed = await verifier(state)
if passed:
state.phase = Phase.DONE
return state
state.phase = Phase.PLAN
state.iteration += 1
state.phase = Phase.FAILED
return state
STEP 1|计划
先明确当前要做什么,避免模型一上来就直接操作。
STEP 2|执行
通过受控工具完成当前步骤,并保存Observation。
STEP 3|验证
检查任务是不是满足验收条件,而不是相信模型自己宣布完成。
STEP 4|继续
如果验证失败,根据新的Observation重新规划,而不是整条任务重来。
10. 第八层:Checkpoint解决“长任务中途断掉怎么办”
真正跑半小时以上的Agent,不可能保证永远不断线。
模型服务可能超时,工具可能失败,用户也可能关闭页面。
@dataclass
class Checkpoint:
task_id: str
goal: str
current_plan: list[str]
completed_steps: list[str]
important_context: list[str]
unresolved_errors: list[str]
next_action: str
恢复任务时,不需要重新把完整历史塞给模型。
只需要恢复继续工作必需的最小状态。
11. 第九层:模型路由,让Pro和Flash承担不同工作
Agent和普通对话最大的不同,是一个任务内部可以调用几十次模型。
如果每次都使用最贵模型,成本会快速放大。
def route_model(task_type: str, complexity: int):
if task_type in {
"summarize_file",
"classify",
"simple_tool_decision",
}:
return "deepseek-v4-flash"
if complexity <= 2:
return "deepseek-v4-flash"
return "deepseek-v4-pro"
主规划和复杂Debug可以使用Pro。
文件摘要、分类和简单子任务可以交给Flash。
12. 视觉Agent怎么做?重点仍然不是“换个多模态模型”
如果需要增加图片理解能力,可以增加一个Vision Adapter。
底层模型可以是任何符合接口的视觉模型。
class VisionAdapter:
async def analyze(
self,
image_uri: str,
instruction: str,
) -> dict:
result = await self.client.generate(
image=image_uri,
prompt=instruction,
)
return {
"summary": result.text,
"confidence": result.score,
}
真正重要的是Harness仍然统一负责权限、任务状态、工具调用与结果验证。
换模型只是Adapter层的事情。
13. 为什么这套架构也适用于多模型AI平台
如果平台只有聊天,聚合模型主要解决“选谁回答”。
当平台加入智能体、图片、视频、音频、漫剧和PPT以后,任务已经不再是一次调用。
它会变成多阶段工作流。
User Goal
↓
Task Planner
↓
Text Model
↓
Image / Video / Audio Model
↓
Asset Registry
↓
Quality Gate
↓
Final Deliverable
对于创源AIGC这类聚合500+模型,并同时提供智能体、无限画布、AI漫剧、AI PPT等能力的平台来说,下一阶段真正有技术价值的部分并不是继续把模型列表做长。
而是让不同模型通过统一Harness参与同一个任务。
Multi-Model Harness
├── Model Registry
├── Model Router
├── Plugin Runtime
├── Tool Registry
├── Task State
├── Asset Registry
├── Workflow DAG
├── Checkpoint
├── Quality Gate
└── Audit Log
14. 五个Harness系统最容易踩的坑
PLUGIN-101|PLUGIN_WITHOUT_PERMISSION
插件支持热插拔,但没有权限声明和隔离,扩展能力越多,安全风险越高。
STATE-202|NO_CHECKPOINT
Agent任务状态只保存在当前会话里,一旦中断就只能从头开始。
TOOL-303|SHELL_EVERYWHERE
所有工具最终都被实现成任意Shell命令,平台失去最小权限和审计能力。
CTX-404|CONTEXT_IS_STORAGE
把上下文窗口当数据库使用,不做筛选、压缩和状态持久化。
DONE-505|MODEL_SAYS_DONE
模型说任务完成就直接返回,没有独立Verifier确认验收条件。
15. 如果真要做一个Harness,建议从这4层开始
STEP 1|先做统一状态模型
不要先追求复杂插件市场,先保证Goal、Plan、Observation和Checkpoint能够可靠保存。
STEP 2|再做Tool Registry
把读、写、网络和执行能力显式拆开,建立最小权限模型。
STEP 3|然后做Verifier
没有独立验收的Agent,本质上只是会自动连续聊天。
STEP 4|最后做插件和多模型路由
等运行时稳定以后,再扩展视觉模型、第三方模型、办公插件与复杂Workflow。
16. 最后:Agent下一阶段拼的,可能真的不是模型
过去两年,我们习惯把AI产品差异归结为模型差异。
但Agent时代开始以后,越来越多体验差距会来自模型之外。
上下文怎么选。
工具怎么开放。
状态怎么保存。
任务怎么恢复。
结果怎么验收。
模型怎么分工。
这些才是Harness真正要解决的问题。
模型决定Agent的智力上限。
Harness决定这个上限能不能稳定地变成真实产出。
更多推荐


所有评论(0)