
开头写给技术人的判断DeepSeek Harness 不是拿来跑一次就结束的玩具它是一个可以承载自定义能力的“工具管线”。但很多人在使用它的过程中会卡在同一个地方内置命令不够用、知识文件需要手工去翻、想要接入团队内部的服务却不知道代码该放哪里。这时候真正需要解决的问题不是“再加一段提示词”而是“给 Harness 写一个正式插件”。本文的目标很明确从零写一个完整的 DeepSeek Harness 插件把代码整理成标准目录结构装进 Harness 能扫描到的插件目录然后作为开源项目发布到 GitHub。这里说的“正式”指的是代码结构规范、支持独立配置、能被打包安装、可以对外发布而不是在临时脚本里凑一个功能。读完这篇文章你能够独立完成插件的设计、编码、安装、验证和发布全流程。需要说明的是DeepSeek Harness 不同版本对插件机制的约定可能有差异本文示例采用 Python 插件系统里最通用的写法具体 API 名称请以项目当前官方文档为准。1. 为什么需要自己写一个 DeepSeek Harness 插件先弄清楚一个判断提示词和插件解决的是两种完全不同的问题。提示词只能改变模型“怎么回答”。你在 prompt 里写“请把结果输出为 JSON”模型会尽力照做但如果某个数据源不在它的上下文里它编出来的结果就是不存在的。插件则不一样它可以介入执行过程读文件、调服务、查数据库、把结果结构化之后塞给模型。也就是说提示词决定模型的表达插件决定模型的能力边界。实际开发中这几种需求都只有插件能解决希望 Harness 能检索本地的技能文档目录而不是每次手工把内容粘进对话。希望 Harness 能访问公司内部 API把某个工单状态查询变成一条命令。希望把固定业务流程封装好让团队其他人不用关心内部实现。希望 Harness 启动时自动加载某些上下文信息比如项目代号、联系人、环境地址。如果你只是调整模型参数、切换模型、改对话温度那么配置文件就够用不必写插件。但如果你要让 Harness 和外部系统产生真实交互插件几乎是绕不开的路径。最容易被忽略的一点是插件并不神秘。它本质上就是一段被 Harness 按约定加载的 Python 代码只是相比普通脚本多了一层“注册逻辑”。掌握了插件开发你也顺便理解了大多数 LLM 应用框架的扩展思路这个能力是通用的。2. 插件机制的核心概念与工作原理在动手写代码之前先理解 Harness 插件体系里的几个关键抽象。无论命名怎么变核心概念基本都是下面这几个。2.1 Harness 是什么“Harness”这个词在 AI 工程里通常指一层调度框架。它负责把模型、工具、上下文、配置组合到一起形成一条可以执行的管线。DeepSeek Harness 可以简单地理解为一个可以运行任务、管理上下文、调用工具的应用框架而插件就是插在框架里的能力模块。2.2 插件是什么插件不是一个独立运行的程序而是被 Harness 进程导入的 Python 模块。它遵循框架的约定暴露出特定入口让 Harness 在启动或运行时执行注册、命令挂载、生命周期回调等行为。一个插件通常包含以下几部分组成部分作用常见实现插件入口类对外提供加载入口Python 类注册方法把能力挂载到 Harness 上register() 方法配置项控制插件行为YAML 或 JSON 配置依赖声明声明第三方库pyproject.toml元信息插件名称、版本、描述类属性或元数据文件2.3 插件的生命周期多数 Python 插件框架会包含三个阶段初始化框架读取配置实例化插件对象。注册框架调用插件的 register 方法把命令、钩子或工具注册到运行环境中。执行用户在 Harness 会话中触发命令插件执行具体逻辑。如果涉及资源释放还会有清理阶段。插件代码要围绕这个生命周期去写而不是在类里随手放几个函数。2.4 常见误区插件不等于命令行脚本很多新手拿插件当脚本写在入口文件里放一个 main 函数以为 Harness 会像执行 bash 脚本一样执行它。这是错误的认知。Harness 不会执行你的脚本文件而是导入你的模块调用约定的方法。所以插件的代码必须面向“被调用”来组织类属性提供元信息方法提供行为。这也解释了为什么插件的目录结构、入口命名比业务逻辑本身更重要——写错了框架根本找不到你。3. 开发环境与前置准备建议环境如下版本不必刻意追求最新稳定即可Python 3.9 及以上版本pip 和 venv 模块Git 客户端GitHub 账号任意代码编辑器VS Code、PyCharm 均可在开始前先确认本机环境正常。python3 --version pip3 --version git --version建议创建一个虚拟环境保持插件依赖与系统环境隔离。mkdir dsh-plugin-workspace cd dsh-plugin-workspace python3 -m venv .venv source .venv/bin/activate注意这里的.venv是开发环境。真正安装到 Harness 时如果 Harness 使用独立虚拟环境就需要在 Harness 的环境中安装插件或者把插件目录放进 Harness 的扫描路径二选一不要混着来。4. 插件工程化目录结构与命名规范很多写插件失败的人不是代码逻辑出问题而是目录结构不符合约定导致 Harness 找不到插件类。所以先把结构搭对。本文以一个“技能检索插件”为例功能是让 Harness 会话中执行/skill 关键词命令检索本地 skills 目录下的技能模板文件。虽然这个功能不复杂但可以完整展示一个正式插件的全部要素。项目结构如下dsh-plugin-skill-search/ ├── pyproject.toml ├── README.md ├── LICENSE ├── dsh_plugin_skill_search/ │ ├── __init__.py │ ├── plugin.py │ └── config.py └── tests/ └── test_plugin.py4.1 目录命名规则包名dsh_plugin_skill_search遵循了 Python 包命名规范小写、下划线分隔。插件显示名称skill-search则适合作为命令前缀。类名DeepSeekHarnessPlugin清晰表达这个类的作用。正式插件建议在包名中带上dsh_plugin_前缀避免安装到环境中时与其他同名模块冲突。这也是一种命名约束团队协作时会省掉不少麻烦。4.2 各个文件的作用文件作用pyproject.toml声明包信息、依赖、插件入口点README.md使用说明和发布说明LICENSE开源许可证决定别人能否合法使用dsh_plugin_skill_search/init.py包标识文件dsh_plugin_skill_search/plugin.py插件入口类核心逻辑dsh_plugin_skill_search/config.py配置加载逻辑tests/test_plugin.py基础单元测试这些文件缺一不可。发布到 GitHub 的项目如果没有 LICENSE别人是不敢直接使用的这是一个新手最容易忽略的坑。5. 插件核心代码实现现在开始写代码。先写插件入口类plugin.py# 文件路径dsh_plugin_skill_search/plugin.py from pathlib import Path class DeepSeekHarnessPlugin: name skill-search version 1.0.0 description 在 DeepSeek Harness 会话中快速检索本地技能模板 def __init__(self, config: dict): self.config config skill_dir config.get(skill_dir, ./skills) self.skill_dir Path(skill_dir).resolve() def register(self, ctx): ctx.register_command(skill, self.run) def run(self, args): keyword str(args).strip() if not keyword: return 用法/skill 关键词例如 /skill knowledge if not self.skill_dir.exists(): return f技能目录不存在{self.skill_dir}请检查配置。 matches [p.name for p in self.skill_dir.glob(*.md) if keyword in p.name] if not matches: return 未找到匹配技能请更换关键词或检查 skills 目录。 result [f- {name} for name in matches[:10]] return 匹配技能\n \n.join(result)这段代码的关键点有三个name、version、description是插件元信息Harness 加载插件时会读取这些属性用于展示和日志。register方法向 Harness 上下文注册了skill命令命令入口指向run方法。run方法接收 Harness 传入的参数返回一个字符串作为执行结果。需要注意ctx对象的注册方式取决于 Harness 的插件 API。这里写的ctx.register_command(skill, self.run)是通用写法如果你的项目使用plugin.command装饰器或其他机制以官方文档为准。核心思想是“声明命令 挂载函数”。接下来是配置加载逻辑config.py# 文件路径dsh_plugin_skill_search/config.py import json from pathlib import Path def load_plugin_config(config_path: str) - dict: config_file Path(config_path) if not config_file.exists(): return {} with open(config_file, r, encodingutf-8) as f: data json.load(f) # 只返回该插件关心的配置段避免把无关配置塞进插件对象 return data.get(skill_search, {})配置加载逻辑并不复杂但它体现了一个规范插件不应该直接读取全量配置对象而是只读取自己命名空间下的字段。这样当配置文件越来越复杂时插件之间不会相互干扰。为了让插件可以被pip安装并作为入口点被 Harness 识别编写pyproject.toml# 文件路径pyproject.toml [build-system] requires [setuptools61.0] build-backend setuptools.build_meta [project] name dsh-plugin-skill-search version 1.0.0 description A skill search plugin for DeepSeek Harness requires-python 3.9 dependencies [] [project.entry-points.deepseek_harness.plugins] skill-search dsh_plugin_skill_search.plugin:DeepSeekHarnessPlugin [tool.setuptools.packages.find] include [dsh_plugin_skill_search*]这里的 entry-points 是 Python 生态中非常常见的插件注册方式。如果 Harness 支持通过 entry-points 扫描插件安装后就能自动被发现如果 Harness 通过目录扫描插件那么需要把插件装进它的扫描目录。文章后面会分别说明这两种情况。tests/test_plugin.py提供最小测试# 文件路径tests/test_plugin.py from dsh_plugin_skill_search.plugin import DeepSeekHarnessPlugin class FakeContext: def __init__(self): self.commands {} def register_command(self, cmd, handler): self.commands[cmd] handler def test_run_returns_usage_when_no_keyword(): plugin DeepSeekHarnessPlugin({skill_dir: ./skills}) assert plugin.run() 用法/skill 关键词例如 /skill knowledge def test_register_command(): ctx FakeContext() plugin DeepSeekHarnessPlugin({}) plugin.register(ctx) assert skill in ctx.commands代码写到这里插件的基本逻辑已经完整。但此时它只是“放在磁盘上的文件”还没有真正进入 DeepSeek Harness 的运行环境。下一节就解决安装问题。6. 本地安装与调试插件安装有两种典型方式直接放入 Harness 的插件目录或者通过 pip 以可编辑模式安装。6.1 方式一放入插件目录多数 Harness 框架会约定一个插件扫描目录例如plugins/、~/.config/deepseek-harness/plugins/等。以扫描目录为plugins/为例# 在 Harness 项目目录下创建插件目录 mkdir -p plugins # 将插件包复制到插件目录 cp -r dsh_plugin_skill_search plugins/ # 启动 Harness 验证插件是否被加载 dsh start启动后观察日志输出看到类似loaded plugin: skill-search (1.0.0)的日志就说明加载成功。如果没有加载优先检查以下两点目录层级是否正确Harness 是否扫描到了包含plugin.py的目录。插件类名是否与 Harness 约定的入口类名一致。6.2 方式二pip 可编辑安装如果要重复开发调试推荐用可编辑模式安装到当前虚拟环境。cd dsh-plugin-workspace pip install -e .安装后在 Python 环境里可以验证插件是否能被 importpython3 -c from dsh_plugin_skill_search.plugin import DeepSeekHarnessPlugin; print(DeepSeekHarnessPlugin.name)如果 Harness 支持 entry-points 插件发现机制安装后重启 Harness 就能加载到插件不需要复制文件。6.3 配置插件插件通常需要一份配置文件。假设 Harness 支持config.yamlplugins: enabled: - skill-search skill_search: skill_dir: ./skills配置的含义是启用skill-search插件并告诉插件技能文件放在./skills目录。配置文件路径以 Harness 实际约定为准。6.4 运行验证重启 Harness 后在会话中输入/skill knowledge预期输出类似匹配技能 - knowledge-engineering.md - knowledge-base-setup.md如果输出报错先看 Harness 日志再看插件目录路径是否正确。调试阶段建议在plugin.py中临时打印配置项print(skill_dir:, self.skill_dir)确认配置真正传了进来再继续排查业务逻辑。7. 发布到 GitHub从本地仓库到开源项目插件本地跑通只是第一步。真正让插件“正式”起来是把它发布到 GitHub让别人可以 clone、使用、提 issue。7.1 初始化仓库与提交代码cd dsh-plugin-skill-search git init git add . git commit -m feat: initial skill search plugin for DeepSeek Harness提交之前建议创建.gitignore忽略虚拟环境目录和缓存文件# 文件路径.gitignore .venv/ __pycache__/ *.pyc dist/ build/ *.egg-info/7.2 在 GitHub 创建远程仓库在 GitHub 网站上点击 New repository填写仓库名建议与插件包名一致例如dsh-plugin-skill-search。公开仓库或私有仓库都可以发布插件建议选择 Public。创建完成后在本地添加远程地址并推送git remote add origin gitgithub.com:yourname/dsh-plugin-skill-search.git git branch -M main git push -u origin main这里使用 SSH 协议推送比 HTTPS 更少遇到认证问题。如果本机还没配置 SSH key可以先运行ssh-keygen生成公钥然后添加到 GitHub 账号设置里。如果网络环境下直接访问 GitHub 不稳定推送 clone 时可以考虑使用gh repo create配合 GitHub CLI 创建仓库。clone 慢时尝试 SSH 协议而不是 HTTPS。下载 release 资产时可以使用国内常见的 GitHub 镜像站或文件代理服务以加速下载。需要提醒不要为加速 clone 去配置任何不安全的“一键脚本”该类工具很容易引入供应链风险。尽量使用官方 git 命令配合可靠的镜像服务下载 release 文件。7.3 补全 README 与 LICENSEREADME 至少要说明插件是做什么的。环境要求。安装方式。配置方式。使用示例。如何参与贡献。LICENSE 建议选择 MIT、Apache-2.0 这类宽松许可证。直接在代码仓库根目录添加 LICENSE 文件即可。没有许可证的公开仓库在法律上意味着“保留所有权利”别人不能合法使用这既不利于传播也会劝退潜在贡献者。7.4 打 tag 与创建 Release插件版本需要与pyproject.toml中的版本号保持一致。发布一个正式版本时在本地打 taggit tag v1.0.0 git push origin v1.0.0然后在 GitHub 仓库页面创建 Release选择 tagv1.0.0填写发布说明附上构建好的安装包。如果需要构建发布包可以安装build工具pip install build python3 -m build执行后会生成dist/目录里面包含.tar.gz源码包和.whl安装包。Release 页面可以把这两个文件作为附件上传方便用户直接下载安装。如果想上传到 PyPI 让用户通过 pip 安装需要单独配置 PyPI 的发布流程这一步不强制发布到 GitHub 已经满足“正式插件”的要求。8. 常见问题与排查思路下面这些问题是我在开发插件过程中见过的高频问题整理成表格方便定位。问题现象可能原因排查方式解决方案Harness 启动时没有加载插件插件目录不在扫描范围内查看 Harness 日志确认扫描路径把插件复制到约定的插件目录或通过 pip 安装报错ModuleNotFoundError依赖包未安装或包名冲突检查当前 Python 环境在 Harness 虚拟环境中安装依赖避免把包装到系统环境命令执行后没有任何响应命令未注册成功检查注册方法是否被调用确认 register 方法名与框架约定一致配置文件修改后不生效Harness 缓存配置重启 Harness重启并清理缓存目录插件代码修改后不生效使用普通 pip install 安装确认安装方式使用pip install -e .进行可编辑安装GitHub 推送失败认证失效或网络不稳定查看 git 输出信息使用 SSH 协议或重新认证 GitHub CLIRelease 下载很慢网络环境问题尝试不同网络或代理使用国内镜像站下载 release 资产排查时有一个重要原则先确认“框架有没有加载到你的插件”再确认“代码逻辑对不对”。很多人一开始就钻进业务逻辑里看半天实际问题是目录结构完全不符合约定框架压根没扫描到插件。9. 最佳实践与工程建议插件写多了之后你会意识到代码能不能跑只是底线真正拉开差距的是工程化水平。下面几条建议值得在项目里落地。9.1 插件 API 版本与 Harness 版本保持解耦Harness 主框架不断迭代插件 API 可能会变化。建议在 README 中明确声明插件支持的 Harness 版本范围例如deepseek-harness0.5,1.0。这样可以避免用户因为版本不匹配而遇到莫名其妙的错误。9.2 配置校验前置不要在run方法里才判断配置有没有问题。应该在__init__阶段就校验必备配置def __init__(self, config: dict): if skill_dir not in config: raise ValueError(skill_dir is required) self.skill_dir Path(config[skill_dir]).resolve()这样配置错误会在 Harness 启动时暴露而不是等到用户执行命令时才报错。9.3 合理使用日志插件中的业务日志要区分级别。命令被调用、参数错误、搜索无结果这些场景分别使用不同级别的日志。不要在run方法里 print正式插件应该通过框架提供的 logger 记录日志。9.4 错误处理要面向用户命令执行时的异常信息应该友好。不要直接抛出 Python traceback而是捕获异常并返回用户可以理解的中文提示同时把详细堆栈写入日志。9.5 安全性边界插件访问本地文件时要考虑路径穿越风险。配置中的目录应该限制在允许范围内避免用户传入../../etc这类路径。如果需要调用外部 API不要在配置中硬编码密钥建议通过环境变量或密钥管理服务注入。9.6 测试与 CI正式项目建议至少包含单元测试。更进一步可以在 GitHub 上配置 CI当代码推送时自动运行 pytest# 文件路径.github/workflows/test.yml name: test on: push: branches: [main] pull_request: jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - uses: actions/setup-pythonv5 with: python-version: 3.11 - run: pip install -e . - run: pytest有了 CI每次提交都能自动跑测试插件质量会稳定很多。9.7 发布前检查清单pyproject.toml版本号是否与 git tag 一致。README 是否包含安装、配置、使用说明。LICENSE 是否存在。.gitignore是否忽略掉敏感文件。是否在本地虚拟环境完整执行过一遍安装和验证流程。10. 总结与后续学习方向本文围绕一个具体的插件示例完整走通了 DeepSeek Harness 插件开发的五个关键环节理解插件机制、搭建目录结构、编写核心代码、本地安装调试、发布到 GitHub。过程中还补充了配置管理、错误排查、工程规范和开源发布注意事项。如果只看表面插件开发很容易被当成“框架相关的琐碎知识”但深入之后会发现它本质上是一套 Python 工程化的标准流程。入口类、配置加载、依赖声明、entry-points、git tag、release 发布这些技能在任何 Python 项目中都通用。下一步可以继续深入研究的方向有三个一是学习 Harness 更复杂的钩子机制比如事件监听、上下文注入、工具链编排二是给插件补充更完整的测试和 CI三是考虑把插件发布到 PyPI让用户通过pip install dsh-plugin-skill-search直接安装。对于想立刻上手的读者建议不要直接复制本文代码而是先创建一个最小插件改掉包名和命令名跑通安装流程再逐步加入自己的业务逻辑。插件开发最大的障碍通常不是代码而是环境没跑通。先把最小的链路走通后面就顺了。