DeepSeek Harness · 框架研究学习与实践指南 -- 以猫狗图片识别为例 (进阶:增加了token权限,spwarm批量处理图片,自定义服务的理解和应用)
DeepSeek Harness · 框架研究学习与实践指南 – 以猫狗图片识别为例 (进阶:增加了token权限,spwarm批量处理图片,自定义服务的理解和应用)
学习型项目 · 研究 · 实践
从一句话需求,到一套能跑、可验证、可复盘的 Cordis 插件系统 —— 用"搭建一个真实系统"的方式,彻底理解 dsh 框架「一切皆插件」的架构思想。
- 交付物:web 系统 + dsh 插件 + ds-v4-flash API
- 运行地址:
http://127.0.0.1:3080- 插件:
cat-dog-classify-plugin- 数据:50 猫图 + 50 狗图,批量识别 100% 正确;REQ-001 的 24 用例全过,REQ-002 增量后 47 用例全过(含权限门 / ctx.classifier 服务 / zip 批量多 Agent)
目录
1. 项目定位:为什么要做这个系统
DeepSeek Harness(dsh)是 DeepSeek AI 开源的 Agent 编排框架,核心口号只有五个字——一切皆插件:模型适配器、工具注册表、会话日志、HTTP 服务、Agent 主循环,都是插件。
本项目(猫狗识别)正是为理解这套思想而设计的:功能足够简单(上传图片 → 输出"猫"/“狗”),却要求你亲手走完插件开发的完整闭环——注册模型工具、注册 HTTP 路由、装配进 profile、验证插件树,并用真实 API 完成全链路联调。
📌 框架知识点(贯穿全程的核心概念)
插件(Plugin)→ 上下文(Context)→ 服务(Service)→ 可逆注册(Effect)→ 装配层(Patch)。
理解这五个概念,就理解了 dsh 插件化设计的骨架。
两条学习入口(同一份能力,两个入口)
| 入口 | 面向对象 | 走哪个管道 |
|---|---|---|
HTTP 接口 /api/cat-dog-classify | 浏览器页面 | 裸 node:http 处理器,插件自解析 multipart |
模型工具 classify_pet_image | harness 会话中的 Agent | dsh 工具管道(校验/权限/执行/日志由框架统一处理) |
关键设计决策:两个入口复用同一个 ClassifierService 业务实例,业务逻辑只写一遍,互不复刻。
2. 制作过程:8 个阶段的完整旅程
这条旅程把"需求 → 设计 → UE → 规则 → 测试 → 插件 → 联调 → 验证"串成一条可复制的学习路线,每一步都产出可检验的文档或代码。
第 0 步:先想清楚,你要学什么
- 产出:明确的目标与学习对象
- 明确 dsh 是什么、为什么学它;项目定位为"通过构建一个小系统来理解插件框架"。此阶段没有文件,却决定了后续所有技术选型的基调。
第 1 步:把一句话需求变成规格
- 产出:
doc/req-001-spec.md FR-1~FR-7|NFR-1~NFR-5|AC-1~AC-7- 需求原文仅一句:“web 系统 + dsh 插件连接 ds-v4-flash API,识别猫狗图片”。学习型项目的第一课是先文档后代码:把模糊想法拆成功能需求、非功能需求、可检验的验收标准,并约定三条约束(插件优先 / 指令源唯一 / 以官方文档为准)。
📌 框架知识点
dsh 处于开发者预览阶段,API 可能变动。规格里预留"以安装版本官方文档为准"的兜底条款,并把
dsh --profile web --dump-config的插件树输出作为最终验收依据 —— 这比任何文档都真实。
第 2 步:技术设计:搭建系统骨架
- 产出:
doc/tech-design-spec.md 分层架构|双入口复用|错误码表- 设计文档回答三个关键问题:分层架构(表现层/能力层/服务层/接入层)、双入口复用(工具与路由共享同一份
ClassifierService)、错误码表(INVALID_IMAGE(400)、FILE_TOO_LARGE(413)、MODEL_TIMEOUT(504)、MODEL_AUTH_ERROR(502)、RESULT_PARSE_ERROR(502))。这张错误码表后来被"一处定义、处处引用"——设计文档、规则、前端、路由、测试用例全部一致。
第 3 步:UE 设计先行,原型即页面
- 产出:
doc/ue-design-spec.md→web/index.html 单页 5 区域|状态机 5 态|错误映射- 流程值得学习:先出 UE 设计文档,人工确认后,才动手生成原型。单页 5 区域(标题→上传→操作→结果→页脚),视觉规范主色
#4D6BFE呼应 DeepSeek 品牌,emoji 图标、零外部依赖(符合最小实现)。交互状态机idle → preview → loading → success/error,5 个错误码逐一映射为友好中文提示。
web/index.html 单文件(HTML + 内联 CSS + 原生 JS):fetch POST /api/cat-dog-classify、FormData 字段 image、AbortController 60s 超时、所有动态文本 textContent 渲染(零 innerHTML 拼接模型输出)、loading 中换图会中止旧请求。
📌 框架知识点
页面是纯静态文件,最终由 dsh web 服务的 HTTP 层承载(插件注册路由把它挂出来)。所以前端不用自己起服务,接口与页面天然同源 —— 这正是"web 系统 + 插件"一体化的含义。
第 4 步:给 AI 协作者立规矩
- 产出:
AGENTS.md+.qoder/rules/ 行为规范|权限清单|规则索引- 学习型项目里 AI 是最主要的协作者。AGENTS.md 定义行为规范(插件优先、最小实现、验证优先)、工具使用权限、插件加载策略、工作流约束与"关键事实速查表";.qoder/rules/ 提供四个按场景分工的规则(coding-standards、plugin-rules、api-contract、service-workflow),AGENTS.md 维护规则索引。
📌 框架知识点
配置文件也是学习框架的窗口 —— AGENTS.md 会被 dsh 加载这件事,本身就是"一切皆插件"的体现:指令加载是插件、技能发现是插件、规则消费也是插件。
第 5 步:测试用例先行
- 产出:
test/test-cases.md+ 100 张测试图 TC-01~TC-24|LLM 可自动执行|PASS/FAIL/BLOCKED- 在写插件之前先把验收合同定下来,并把它升级成 LLM 可自动执行的规格:每条用例结构化(编号/依赖/执行方式/可复制命令/精确断言/判定规则),判定仅三种输出 PASS / FAIL / BLOCKED(前提不满足不算失败)。测试数据:50 张猫图 + 50 张狗图,另加非法格式/超限文件的现场构造指令。写用例的过程就是反向梳理设计的过程。
第 6 步:插件开发:本旅程的核心
- 产出:
plugins/cat-dog-classify-plugin/(四文件)+ 装配层 classifier.ts|tool.ts|route.ts|index.ts
先调研 API 再动手写码。 三个可靠信息源:官方文档与社区教程、npm 包的类型定义(.d.ts 就是最精确的 API 文档)、运行时验证(dsh --dump-config 看真实插件树)。
四个源文件的分工
| 文件 | 角色 | 要点 |
|---|---|---|
classifier.ts | 纯业务,零框架依赖 | 校验 → base64 编码 → 提示词组装 → OpenAI 兼容调用(temperature=0、60s 超时)→ 归一化为"猫/狗"(歧义不猜测 → 抛 RESULT_PARSE_ERROR)。零依赖便于直接单测 |
tool.ts | 模型工具 classify_pet_image | defineTool 声明 schema;required 是每属性的 required: true,不是 JSON Schema 的数组;工具只写业务 |
route.ts | HTTP 路由 | 裸 node:http 语义,手工解析 multipart(boundary 切分 + Content-Disposition 提取 + 大小上限);错误码 → HTTP 状态映射(400/413/504/502) |
index.ts | 装配入口 apply(ctx) | inject = ['tools'] 必需依赖;ctx.effect 可逆注册工具;ctx.inject(['webServer']) 声明可选路由依赖 |
装配:让插件进入插件树
dsh 的插件树由多层 patch 叠加:bundle 层 → profile 的 cordis.patch.yml → --patch 覆盖层。本项目把装配写进项目根 dsh-patch.yml:
# dsh-patch.yml
- insert:
- id: cat-dog-classify
name: 'file:///D:/szp/work/deepseek-harness/plugins/cat-dog-classify-plugin/index.ts'
并更新唯一指令源 command/start-web-command.md;用 dsh --profile web --dump-config 验证插件树中可见 id: cat-dog-classify。
⚠️ 联调必踩的两个坑
① 模型名坑:设计文档里的占位名
ds-v4-flash-version会 400。需先用密钥调GET /models探测真实模型列表,得到deepseek-v4-flash-vision-exp(vision 多模态版)。② 推理预算坑:该模型是推理模型,
max_tokens=32会让推理 token 吃光预算、content为空,实测需max_tokens=1024。→ 通过环境变量DS_MODEL覆盖模型名,密钥只走DS_API_KEY。
第 7 步:全链路验证:24 用例全过
- 产出:验证报告(API 批量 / UI 自动化 / 异常注入 / Agent 工具调用)
100% 正确|单张 ~2s|异常可构造
API 批量验证:100 张测试图逐张过 POST /api/cat-dog-classify,猫 50/50、狗 50/50,100% 正确,单张延迟约 2 秒。UI 浏览器自动化:逐条断言空态→预览→非法类型/超限拒绝→"识别中…“→成功展示。异常注入:把 DS_API_BASE 指向不可路由地址→504;去掉 DS_API_KEY→502;停服→前端"无法连接识别服务”。
📌 框架能力的最终证明
在 headless profile 会话中给 Agent 下达任务"识别 test/images/cat/cat_001.jpg 是猫还是狗",Agent 自主完成:读文件 → base64 编码 → 调用
classify_pet_image→ 得到"识别结果:猫" → 回答"猫"。你写的工具,被另一个 AI 当成了它的手。
第 8 步:复盘:框架知识地图
- 产出:概念全景与进阶方向(详见第 5 部分)
- 把整个旅程对照框架概念做一次收束,形成可迁移到任何 dsh 插件开发任务的方法论,并指出进阶方向(事件钩子、自定义服务、正式发布为 npm 包、MCP 接入、多 Agent)。
第 9 步:REQ-002 进阶实战(从 24 到 47 条用例)
- 产出:
doc/req-002-spec.md+doc/tech-design-002.md+doc/ue-design-spec.mdv2 +test/test-cases.mdv3 + 插件扩展(service.ts/guard.ts/zip.ts/orchestrator.ts/report.ts) FR-8~FR-10|AC-8~AC-14|TC-25~TC-47|47/47通过
REQ-001 交付后,用同一系统做增量升级,刻意引入框架的三个进阶能力:
- token 权限门(FR-8):用框架权限层而非业务代码拦截识别——
ctx.tools.guard()做不可撤销的最终否决,tools/pre-execute事件做瀑布式审计;HTTP 层校验X-Auth-Token头。校验失败即不发起模型调用。 - ctx.classifier 服务(FR-9):把识别核心包成
Service子类(super(ctx, 'classifier')+declare module类型增补),消费方统一inject: ['classifier']获取,Provider 可替换 → 能力缝三角色打通。 - zip 批量 + 多 Agent(FR-10):零依赖手写 zip 解析(stored/deflate、三重炸弹防护)→ 父 Agent 切片后
ctx.subagents.start('fork', { parent, capabilities: { toolFilter } })派发子 Agent 逐张识别 → 父侧report.ts守恒校验、字典序排序、双呈现汇总报告;与工具classify_zip_images+ HTTPPOST /api/cat-dog-classify-batch双入口打通。
📌 框架知识点(进阶)
tools/pre-execute(waterfall 权限门) |ctx.tools.guard()|Service子类 + 能力缝 |ctx.subagents.start('fork'/'spawn')|SubagentRun.result|ctx.agents.create()+ AgentHandle |capabilities.toolFilter。这些概念把一个"单机插件"升级为"可编排的插件系统"。
3. 工程结构:目录、架构与分工
一份可导航的代码库地图,从总目录到文件分工,看懂"哪个文件负责什么"。
3.1 总目录结构
deepseek-harness/
├── AGENTS.md # Agent 行为准则(dsh 指令插件自动加载)
├── dsh-patch.yml # 装配层:把插件插入 dsh web profile 插件树
├── command/
│ └── start-web-command.md # 启动命令唯一指令源
├── doc/ # 文档区
│ ├── readme.md # 代码库导航入口
│ ├── ds-harness-doc.md # 框架官方文档链接
│ ├── req-001.md # 原始需求(一句话需求)
│ ├── req-001-spec.md # 需求规格说明书 REQ-001
│ ├── req-002-spec.md # 增量需求规格说明书 REQ-002(FR-8~10)
│ ├── tech-design-spec.md # 技术详细设计 TECH-DESIGN-001
│ ├── tech-design-002.md # 增量技术设计 TECH-DESIGN-002(含 SPIKE 结论)
│ ├── ue-design-spec.md # 用户体验设计(v2:凭证/批量/报告)
│ ├── impl-plan-002.md # REQ-002 实施方案
│ └── coach/ # 教练式指南
│ ├── guide.md # 从 0 构建的学习指南(步骤式)
│ └── ds-harness-framework-dogcatclassify-research-study-practice.md # 本文档
├── plugins/
│ └── cat-dog-classify-plugin/ # 核心交付物:猫狗识别 dsh 插件
│ ├── index.ts # 插件入口:apply(ctx) 注册服务 + 权限门
│ ├── classifier.ts # 识别核心(零依赖)
│ ├── service.ts # ctx.classifier 服务(FR-9:Service 子类 + 类型增补)
│ ├── guard.ts # FR-8 token 权限门(tools.guard + pre-execute 审计)
│ ├── tool.ts # classify_pet_image + classify_zip_images 工具
│ ├── route.ts # /api/cat-dog-classify + /batch + 页面路由(含 token 头校验)
│ ├── zip.ts # FR-10 最小 zip 解析(stored/deflate + 炸弹防护)
│ ├── orchestrator.ts # FR-10 多 Agent 编排(fork/spawn 派发子 Agent)
│ ├── report.ts # FR-10 批量报告生成(守恒校验/排序/双呈现)
│ ├── cordis.patch.yml # 插件装配描述(bundle patch)
│ ├── package.json # 包元信息(dsh.bundle 声明)
│ └── tsconfig.json # TypeScript 配置
├── web/
│ └── index.html # 前端单页(原生 HTML+JS,无构建链)
├── test/
│ ├── test-cases.md # 测试用例集 TEST-001 v3(47 用例,LLM 可执行)
│ ├── images/{cat,dog}/ # 各 50 张测试图片
│ └── data/zip/ # REQ-002 zip 夹具(valid/mixed/many/bomb/empty/not_zip)
├── .qoder/
│ ├── rules/ # 项目规则(改代码前必读)
│ └── skills/start-web-service/ # 启停服务项目级技能
└── .test-loop/ # 文档驱动测试的循环记录(产物)
3.2 分层架构
识别能力的分层设计,从浏览器到模型 API 一共四层,各层职责清晰、边界明确:
表现层 Web 页面(上传 / 预览 / 结果展示)
│ HTTP POST /api/cat-dog-classify
▼
能力层 dsh 插件 cat-dog-classify-plugin
├─ 模型工具 classify_pet_image
└─ HTTP 路由 /api/cat-dog-classify
│ 复用同一实例
▼
服务层 识别核心 ClassifierService
├─ 图片校验/编码
└─ 提示词组装/结果解析
│ OpenAI 兼容接口(图片 base64)
▼
接入层 ds-v4-flash 系列多模态 API(deepseek-v4-flash-vision-exp)
REQ-002 在此基础上加密两层:权限门(凭证校验 gate → guard)悬在能力层与服务层之间,未过校验不触达模型;批量识别(zip → 多 Agent → 报告)在能力层新增一组编排管线,识别仍复用服务层的 ctx.classifier。
3.3 端到端数据流
web/index.html ──POST /api/cat-dog-classify──▶ cat-dog-classify-plugin ──▶ ds-v4-flash API
▲ │
└────────── 识别结果 {"result":"猫"|"狗"} ────────┘
同时:Agent 会话 ──ctx.tools──▶ classify_pet_image 工具(复用同一识别逻辑)
REQ-002 批量链路:
web/index.html ──POST /api/cat-dog-classify-batch──▶ guard 校验 token ▶ zip.ts 解压/炸弹防护
│ ▶ orchestrator.ts: 父 Agent 切片
│ └─ctx.subagents.start('fork')──▶ 子 Agent──classify_pet_image──▶ ctx.classifier──▶ ds-v4-flash
└── 报告 report.ts(守恒校验/字典序/双呈现) ◀── 子 Agent 回传 ├ 逐张 struct + summary + orchestration
3.4 装配层(插件如何"插进"框架)
| 文件 | 作用 |
|---|---|
dsh-patch.yml | 顶层装配:--patch overlay 把本地插件插入 web profile 插件树(用 file:///D:/... URL) |
cordis.patch.yml | 插件自带 bundle patch,声明插件 id 与依赖服务(webServer、tools) |
package.json | dsh.bundle.patch 字段关联装配文件;依赖 @deepseek-ai/cordis、dsh-tools、dsh-host-webserver |
3.5 装配与前后置拦截(REQ-002)
REQ-002 引入两类装配扩展,让框架层替业务代码做控制:
| 机制 | 挂载点 | 作用 |
|---|---|---|
tools.guard | 工具执行路径 | 对 classify_pet_image / classify_zip_images 做不可撤销最终否决(token 缺失/无效直接拒绝) |
tools/pre-execute | 瀑布事件 | 每次工具执行前做一次审计,next() 放行、拦截则中止;配合 guard 形成双保险 |
📌 框架知识点
guard 与
pre-execute都属于工具执行前的拦截管线:guard 是硬闸(最终否决、不随上下文撤销),事件是软管线(可组合多个审计者)。二者都不需要业务代码感知,这正是“用框架层而非业务代码控制”的含义。
4. 项目构建结果:验收、测试与踩坑
用可验证的数字与清单,说明"这套系统确实做成了、做对了"。
4.1 结果总览
| 指标 | 数值 |
|---|---|
| 批量识别正确率(50 猫 + 50 狗) | 100% |
| 测试用例 PASS(TC-01~TC-24) | 24/24 |
| 测试用例 PASS(REQ-002 后 TC-01~TC-47) | 47/47 |
| 批量识别正确率(12 图 3 子 Agent) | 100% |
| 单张识别延迟 | ~2s |
| 验收标准(AC-1~AC-7) | 全部满足 |
| 验收标准(AC-8~AC-14) | 全部满足 |
4.2 验收标准(AC-1~AC-14)对照
| 编号 | 验收项 | 通过条件 | 结果 |
|---|---|---|---|
| AC-1 | 服务启动 | 执行启动命令后 dsh web 可用(http://127.0.0.1:3080) | ✅ 通过 |
| AC-2 | 插件加载 | 插件树中可见 cat-dog-classify-plugin | ✅ 通过 |
| AC-3 | 图片识别-猫 | 上传猫图输出"猫" | ✅ 通过 |
| AC-4 | 图片识别-狗 | 上传狗图输出"狗" | ✅ 通过 |
| AC-5 | Agent 工具调用 | Agent 可发现并调用"猫狗识别"工具 | ✅ 通过 |
| AC-6 | 服务关闭 | 可按技能流程干净关闭服务 | ✅ 通过 |
| AC-7 | 文档交付 | 需求规格文档交付完成 | ✅ 通过 |
| AC-8 | 无 token 拒绝 | HTTP/工具均可拒绝且不产生模型调用,返回 TOKEN_MISSING | ✅ 通过 |
| AC-9 | 无效 token 拒绝 | 错误 token 返回 TOKEN_INVALID,不产生模型调用 | ✅ 通过 |
| AC-10 | 有效 token 放行 | 正确 token 时行为与 REQ-001 完全一致 | ✅ 通过 |
| AC-11 | ctx.classifier 服务 | 消费方经 inject: ['classifier'] 获取;替换 Provider 无改动切换 | ✅ 通过 |
| AC-12 | zip 批量识别 | 报告 items 数量 = N、每张正确、summary 准确,成功率 ≥80%(实测 100%) | ✅ 通过 |
| AC-13 | 多 Agent 编排 | 会话日志可从子 Agent / fork 轨迹重建编排 | ✅ 通过 |
| AC-14 | 兼容回归 | REQ-001 的 24 条用例携带 token 后保持通过 | ✅ 通过 |
4.3 测试覆盖(TC-01~TC-47)
| 类别 | 用例 | 关键断言 |
|---|---|---|
| 服务类 | TC-01 / TC-02 / TC-13 / TC-14 | 启动就绪、插件树可见、干净关闭、重复启动防护 |
| API 类 | TC-03 ~ TC-09 | 猫/狗批量识别、非法格式 400、超限 413、缺字段 400、超时 504、密钥缺失 502 |
| 单元类 | TC-10 / TC-12 | parseResult 归一化与歧义不猜测(8 项样例) |
| UI 类 | TC-15 ~ TC-21 | 空态、预览、非法/超限拒绝、加载反馈、成功展示、服务不可达提示 |
| 静态检查 | TC-22 ~ TC-24 | 无 innerHTML、5 错误码齐全、接口路径正确 |
| Agent 类 | TC-11 | 会话中出现 classify_pet_image 调用且回答含结论 |
| 权限类 | TC-25 / TC-26 / TC-27 / TC-33 | 无/错 token 在 HTTP 与工具层均被拒(TOKEN_MISSING / TOKEN_INVALID),guard 拒绝工具,批量无 token 拒且无子会话 |
| 服务类 | TC-29 | service.ts 含 classifier + declare module,tool.ts 经 inject 获取 |
| 批量识别类 | TC-30 ~ TC-32 / TC-34 ~ TC-39 | 正常批量(12 图 8 猫 4 狗)、混合内容宽容、多 Agent 编排、非 zip / 空 zip、炸弹 413、报告结构、超预算 |
| 批量 UI 类 | TC-40 ~ TC-47 | 模式切换、token 空/错拦截、zip 校验、加载反馈、报告 / 部分失败 / 错误恢复 |
4.4 关键事实速查表
| 项 | 值 |
|---|---|
| 启动命令 | npx @deepseek-ai/dsh --profile web --patch dsh-patch.yml |
| Web 地址 | http://127.0.0.1:3080 |
| 插件名 | cat-dog-classify-plugin |
| 模型工具 | classify_pet_image(入参 {"image": string, "token": string})、classify_zip_images(入参 {"zip": string}) |
| HTTP 接口 | POST /api/cat-dog-classify(字段 image)、POST /api/cat-dog-classify-batch(字段 zip,批量) |
| token 环境变量 | CATDOG_AUTH_TOKEN(测试值 test-token-001,经环境变量注入) |
| 权限门 | ctx.tools.guard + tools/pre-execute(token 校验) |
| 自定义服务 | ctx.classifier(Service 子类 + declare module) |
| 多 Agent | ctx.subagents.start('fork'/'spawn') + ctx.agents.create() + capabilities.toolFilter |
| 模型标识 | deepseek-v4-flash-vision-exp(环境变量 DS_MODEL 可覆盖) |
| 密钥环境变量 | DS_API_KEY |
| 环境要求 | Node.js ^22.19.0 或 >=24.0.0 |
4.5 踩坑清单(完整记录)
这些坑是这趟旅程最宝贵的经验积累,每一个都有具体后果与解法:
| 坑 | 后果 | 解法 |
|---|---|---|
Node 24 type-stripping 不支持 TS 参数属性(constructor(public x)) | 运行时 SyntaxError | 构造函数内显式赋值 |
占位模型名 ds-v4-flash-version | API 400 invalid_request_error | GET /models 探测,改 deepseek-v4-flash-vision-exp |
推理模型 max_tokens=32 | 推理吃光预算,content 为空 | max_tokens=1024 |
| Windows 绝对路径装配 | ERR_UNSUPPORTED_ESM_URL_SCHEME | 用 file:///D:/... URL |
dsh web 子命令不接受父级 --patch | boot 报错 | 用 --profile web --patch ... 形式 |
| PowerShell 5.1 读 UTF-8 无 BOM 脚本 | 中文注释乱码/匹配失败 | 脚本存 BOM;响应断言用 UTF-8 hex 比对 |
| npm --no-save 单包安装 | 剪掉此前全部未记录包 | 一次安装全部所需包(含可选原生依赖) |
dsh Web UI 与业务页争抢 / | UI 不可达 | 按测试合同业务页占用 /;Agent 会话改用 headless 验证 |
访问 ctx.agents/ctx.subagents 未显式 inject | cannot get property without inject | inject = ['classifier','subagents','agents'] 显式声明 |
| 子 Agent 只继承全局工具层 | preset/会话级工具对子会话不可见 | 让 classify_pet_image 的 image 参数直接支持文件路径 |
| 子 Agent 回传基名 vs 父侧完整路径 | 匹配全部失败 | 统一按 basename 匹配 |
| 子 Agent 输出示例 JSON 干扰解析 | 抽取到错误片段 | 配平扫描 + 跳过字符串字面量 + 末块优先 |
父 Agent 缺 meta.cwd / agentOptions.model | {{cwd}}/{{model}} 提示词变量无值 | 创建父 Agent 时显式传入 |
| 150MB 炸弹夹具等于上限 | 不触发 413 | 夹具改 151MB,超上限才拒绝 |
5. 框架知识地图:概念全景
把工程动作翻译成框架概念,是这趟旅程真正的"学习成果"。
| 概念 | 一句话理解 | 本项目落点 |
|---|---|---|
| Plugin | 能力单元,用 apply(ctx) 描述贡献 | index.ts 四文件 |
| Context | 服务仓库,按 key 找服务而不 import 实现 | ctx.tools / ctx.webServer |
| Service | 具名能力,可被替换 | ToolRegistry、WebServer |
| Effect | 可逆注册,卸载自动回滚 | 工具/路由注册的 disposer |
| inject | 声明依赖,服务就绪才执行 | ['tools'] 必需、['webServer'] 按需 |
| Profile/Bundle/Patch | 组合层,后层覆盖前层 | dsh-patch.yml overlay |
| dump-config | 真实插件树的"照妖镜" | 装配验收 |
| tools.guard / pre-execute | 工具执行前的拦截管线(硬闸 / 瀑布事件) | FR-8 token 权限门 |
| Service 子类 + declare module | 把能力注册为具名服务,对外暴露 ctx.<key> | FR-9 ctx.classifier |
| Subagents | 派生子会话执行子任务(fork 继承 / spawn 全新) | FR-10 批量派发子 Agent |
| Agents + AgentHandle | 以编程方式创建/编排 Agent | FR-10 父 Agent 与 capabilities.toolFilter |
| CustomService / 能力缝 | Definition / Provider / Consumer 三角色 | FR-9 服务可替换 |
✅ 你现在能做什么了
写一个模型工具、写一个 HTTP 路由、把插件装配进 web profile、验证插件树、用 headless 会话驱动 Agent、按 47 条用例做全量回归。进阶后还能:用框架权限门拦工具、把能力升级为 ctx.classifier 服务供其他插件消费、用 subagents 编排批量多 Agent 任务。这套流程可以迁移到任何 dsh 插件开发任务上。
6. 进阶方向与学习闭环
进阶方向
- 事件钩子:
tools/pre-execute(权限门)、tools/post-execute(结果改写);→ 已在 REQ-002 落地(FR-8 权限门); - 自定义服务:
Service子类对外提供ctx.<key>;→ 已在 REQ-002 落地(FR-9 ctx.classifier); - 正式发布:把插件做成 npm 包 +
"dsh": {"bundle": {"patch": ...}},dsh plugin add安装; - MCP 接入、多 Agent(spawn / fork / workflow);→ 多 Agent 已在 REQ-002 落地(FR-10 批量识别),MCP 接入留作下一步。
🔁 学习闭环
读文档 → 写规格 → 写设计 → 写测试 → 写插件 → 装配验证 → 注入异常 → 全量回归。每一步都留下可检验的产物,这就是"从 0 构建一个系统来学习框架"的正确姿势。
附录:命令速查
# 启动(唯一指令源 command/start-web-command.md)
npx @deepseek-ai/dsh --profile web --patch dsh-patch.yml
# 验证插件树
npx @deepseek-ai/dsh --profile web --patch dsh-patch.yml --dump-config
# 停止(Windows:定位 PID → 终止 → 复查端口释放)
netstat -ano | findstr :3080
Stop-Process -Id <PID> -Force
# 设置 token 环境变量
$env:CATDOG_AUTH_TOKEN = "test-token-001"
# 单张识别(带 token 头)
curl.exe -s -H "X-Auth-Token: $env:CATDOG_AUTH_TOKEN" -F "image=@test\images\cat\cat_001.jpg" http://127.0.0.1:3080/api/cat-dog-classify
# 批量识别(zip 包,带 token 头)
curl.exe -s -H "X-Auth-Token: $env:CATDOG_AUTH_TOKEN" -F "zip=@test\data\zip\batch_valid.zip" http://127.0.0.1:3080/api/cat-dog-classify-batch
# headless 会话驱动 Agent
npx @deepseek-ai/dsh --profile headless --patch dsh-patch.yml "识别 test/images/cat/cat_001.jpg 是猫还是狗"
# 插件类型检查
npx tsc --noEmit -p plugins\cat-dog-classify-plugin\tsconfig.json
本文档基于 deepseek-harness 工程的真实交付物整理,供研究学习与实践复盘使用。
更多推荐



所有评论(0)