欢迎光临
我们一直在努力

DeepSeek Harness · 猫狗识别框架研究学习与实践指南

DeepSeek Harness · 猫狗识别框架研究学习与实践指南

学习型项目 · 研究 · 实践

从一句话需求,到一套能跑、可验证、可复盘的 Cordis 插件系统 —— 用"搭建一个真实系统"的方式,彻底理解 dsh 框架「一切皆插件」的架构思想。

  • 交付物:web 系统 + dsh 插件 + ds-v4-flash API
  • 运行地址:http://127.0.0.1:3080
  • 插件:cat-dog-classify-plugin
  • 数据:50 猫图 + 50 狗图,批量识别 100% 正确,24 用例全过

目录

  • 项目定位:为什么要做这个系统
  • 制作过程:8 个阶段的完整旅程
  • 工程结构:目录、架构与分工
  • 项目构建结果:验收、测试与踩坑
  • 框架知识地图:概念全景
  • 进阶方向与学习闭环
  • 附录:命令速查

  • 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: catdogclassify
    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)。

    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
    │ ├── tech-design-spec.md # 技术详细设计 TECH-DESIGN-001
    │ ├── ue-design-spec.md # 用户体验设计 UE-DESIGN-001
    │ └── coach/ # 教练式指南
    │ ├── guide.md # 从 0 构建的学习指南(步骤式)
    │ └── ds-harness-framework-dogcatclassify-research-study-practice.md # 本文档
    ├── plugins/
    │ └── cat-dog-classify-plugin/ # 核心交付物:猫狗识别 dsh 插件
    │ ├── index.ts # 插件入口:apply(ctx) 注册服务
    │ ├── classifier.ts # ClassifierService 识别核心(零依赖)
    │ ├── tool.ts # classify_pet_image 模型工具定义
    │ ├── route.ts # /api/cat-dog-classify + 页面路由
    │ ├── cordis.patch.yml # 插件装配描述(bundle patch)
    │ ├── package.json # 包元信息(dsh.bundle 声明)
    │ └── tsconfig.json # TypeScript 配置
    ├── web/
    │ └── index.html # 前端单页(原生 HTML+JS,无构建链)
    ├── test/
    │ ├── test-cases.md # 测试用例集 TEST-001(LLM 可执行)
    │ └── images/{cat,dog}/ # 各 50 张测试图片
    ├── .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)

    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 工具(复用同一识别逻辑)

    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

    4. 项目构建结果:验收、测试与踩坑

    用可验证的数字与清单,说明"这套系统确实做成了、做对了"。

    4.1 结果总览

    指标数值
    批量识别正确率(50 猫 + 50 狗) 100%
    测试用例 PASS(TC-01~TC-24) 24/24
    单张识别延迟 ~2s
    验收标准(AC-1~AC-7) 全部满足

    4.2 验收标准(AC-1~AC-7)对照

    编号验收项通过条件结果
    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 文档交付 需求规格文档交付完成 ✅ 通过

    4.3 测试覆盖(TC-01~TC-24)

    类别用例关键断言
    服务类 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 调用且回答含结论

    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},出参 {"result": string})
    HTTP 接口 POST /api/cat-dog-classify(multipart/form-data,字段 image)
    模型标识 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 验证

    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 真实插件树的"照妖镜" 装配验收

    ✅ 你现在能做什么了

    写一个模型工具、写一个 HTTP 路由、把插件装配进 web profile、验证插件树、用 headless 会话驱动 Agent、按 24 条用例做全量回归。这套流程可以迁移到任何 dsh 插件开发任务上。


    6. 进阶方向与学习闭环

    进阶方向

    • 事件钩子:tools/pre-execute(权限门)、tools/post-execute(结果改写);
    • 自定义服务:Service 子类对外提供 ctx.<key>;
    • 正式发布:把插件做成 npm 包 + "dsh": {"bundle": {"patch": …}},dsh plugin add 安装;
    • MCP 接入、多 Agent(spawn / fork / workflow)。

    🔁 学习闭环

    读文档 → 写规格 → 写设计 → 写测试 → 写插件 → 装配验证 → 注入异常 → 全量回归。每一步都留下可检验的产物,这就是"从 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

    # 单张识别
    curl.exe s F "image=@test\\images\\cat\\cat_001.jpg" http://127.0.0.1:3080/api/catdog-classify

    # headless 会话驱动 Agent
    npx @deepseek-ai/dsh profile headless patch dsh-patch.yml "识别 test/images/cat/cat_001.jpg 是猫还是狗"

    # 插件类型检查
    npx tsc noEmit p plugins\\catdog-classify-plugin\\tsconfig.json


    本文档基于 deepseek-harness 工程的真实交付物整理,供研究学习与实践复盘使用。

    源码仓库:github.com/leo21cn/sharing-dsharness-dogcatclassify

    赞(0)
    未经允许不得转载:171主机测评 » DeepSeek Harness · 猫狗识别框架研究学习与实践指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址