2026年8月13日,DeepSeek以MIT许可证开源了DeepSeek Harness(简称dsh),一个基于Cordis微内核的Agent运行时框架。它的架构宣言只有一句话:Everything is a Plugin。模型适配器、工具注册表、会话日志、Agent Loop本身甚至Web前端,全部是地位平等的插件。这不是又一个API聊天客户端,而是一套用于组装Agent的开源基础设施。本文从Cordis插件树、事件源会话、工具安全流水线、四种运行模式、多Agent编排和横向选型等维度,深度解析DeepSeek Harness如何重构Agent运行时。
一、Agent竞争的重心转移:从模型到Harness
1.1 为什么2026年Harness成为主角
早期LLM应用的典型形态是系统提示词加聊天历史再加一次API请求。工具调用出现后,应用需要在模型和现实世界之间反复循环:读文件、执行命令、检查输出、修改代码、跑测试,直到任务结束。此时决定成败的不再只是一段提示词,而是一套运行时制度。
|
演进阶段 |
应用重心 |
核心问题 |
Harness的回答 |
|
单轮对话 |
Prompt与生成质量 |
如何说清需求 |
系统提示词模板 |
|
工具调用 |
模型与API对接 |
如何调用、重试和解析 |
工具注册表与Agent Loop |
|
长程任务 |
跨多步保持状态 |
上下文溢出、中断、恢复 |
事件日志、压缩与持久化 |
|
多Agent协作 |
分工、回报与审核 |
队列、身份、资源和取消 |
子代理运行时与Workflow |
|
生产化 |
安全、观测和组织策略 |
Agent能碰什么、出错如何追责 |
审批、沙箱、回放与遥测 |
1.2 DeepSeek Harness的关键时间线
|
时间节点 |
事件 |
工程含义 |
|
2026年5月 |
DeepSeek官方招聘Agent Harness团队 |
目标不是维护API Demo,而是打通模型、产品反馈和Agent研究 |
|
2026年8月13日 |
deepseek-ai/deepseek-harness公开,MIT许可证 |
DeepSeek选择开放Harness层,让社区能替换模型、工具、沙箱和前端 |
|
2026年8月19日 |
版本迭代至v0.1.0-rc.8,12,940次提交 |
插件生态快速扩张,25位贡献者参与开发 |
|
2026年8月20日 |
社区插件生态启动,dsh-plugin话题开放 |
第三方插件可通过GitHub Topic被发现和安装 |
DeepSeek模型原本就能通过OpenAI或Anthropic兼容协议接入Claude Code、OpenCode等三方工具,因此能用DeepSeek写代码不是产品空白。真正缺失的是对Harness自身的控制权:模型看到什么上下文、如何编排子代理、什么反馈可以回流评测与训练。dsh的目标就是填补这一层。
二、Cordis微内核:不设特权内核的插件树
2.1 架构全景:五层插件堆叠
DeepSeek Harness基于Cordis框架构建。Cordis源自Koishi生态,其设计思想来自论文A Programming Paradigm for Spatiotemporal Composability。Cordis只做三件事:插件的加载、卸载和依赖管理。它本身不承载任何Agent能力,像个乐高底座板,只提供插口。
┌──────────────────────────────────────────────────┐
│ 产品入口层 │
│ Web UI · Headless · SDK · API Gateway │
├──────────────────────────────────────────────────┤
│ Agent运行层 │
│ Agent Loop · Session · Prompt · Scope · Compaction │
├──────────────────────────────────────────────────┤
│ 能力与策略层 │
│ Tools · Skills · MCP · LSP · Subagent · Approval │
├──────────────────────────────────────────────────┤
│ 执行与存储层 │
│ FS · Shell · PTY · Sandbox · SQLite/JSONL · OTel │
├──────────────────────────────────────────────────┤
│ 模型适配层 │
│ DeepSeek · OpenAI · Anthropic · 自定义兼容端点 │
└──────────────────────────────────────────────────┘
每一层都通过Cordis插件组合
这种架构的要点不是插件数量多,而是核心循环也没有特权。如果一个团队希望把本地文件系统和进程执行替换为远程沙箱,可以替换对应Service Provider;依赖这两项服务的Bash、PTY和LSP也会随之转移,而不需要复制一套Agent Loop。
2.2 Profile、Bundle与Patch:插件组合的三层配置
运行中的dsh是一棵按序叠加的插件树。profile是具名组装,bundle是可分发的插件配置包,cordis.patch.yml负责覆盖或插入配置。
|
组合对象 |
职责 |
官方默认 |
|
dsh-base |
模型、工具、持久化、沙箱、审批、凭据、遥测 |
所有profile的底座 |
|
dsh-web-app |
Web服务器与浏览器界面 |
web profile |
|
dsh-headless |
一次性执行器,不启动服务器 |
headless profile |
|
profile patch |
某个组装的本地差异 |
安装第三方插件、替换实现 |
|
home patch / --patch |
用户级或本次启动覆盖 |
环境策略和实验配置 |
同一套核心可以被组装为Web Agent、无头CI任务执行器、特定企业环境的受限Agent,或完全不同的前端产品。开发者可用命令查看最终组装结果:
dsh --profile web --dump-config
2.3 Capability Seam:可替换能力的三个角色
DeepSeek Harness把可替换能力称为seam,并拆成三个角色。这种拆分比把所有功能都做成一个工具插件更严格,要求开发者先明确能力边界,再分别处理实现与暴露。
|
角色 |
含义 |
以文件系统为例 |
|
Service Definition |
稳定接口和领域词汇 |
ctx.fs定义读写能力 |
|
Service Provider |
具体执行环境 |
本地FS、沙箱FS或E2B远程FS |
|
Consumer |
面向模型或用户的入口 |
读文件、编辑文件工具 |
三、四种运行模式深度拆解
DeepSeek Harness提供四种运行模式,每种模式对应不同的插件组合和工具集,覆盖从全功能编码到基准测试的完整场景。
|
运行模式 |
工具集 |
典型场景 |
核心特征 |
|
Standard模式 |
文件编辑、Shell、文件搜索、Web搜索、Skills、规划、目标、子代理、工作流 |
日常编码与复杂任务 |
全工具集,最通用 |
|
Code模式 |
Standard全部能力 + Code Mode SDK |
多步骤工具编排 |
模型生成TypeScript程序编排多轮操作 |
|
Minimal模式 |
仅Shell + str_replace_editor |
模型基准测试 |
最小环境,两工具编码Agent |
|
Creator模式 |
Standard全部能力 + 运行时检查 + 插件实验 |
自定义Agent预设 |
检查运行时、内存中测试Cordis插件 |
Minimal模式的设计意图尤为值得关注。它只保留两个工具——持久化bash和str_replace_editor——专门用于在最小环境中评估模型的真实编码能力,排除丰富工具集带来的性能偏差。这对模型评测和选型具有直接工程价值。
四、事件源会话:模型可见即已记录
4.1 Turn、Step与Tool Call的精确定义
DeepSeek Harness对一次任务的定义极其精确:一个step是一次模型请求及其触发的工具调用;一个turn包含零个或多个step,直到系统不再欠任何待处理工作才结束。
用户输入进入 inbox
↓
turn/start
↓
agent/pre-step:改写、拒绝或放行本次输入
↓
step/start → 组装 Prompt 与 Tool Schema
↓
agent/request → llm/stream → assistant/message
↓
tool/call → 审批/守卫/执行/后处理 → tool/result
↓
step/end
├─ 还有工具结果或新输入 → 下一个 step
└─ 没有待办 → turn/end
agent/pre-step、agent/request、llm/stream和工具前后处理都是可被插件拦截的waterfall事件。插件可以调用next()委托给下游,也可以短路并返回自己的决策。因此,压缩策略、请求重写、权限检查和遥测不需要修改Agent Loop源码。
4.2 事件域与持久化策略
|
事件域 |
是否持久化 |
用途 |
|
turn/*、step/* |
是 |
重建任务与步骤边界 |
|
user/message、assistant/* |
是 |
恢复模型可见对话与流式输出 |
|
tool/call、tool/result |
是 |
重放工具轨迹、校验调用结果配对 |
|
agent/* |
否(实时) |
inbox、状态、中途引导、重试和续跑 |
|
fs/*、tools/*等能力事件 |
按事件定义 |
把策略挂在能力边界上 |
事件源比每轮把整个会话JSON覆盖一次复杂,但它解决了Agent长程运行中最难的可观测性问题:界面上看到的输出、模型实际收到的上下文与磁盘上恢复的状态,理论上来自同一份事实。Resume、fork、search和replay都操作在同一条事件流上。
4.3 上下文压缩:原始事实不变,可见投影可变
长任务终将碰到上下文窗口。dsh-compaction-basic不直接改写旧日志,而是记录compaction/start、摘要、被遮蔽范围和compaction/end,再用一条新的user/message替换模型可见表层的某一段。完整历史仍然可用于审计,模型则看到压缩后的表层。
|
压缩维度 |
传统做法 |
dsh做法 |
工程优势 |
|
历史保存 |
覆盖旧messages |
仅追加compaction事件 |
原始事实可审计 |
|
模型可见 |
裁剪后的列表 |
压缩后的表层投影 |
上下文窗口可控 |
|
恢复方式 |
从最终状态重启 |
从事件流任意点fork |
支持分支探索 |
|
工具结果 |
直接截断 |
可选剪枝过大结果 |
减少信息损失 |
五、工具安全流水线:从tool/call到tool/result
5.1 六层工具执行流水线
模型生成一个tool call后,DeepSeek Harness不会立即调用工具函数。一次调用会通过前置策略、单调守卫、审批、执行包装、后置重写和结果归一化,最后才作为唯一模型可见结果写入会话。
tool/call 已记录
↓
tools/pre-execute
├─ deny → 跳过工具主体
├─ ask → 一次性用户审批
└─ allow
↓
单调守卫:只能加严,不能绕过既有拒绝
↓
tools/execute:超时、重试、指标 → 工具主体
↓
tools/post-execute:接受、屏蔽、替换或附加上下文
↓
结果序列化与不变式检查
↓
tool/result 已记录
单调守卫是一个关键设计:多个策略叠加时,后加的插件不应把前面的拒绝重新改成允许。否则,一个设置顺序就可能把安全策略变成偶然行为。
5.2 安全层对比矩阵
|
安全层 |
解决的问题 |
仍需注意的风险 |
|
Tool Schema |
参数类型与结果格式 |
Schema正确不等于操作安全 |
|
Approval |
高风险动作是否经人确认 |
频繁弹窗会造成审批疲劳 |
|
Guard(单调守卫) |
组织策略与终态拒绝 |
需测试插件组合后的实际行为 |
|
Sandbox |
限制进程对文件和系统的影响 |
平台后端的强制能力并不完全相同 |
|
Event Log |
追踪模型说了什么、调了什么 |
可追责不等于事前防护 |
|
Result Normalization |
防止异常输出污染上下文 |
归一化规则需与业务对齐 |
5.3 沙箱失败即关闭原则
Harness的沙箱层把策略和后端分开。策略描述工作区边界和执行模式,后端则把命令包装为具体平台的受限进程。对于声明为受限的执行,如果没有可用后端,系统必须报SANDBOX_UNAVAILABLE,不允许静默退化为无沙箱运行。这是安全设计中的失败安全原则。
六、多Agent编排:Skills、Subagent与Workflow
6.1 Skills:按需加载的过程知识
dsh支持从项目级.dsh/skills、.agents/skills、用户目录、自定义目录和绑定资源中发现Skill。模型初始只看到名称和描述,需要时再读取完整SKILL.md,避免把所有操作手册一次性塞进上下文。项目级Skill可覆盖用户级同名Skill,每个候选项都记录来源和Provider,目录变化会使缓存失效。
|
Skill特征 |
工程价值 |
对比传统Prompt |
|
按需加载 |
初始只暴露名称和描述 |
避免上下文膨胀 |
|
分层覆盖 |
项目级覆盖用户级同名Skill |
支持环境差异化 |
|
来源追踪 |
每个候选项记录Provider |
可审计、可回溯 |
|
缓存失效 |
目录变化自动刷新 |
保证Skill时效性 |
6.2 Subagent:多种后端的子代理运行时
ctx.subagents后面可同时注册多种Provider。官方代码包已包含进程内spawn、继承父历史的fork、ACP、Codex、Claude Code和dsh SDK等后端。这意味着协调者可以把任务交给另一个dsh Agent,也可以把Codex或Claude Code当作外部子代理。
|
子代理能力 |
工程价值 |
|
一次性子代理 |
把边界清晰的研究、实现或审查任务独立执行 |
|
可继续子代理 |
保留子会话ID,可多轮追加消息或冷恢复 |
|
Persona与Tool Filter |
限定子代理角色与可见工具,减少误用 |
|
结构化输出 |
让上层编排获取稳定JSON,而非从自然语言中猜测 |
|
直接父级授权 |
followup、interrupt和report围绕持久化谱系校验 |
6.3 Workflow:模型生成的受限编排程序
Workflow seam允许模型生成JavaScript编排脚本,再由Worker Thread中的VM执行。脚本可串行或并行启动子代理,上报阶段和进度,并返回纯JSON结果。引擎可限制总子代理数,取消后会在有界宽限期内终止脚本并等待child清理。核心不是让模型随便写段JS,而是把复杂编排从一连串自然语言tool call转换为可表达并行、管道和错误处理的程序。
6.4 MCP、ACP与LSP的边界划分
|
协议/能力 |
在dsh中的位置 |
解决什么边界 |
|
MCP |
接入外部工具与资源 |
扩大Agent能做什么 |
|
ACP |
连接外部Agent运行时 |
可作为子代理传输 |
|
LSP |
从编程语言服务器获取信息 |
定义、引用和诊断 |
|
Skill |
按需加载任务方法 |
领域知识和规则 |
|
Plugin |
改变Harness本身 |
服务、策略、工具或UI |
七、Python实战:dsh会话日志解析与MCP工具服务
DeepSeek Harness的会话日志采用仅追加的JSONL格式,每个SessionEvent都是一条独立JSON记录。以下Python代码实现了dsh会话日志的解析、工具调用轨迹提取和Token消耗分析,可用于CI/CD流水线中的Agent行为审计。
7.1 dsh会话日志解析器
import json
from pathlib import Path
from collections import defaultdict
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class ToolCallRecord:
tool_name: str
step_index: int
turn_index: int
duration_ms: Optional[float] = None
success: bool = True
input_summary: str = ""
output_summary: str = ""
@dataclass
class SessionAnalysis:
total_turns: int = 0
total_steps: int = 0
total_tool_calls: int = 0
tool_calls: list = field(default_factory=list)
compaction_events: int = 0
error_count: int = 0
token_usage: dict = field(default_factory=lambda: defaultdict(int))
class DSHSessionParser:
"""解析dsh仅追加会话日志(JSONL格式)的解析器"""
EVENT_TYPES = {
"turn/start": "turn", "turn/end": "turn",
"step/start": "step", "step/end": "step",
"tool/call": "tool", "tool/result": "tool",
"compaction/start": "compaction", "compaction/end": "compaction",
"assistant/message": "message",
"user/message": "message",
}
def __init__(self, log_path: str):
self.log_path = Path(log_path)
self.events = self._load_events()
def _load_events(self) -> list:
events = []
with open(self.log_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line:
events.append(json.loads(line))
return events
def analyze(self) -> SessionAnalysis:
analysis = SessionAnalysis()
turn_idx = 0
step_idx = 0
pending_tool_calls = {}
for event in self.events:
etype = event.get("type", "")
category = self.EVENT_TYPES.get(etype, "")
if etype == "turn/start":
turn_idx += 1
elif etype == "step/start":
step_idx += 1
elif etype == "tool/call":
tool_name = event.get("tool", "unknown")
call_id = event.get("callId", str(len(pending_tool_calls)))
pending_tool_calls[call_id] = ToolCallRecord(
tool_name=tool_name,
step_index=step_idx,
turn_index=turn_idx,
input_summary=str(event.get("input", ""))[:200],
)
elif etype == "tool/result":
call_id = event.get("callId", "")
record = pending_tool_calls.pop(call_id, None)
if record:
record.output_summary = str(event.get("output", ""))[:200]
record.success = not event.get("error", False)
record.duration_ms = event.get("durationMs")
analysis.tool_calls.append(record)
elif etype == "compaction/start":
analysis.compaction_events += 1
elif etype == "assistant/message":
usage = event.get("usage", {})
for key in ["prompt_tokens", "completion_tokens"]:
if key in usage:
analysis.token_usage[key] += usage[key]
analysis.total_turns = turn_idx
analysis.total_steps = step_idx
analysis.total_tool_calls = len(analysis.tool_calls)
analysis.error_count = sum(1 for tc in analysis.tool_calls if not tc.success)
return analysis
def generate_report(self, analysis: SessionAnalysis) -> str:
lines = ["=" * 60, "DeepSeek Harness Session Analysis Report", "=" * 60]
lines.append(f"Total Turns: {analysis.total_turns}")
lines.append(f"Total Steps: {analysis.total_steps}")
lines.append(f"Tool Calls: {analysis.total_tool_calls}")
lines.append(f"Failed Calls: {analysis.error_count}")
lines.append(f"Compaction Events: {analysis.compaction_events}")
lines.append("")
lines.append("Token Usage:")
for key, val in analysis.token_usage.items():
lines.append(f" {key}: {val}")
lines.append("")
lines.append("Tool Call Trace:")
for tc in analysis.tool_calls:
status = "OK" if tc.success else "FAIL"
lines.append(f" [T{tc.turn_index}/S{tc.step_index}] {tc.tool_name} ({status})")
return "\n".join(lines)
这段代码将dsh的JSONL会话日志解析为结构化的SessionAnalysis对象,支持工具调用轨迹追踪、Token消耗统计和压缩事件计数。在CI/CD流水线中,可用它生成Agent行为审计报告,定位失败的工具调用和异常的Token消耗模式。
7.2 Python MCP工具服务:为dsh扩展自定义工具
dsh通过MCP协议接入外部工具。以下Python代码实现了一个MCP工具服务,为dsh提供代码质量检查能力,展示了如何用Python为dsh扩展自定义工具集。
import asyncio
import json
import subprocess
from pathlib import Path
from typing import Any
class MCPToolServer:
"""为DeepSeek Harness提供MCP协议工具服务的Python实现"""
TOOLS_SCHEMA = {
"check_code_quality": {
"description": "Run linter and type checker on a Python file",
"parameters": {
"type": "object",
"properties": {
"file_path": {"type": "string", "description": "Path to Python file"},
"checks": {
"type": "array",
"items": {"type": "string", "enum": ["ruff", "mypy", "pylint"]},
"default": ["ruff", "mypy"],
},
},
"required": ["file_path"],
},
},
"run_test_suite": {
"description": "Execute pytest with coverage for a directory",
"parameters": {
"type": "object",
"properties": {
"test_dir": {"type": "string", "description": "Test directory path"},
"coverage": {"type": "boolean", "default": True},
"parallel": {"type": "boolean", "default": False},
},
"required": ["test_dir"],
},
},
"analyze_dependencies": {
"description": "Parse import statements and build dependency graph",
"parameters": {
"type": "object",
"properties": {
"root_dir": {"type": "string", "description": "Project root directory"},
},
"required": ["root_dir"],
},
},
}
async def handle_tool_call(self, tool_name: str, args: dict) -> dict:
if tool_name == "check_code_quality":
return await self._check_quality(args)
elif tool_name == "run_test_suite":
return await self._run_tests(args)
elif tool_name == "analyze_dependencies":
return await self._analyze_deps(args)
return {"error": f"Unknown tool: {tool_name}"}
async def _check_quality(self, args: dict) -> dict:
file_path = Path(args["file_path"])
checks = args.get("checks", ["ruff", "mypy"])
results = {}
for checker in checks:
cmd = self._build_checker_cmd(checker, file_path)
proc = await asyncio.create_subprocess_exec(
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await proc.communicate()
results[checker] = {
"exit_code": proc.returncode,
"output": stdout.decode()[:2000],
"errors": stderr.decode()[:2000] if stderr else "",
}
return {"file": str(file_path), "results": results}
async def _run_tests(self, args: dict) -> dict:
test_dir = args["test_dir"]
cmd = ["python", "-m", "pytest", test_dir]
if args.get("coverage"):
cmd.extend(["--cov", "--cov-report=term-missing"])
if args.get("parallel"):
cmd.append("-n", )
proc = await asyncio.create_subprocess_exec(
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await proc.communicate()
return {
"exit_code": proc.returncode,
"summary": stdout.decode()[-1000:],
"errors": stderr.decode()[:1000] if stderr else "",
}
async def _analyze_deps(self, args: dict) -> dict:
root = Path(args["root_dir"])
graph = {}
for py_file in root.rglob("*.py"):
imports = self._extract_imports(py_file)
if imports:
graph[str(py_file.relative_to(root))] = imports
return {"dependency_graph": graph, "total_files": len(graph)}
def _build_checker_cmd(self, checker: str, file_path: Path) -> list:
commands = {
"ruff": ["ruff", "check", str(file_path)],
"mypy": ["mypy", str(file_path)],
"pylint": ["pylint", str(file_path)],
}
return commands.get(checker, [])
def _extract_imports(self, file_path: Path) -> list:
imports = []
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line.startswith("import ") or line.startswith("from "):
imports.append(line)
return imports
if __name__ == "__main__":
server = MCPToolServer()
print("MCP Tool Server ready for dsh integration")
print(f"Available tools: {list(server.TOOLS_SCHEMA.keys())}")
这个MCP工具服务实现了代码质量检查、测试套件执行和依赖分析三个工具。dsh通过MCP协议接入后,模型可以在Agent Loop中直接调用这些工具,实现编码质量门禁的自动化。关键设计是将工具的执行逻辑与Schema声明分离,便于在dsh的tools/pre-execute和tools/post-execute流水线中插入安全策略。
八、横向对比矩阵:dsh vs Claude Code vs Codex vs OpenCode
8.1 架构维度对比
|
对比维度 |
DeepSeek Harness (dsh) |
Claude Code |
Codex CLI |
OpenCode |
|
开源许可 |
MIT |
proprietary |
MIT |
Apache 2.0 |
|
架构哲学 |
一切皆插件 |
一体化设计 |
工具链集成 |
模块化设计 |
|
微内核 |
Cordis |
无 |
无 |
无 |
|
插件体系 |
全能力可替换 |
MCP工具扩展 |
配置扩展 |
插件系统 |
|
会话模型 |
事件源(append-only) |
消息列表 |
消息列表 |
消息列表 |
|
上下文压缩 |
不改原始日志 |
截断历史 |
截断历史 |
摘要替换 |
|
沙箱策略 |
失败即关闭 |
内置限制 |
Docker隔离 |
进程限制 |
|
子代理 |
多后端(dsh/Codex/Claude) |
不支持 |
不支持 |
有限支持 |
|
模型绑定 |
不绑定(多provider) |
绑定Anthropic |
绑定OpenAI |
多provider |
|
语言构成 |
TypeScript 97.1% |
TypeScript |
Rust |
Go |
8.2 能力维度对比
|
能力维度 |
dsh |
Claude Code |
Codex |
OpenCode |
|
运行模式数 |
4种(Standard/Code/Minimal/Creator) |
1种 |
1种 |
2种 |
|
Workflow编排 |
模型生成JS脚本 |
无 |
无 |
无 |
|
Skills按需加载 |
支持(分层覆盖) |
有限 |
无 |
无 |
|
会话回放 |
事件流fork/replay |
无 |
无 |
无 |
|
凭据管理 |
脱敏存储+引用 |
环境变量 |
环境变量 |
配置文件 |
|
遥测集成 |
OTel原生 |
无 |
无 |
有限 |
|
Profile系统 |
Profile+Bundle+Patch |
无 |
无 |
无 |
|
MCP支持 |
原生 |
支持 |
无 |
支持 |
|
ACP支持 |
原生 |
无 |
无 |
无 |
|
LSP集成 |
原生 |
无 |
无 |
无 |
8.3 差异化定位分析
|
维度 |
dsh真正的差异点 |
工程含义 |
|
插件化深度 |
连Agent Loop和会话日志都是插件 |
扩展不需要修改源码 |
|
事件源会话 |
模型可见即已记录 |
可审计、可回放、可分支 |
|
单调守卫 |
安全策略只能加严不能放松 |
防止插件组合导致安全降级 |
|
多后端子代理 |
可调度Codex和Claude Code作为子代理 |
跨框架编排能力 |
|
Profile组合 |
同一核心可组装为不同产品 |
一套代码多种部署形态 |
九、企业落地路径与风险边界
9.1 企业采纳的四个阶段
|
阶段 |
目标 |
关键动作 |
风险控制 |
|
评估期 |
理解dsh架构与能力边界 |
Minimal模式跑基准测试 |
隔离环境运行 |
|
试点期 |
在非核心项目中验证 |
Standard模式+自定义Skill |
审批策略全开 |
|
集成期 |
接入企业工具链 |
开发MCP工具服务+Profile配置 |
供应链审查 |
|
生产期 |
规模化部署与监控 |
OTel遥测+事件流审计 |
沙箱强制+凭据隔离 |
9.2 风险矩阵
|
风险类别 |
具体风险 |
缓解策略 |
|
供应链风险 |
第三方插件可能位于凭据和命令的关键路径上 |
固定版本、保留物料清单、审查权限声明 |
|
兼容性风险 |
开发者预览阶段有破坏性变更 |
锁定rc版本,建立升级回归测试 |
|
安全配置风险 |
插件组合可能导致安全策略被绕过 |
测试单调守卫行为,审计tools/pre-execute链 |
|
沙箱逃逸风险 |
平台后端强制能力不完全相同 |
生产环境强制SANDBOX_UNAVAILABLE失败即关闭 |
|
上下文管理风险 |
压缩策略可能丢失关键信息 |
审计compaction事件,验证模型可见投影 |
9.3 生产化部署建议
- 凭据边界:DSH_HOME目录权限限制为600,.credentials.yaml加密存储,设置层只保留引用
- 沙箱策略:生产环境声明所有执行为受限模式,配置landlock或Docker后端,禁止SANDBOX_UNAVAILABLE静默降级
- 遥测接入:启用OTel导出,将turn/step/tool事件流接入企业可观测性平台
- 插件供应链:建立插件物料清单(CBOM),版本固定+签名验证+定期安全扫描
- Profile管理:使用cordis.patch.yml管理企业策略,不修改dsh-base源码
- 会话审计:定期分析JSONL会话日志,使用解析器提取工具调用轨迹和Token消耗模式
十、总结
|
维度 |
核心要点 |
|
产品定位 |
dsh是开源Agent运行时,不是API封装或编程客户端 |
|
架构核心 |
Cordis将Agent Loop、Session、Tool、模型适配器和UI组装为可替换插件树 |
|
状态模型 |
仅追加事件日志作为会话真相来源,压缩改变可见投影而不删除原始事实 |
|
安全路径 |
工具调用经过审批、单调守卫、沙箱、前后置策略和结果归一化 |
|
多Agent编排 |
Skills按需加载、Subagent多后端、Workflow模型生成JS编排 |
|
模型无关 |
不绑定DeepSeek,支持OpenAI/Anthropic/自定义兼容端点 |
|
四种模式 |
Standard/Code/Minimal/Creator覆盖全场景 |
|
生态阶段 |
MIT许可证开发者预览,12,940次提交,25位贡献者活跃迭代 |
DeepSeek Harness的真正赌注不是做一个更好的Claude Code,而是开放模型之外的实验室。当模型、工具、沙箱、会话日志和Agent Loop都可以被替换和重组时,DeepSeek把Agent工程的核心矛盾——能力上限由模型决定,但能力下限由运行时决定——摆在了台面上。对于企业AI团队来说,dsh值得在评估期认真对待:即使不在生产中使用它,它的架构设计也为自建Agent运行时提供了高价值的参考框架。
紫宸策 | GEO咨询与企业AI落地实践
公众号:紫宸策

367

被折叠的 条评论
为什么被折叠?



