恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

DeepSeek Harness:IDE插件双入口设计,固化LLM操作与Agent工具

  • 首页
  • 资讯中心
  • /
  • DeepSeek Harness:IDE插件双入口设计,固化LLM操作与Agent工具

相关资讯

JavaWeb在线订餐系统实战:从JSP+Servlet到MySQL全链路解析 2026/10/8 20:02:25
Windows Server SXS组件存储原理与安全清理指南 2026/10/8 20:02:25
反相器与缓冲器实战指南:从晶体管级到系统级的工程真相 2026/10/8 20:02:25

最新资讯

Octop开源AI工作台:本地部署多Agent协作与Skill扩展实战解析
WorkBuddy:基于MCP协议的可编程工作流中枢
鸿蒙Flutter+Rust桥接:FRB未初始化与Callback稳定实践
AI代理执行安全:沙箱隔离OpenClaw与DSH工具调用实战
边缘大语言模型分布式并行推理:从单卡到多机协同的落地实践
AI代码审查意见如何分级处理?从分类到落地的完整实践指南

今日推荐

context-mode实战指南:从全量塞入到结构化裁剪与检索增强
大模型对话上下文管理实战:三种模式与Token优化
抖音用户主页视频数据爬虫详解:点赞、收藏、分享字段抓取与 TaoToken 统一 Key 配置

本周热门

MR25H40CDF + PIC18F65K40:工业记录仪高可靠存储实战
基于STM32的数控恒压恒流电源设计:从硬件到PID调参全解析
LT9211 MIPI重定时器原理与双路扇出实战指南

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

DeepSeek Harness:IDE插件双入口设计,固化LLM操作与Agent工具

发布时间:2026/10/8 20:07:25
DeepSeek Harness:IDE插件双入口设计,固化LLM操作与Agent工具 这个项目不是灵光一闪它是被逼出来的。我们组用 DeepSeek 跑代码评审、文档结构化、批量标注日常脚本多到什么程度呢历史命令里同一条流程能查到 11 个不同版本参数从--model变成--model_name后来又加了--top_p输出格式从 CSV 改成 JSON最后又换回 Markdown。某天下午我把 300 条测试报告跑完发现--temperature写成了 0.8和上个月的结果对不上只能全部重跑。就是那天我决定写 DeepSeek Harness下面统一叫 DSH一个 IDEA 插件目标特别明确把项目里反复跑的操作固化成 IDE 侧边栏的面板入口同时把这套能力以 Agent 工具的形式暴露出去让外部调用方也能直接使用。如果你也在被频繁改脚本参数、批量调 DeepSeek折磨或者想给团队搭一套人可点、机器可调的 LLM 工程入口这篇文章应该对你有用。我不打算给你讲什么宏大的 Agent 架构只讲我这个插件怎么设计、怎么实现、踩了哪些坑以及为什么双入口设计值得做。1. 从复制脚本改参数到面板点一下三个月前的作业风暴1.1 一次典型的数据批量处理事故那天下午算法同事发来一个压缩包里面是 300 份测试报告需要我用 DeepSeek 批量做一轮质量评分最后输出成统一表格。听起来很简单对吧但实际操作是先翻终端历史找到上次用的脚本然后发现脚本被人改过参数从--model偷偷变成了--model_name还多了一个--system_prompt参数help 文档和实际行为对不上。我花了十分钟比对 git log 才知道谁改了什么。这还不算完。跑完一批之后我发现输出格式和评分标准跟项目约定的不一致——脚本里写死了一段 prompt但版本迭代中 prompt 被换了三次没有一次同步更新过。最后我只能重新组织数据、重跑、再人工核对一遍。整个过程耗了两个小时误差来源全是人的记忆。1.2 脚本方案藏着的三个拐点这类问题不是偶发的我总结下来有三个藏不住的点参数漂移同一个操作在历史命令里躺着十几个版本每次执行前都要花时间确认哪个参数是当前有效的结果不可追溯跑完的结果散落在个人目录没有统一的运行记录出了纠纷根本说不清当时用的什么 prompt、什么模型配置无法复用成能力组里自建的 agent 想用这套能力只能通过拼 shell 命令拼错一次就浪费一次调用额度而且没有任何校验。参数漂移和结果不可追溯是体验问题第三种才是真正的转折点。当团队开始上 agent 以后脚本这种形态很快就撑不住了。agent 需要的是可编程、可校验、可幂等调用的接口而你手里只有一堆.py和.sh。1.3 为什么最终选 IDE 插件而不是 CLI 或 Web 后台当时摆在我面前有三条路我列了一张简单的对比表。方案上下文感知上手成本结果可视化Agent 可编程调用CLI 脚本弱路径全靠传参中需要开终端差纯文本输出弱参数拼装易错IDE 插件强直接感知选中文件、项目结构低点按钮即可好面板内直接看结果与历史强可在插件内起本地服务Web 后台弱需要主动上传/配置高要部署要鉴权好浏览器页面强但要维护一套服务CLI 适合自己用但组里做数据标注的同学不是每个人都习惯开终端Web 后台要部署、要鉴权、要维护数据库为一个重复跑操作的工具付出这个成本不划算。IDE 插件正好落在中间我们团队大部分人一天八小时都在 IDEA 里插件可以感知当前选中的文件、读取项目路径、把结果归档在本地而且 IDEA 本身就是一个常驻进程我可以在里面直接起一个本地 HTTP 服务供 agent 调用。2. Harness 与 Agent 的边界我为什么坚持双入口设计2.1 先把这个被聊烂的词说清楚Harness 到底是什么在 AI 工程圈子里Harness 这个词经常和 Agent 混在一起但两者根本不是一回事。Harness 更接近运行骨架或试验台它负责输入组装、模型调用、输出校验、重试策略、全程记录这些事情。Agent 是决策者它思考该调用哪个工具、怎么组合结果Harness 是执行者它保证每一次调用都按同样的骨架稳定跑完。我用一个类比Agent 是赛车手Harness 是赛道和护栏。赛车手可以决定超车时机但如果没有护栏每一次失误都是灾难。放在 LLM 场景里Harness 的价值不是让你更有创造力而是让跑模型这件事变得可重复、可观测、可兜底。2.2 人和机器的交互方式完全不同所以需要双入口做这个插件之前我研究过怎么把能力暴露出去这个问题。结论是人的入口和机器的入口必须分开设计。人需要面板可视化、可点击、可看运行历史、可对照上次结果机器需要工具函数描述、参数 Schema、稳定的返回值、幂等语义。DSH 的做法是底层共用一套叫 JobSpec 的作业定义上面套两个壳面板负责展示和交互Agent 工具负责暴露 API。同一个操作你在面板里点一下和 agent 调用一次走的完全是同一套代码所以结果一定一致。这点在实际排障时太重要了——如果人跑的和 agent 跑的不一样你根本查不清楚是 prompt 的问题还是调用方式的问题。2.3 双入口设计的直接收益上线一个月后我观察到几个很具体的好处。首先是配置一次到处运行一个新的批量操作进入面板以后组员不用再问我这个参数怎么传其次是人机结果一致评审报告不会再出现人跑版和 agent 跑版互相打架的情况第三是权限能统一管理文件访问白名单、模型配额这些策略只需要在插件里写一遍面板和工具都走同一套拦截。开发量看起来是双份实际维护成本反而更低了。3. 插件核心面板入口层是怎么把操作固化成可复用资产的3.1 我把所有重复操作都抽象成了 JobDSH 里没有脚本这个概念只有 Job。一个 Job 代表一个可重复执行的操作它把参数、prompt、模型配置、输出校验全部固化成一份结构化定义。下面是一个简化版的 JobSpec JSON{ jobId: review_report, name: 代码评审报告, description: 对指定源码文件生成 DeepSeek 评审意见输出 Markdown 报告, inputs: [ { name: files, type: fileList, required: true, description: 相对项目根目录的源码文件路径 }, { name: strictness, type: enum, options: [standard, strict], default: standard } ], prompt: skills/review_report/prompt.md, model: { provider: deepseek, model: deepseek-chat, temperature: 0.3 }, output: { type: markdown } }为什么要这么做因为只有把输入、模板、模型、输出拆开操作才真正可复用。文件的路径是变量模型参数是配置prompt 是资产输出格式是契约。一个 Job 就是一个可裁剪的资产包之后不管是面板还是 agent都只是对这个资产包的调用方。3.2 Tool Window插件面板是怎么搭起来的IDEA 插件的面板本质是一个 Tool Window。我用的开发语言是 Kotlin工程结构里最核心的部分就是注册 Tool Window 和初始化面板。plugin.xml 里需要这么一段extension pointcom.intellij.toolWindow toolWindow idDeepSeek Harness anchorright factoryClasscom.dsh.plugin.DshToolWindowFactory secondarytrue/ /extension面板工厂类的骨架长这样class DshToolWindowFactory : ToolWindowFactory { override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { val panel JobListPanel(project) val contentFactory ContentFactory.getInstance() toolWindow.contentManager.addContent( contentFactory.createContent(panel, Jobs, false) ) } }面板布局分三块左侧是 Job 列表中间是参数表单下方是运行日志和归档记录。点一个 Job右侧就渲染出它定义的 inputs填完参数点运行插件会生成一条运行记录并写入~/.dsh/runs/{jobId}/{timestamp}/目录里面包含请求参数、原始响应、解析后的结果和耗时。所有这些操作都会进入归档这也是我定 DSH 插件时坚持的一个原则——没有记录的执行等于没执行。3.3 Prompt 模板渲染里的坑别用字符串替换第一次做 Job 执行器时图省事直接用了String.replace({{files}}, files.joinToString())结果很快出问题当文件路径里包含{{这种特殊字符或者参数值本身带模板语法时渲染结果会二次展开prompt 直接错乱。后来我把所有参数先序列化成一个 Map再交给模板引擎渲染彻底解决。更值得注意的一点是deepseek 模型对 markdown 的换行和缩进很敏感尤其是 prompt 里如果夹着 JSON 样例字符串替换会破坏格式。我的做法是把参数统一转成 JSON 上下文模板里用点号访问让模型严格按照输出契约返回。比如 prompt 默认会追加一句请严格输出 JSON 对象不要包含任何额外解释。这种约定让后面的结果解析省了很多事。4. Agent 工具注册让外部 Agent 能调用内部能力的实现细节4.1 暴露工具的三种方式我为什么选了本地 HTTP想让外部 agent发现插件里的能力有三种常见做法各家工程社区都很流行本地回环 HTTP 服务插件内起一个localhostHTTP server提供/tools列表和/tools/{name}/call调用端点MCP 这类标准化协议功能更强但当时团队没有标准化诉求技术栈还需要一个 MCP client导出 JSON Schema 文件静态工具清单适合文档协作但不适合动态参数校验和任务状态跟踪。我选了第一种。原因很直接IDEA 插件本身是一个常驻进程我完全可以在插件启动时创建 HTTP serveragent 跑在同一台机器上时天然可以访问而且我可以随时拿到任务执行状态返回task_id给 agent 轮询。MCP 很好但对于当时的团队体量为了暴露三个工具额外引入一套协议收益不划算。4.2 工具调用的完整链路DSH 暴露的 agent 工具描述是标准的 function calling 格式。以代码评审报告这个 Job 为例agent 拿到的工具 Schema 长这样{ type: function, function: { name: ds_review_report, description: 对指定源码文件生成代码评审报告返回 Markdown。, parameters: { type: object, properties: { files: { type: array, items: {type: string}, description: 相对项目根目录的源码文件路径 }, strictness: { type: string, enum: [standard, strict], default: standard } }, required: [files] } } }调用链路是这样的Agent 请求GET /dsh/tools拿到全部工具 SchemaAgent 决策后发起POST /dsh/tools/ds_review_report/call请求体里带request_id和arguments插件校验参数的 JSON Schema校验失败直接返回 400 和错误明细校验通过后任务进入执行队列接口立即返回task_id对应状态是acceptedAgent 通过GET /dsh/tasks/{task_id}轮询拿到completed或failed状态和结果。这一步立即返回 task_id是我特意设计的。DeepSeek 的模型调用耗时通常在十几秒到几十秒如果 HTTP 接口同步等待agent 那边会频繁超时。改成异步任务模式后agent 只需轮询两次就能拿到结果稳定很多。4.3 Agent 安全边界工具白名单与本地文件访问控制让 agent 能调用工具最危险的就是路径穿越。外部 agent 发送的参数如果不受控制理论上可以让你插件读取任意文件。DSH 里有一段路径校验逻辑核心思路是所有相对路径必须 resolve 到项目根目录内否则直接拒绝。def safe_resolve(root: Path, relative: str) - Path: candidate (root / relative).resolve() root_resolved root.resolve() if not str(candidate).startswith(str(root_resolved)): raise PermissionError(path escapes project root) return candidate除了路径校验我还加了一层文件类型白名单。默认只允许读取.java、.py、.kt、.md、.json、.txt这类常规源码和文档文件防止 agent 通过工具去读插件配置或者用户目录下的其他文件。这一步看起来多虑但在agent 可以被外部因素诱导调用工具的场景下属于必须做的防御。5. 并发与稳定性多 Agent 同时调用时我踩过的坑5.1 第一版全局线程池把 IDEA 卡死了第一版 DSH 实现得很天真所有 Job 共用一个全局线程池默认 8 个线程。我忘了考虑一件事——外部 agent 是持续并发调用工具的它不是人不会乖乖等上一个跑完。两个 agent 同时各起一个循环瞬间就把 8 个线程全部占满IDE 的菜单反应都开始变慢最后整个窗口卡死到只能强制退出。那次事故之后我才认真琢磨AI agent 怎么扛并发这个问题。结论是不能无脑放大线程池。DeepSeek API 的调用是 IO 密集型的线程池太大只会让请求更容易被对方限流线程池太小又会让面板前的人等太久。需要一个真正会控制的调度器。5.2 令牌桶加优先级队列才是可控并发我在 DSH 里做了一个简单的调度器令牌桶限速控制每秒能发起的模型调用次数队列有上限超过 200 个任务直接拒绝而不是无限堆积同时区分了两种优先级面板里人的手动操作走高优先级队列agent 的大批量调用走低优先级队列。调度器的核心伪代码大概是这样的class JobScheduler: def __init__(self, quota_per_minute, max_queue200): self.rate quota_per_minute / 60.0 self.capacity quota_per_minute self.tokens self.capacity self.high_queue deque() self.low_queue deque() async def submit(self, job, priority, request_id): if self.queue_size() self.max_queue: raise QueueFull(queue is full, retry later) if request_id in self.seen: return self.seen[request_id] # 幂等返回已有任务 ... if priority high: self.high_queue.append(task) else: self.low_queue.append(task)令牌桶的容量和补发速率要按实际的 API 配额来设置。比如我们的账号每分钟能接受 60 个请求我就把容量设为 60速率设为 1 个/秒。这样即使 agent 发疯一样循环调用整体请求速率也被钉死在配额以内。人手动点的时候几乎感受不到排队因为高优先级队列基本是空的。5.3 超时、熔断和幂等是三个完全不同的策略并发问题解决之后又陆续补了三块稳定性能力。先说超时模型接口超过 60 秒没有响应就标记失败同时把调用时间从 30 秒上调到 60 秒因为 DeepSeek 在长上下文请求时确实会比较慢。再说熔断连续 5 次请求超时或错误率超过 30%调度器会自动进入冷却状态暂停新请求 10 秒10 秒后放一个探针请求成功就恢复失败就继续冷却。最后是幂等外部 agent 经常因网络问题重试同一个请求DSH 要求调用方必须带request_id调度器通过request_id去重同一个任务只会真正执行一次重复请求直接返回第一次的结果或状态。我把这三者的关系整理成了下面这张表方便你对照。策略触发条件行为目的超时单次模型调用超过 60s标记失败并返回错误避免任务无限挂起熔断连续 5 次超时或错误率 30%暂停新请求 10s探针恢复保护 API 额度与插件稳定性幂等相同 request_id 重复提交返回已有任务状态杜绝重复执行与重复扣费这三块缺一不可。没有超时一个卡住的请求会占着队列位置没有熔断限流之后你会连环失败没有幂等agent 每次重试都会让你多花一份额度。对真正跑生产任务的工具来说稳定性比功能更值钱。6. Skill 包内网化把常用能力变成可分发资产6.1 为什么 prompt 不能散落在代码里Job 数量多起来以后一个新的需求出现了prompt 模板不是只有我一个人要改数据分析的同事也想调整评分标准测试组的人想改输出格式。prompt 一旦写在 Kotlin 源码里改一次就要重编插件团队根本没法协作。我把与某个 Job 相关的 prompt、参数定义、样例输出打成一个包起名为 Skill 包它本质上是一组可独立分发、可版本化的资源文件。6.2 Skill 包的目录结构和版本管理DSH 的 Skill 包长这样skills/ review_report/ skill.json prompt.md parameters.schema.json examples/ sample_output.md doc_struct/ skill.json prompt.md parameters.schema.json examples/skill.json里记录了入口模板、模型参数和输入定义{ name: review_report, version: 1.3.0, entry: prompt.md, model: { model: deepseek-chat, temperature: 0.3 }, inputs: [ { name: files, type: fileList } ] }版本号我会直接写进目录名比如review_report-1.3.0而不是只靠 skill.json 里的字段。原因很简单目录名是文件系统层面的标识插件在启动阶段扫描目录做版本判断时不需要打开每个 JSON 再去比较版本直接看目录名就够了快很多也不容易出错。6.3 内网部署的实操步骤和回退策略如果你们公司是纯内网环境插件没法连外网下载 Skill 包解决思路是把 Skill 包做成 zip 放在内网静态服务器上插件启动时拉取。步骤可以这样落把skills/下要分发的目录打成 zip文件名带版本号例如review_report-1.3.0.zip上传到内网静态服务的一个固定路径比如http://internal.harness.local/skills/插件启动时读取本地~/.dsh/skills/目录检查已有 Skill 版本如果服务器上版本号更新则下载 zip 并校验 checksum再解压到新的版本目录解压完成后更新本地软链指向新版本。用命令表达这一段过程就是curl -s http://internal.harness.local/skills/review_report-1.3.0.zip -o /tmp/review_report.zip unzip -q /tmp/review_report.zip -d ~/.dsh/skills/review_report-1.3.0这个流程里最容易被忽略的是回退策略。我一开始图省事更新时直接删掉旧版本目录结果有一次内网服务器传输中断把包解压到一半所有人都没法跑了。后来改成先下载、再校验、最后切换旧版本目录至少保留一个。插件启动时如果发现当前版本校验失败自动回退到上一个完整版本。对于内网团队来说可用性比版本新更重要。我在实际使用中最明显的感觉是插件上线以后我们群里的谁能帮我跑一下 XXX从每天四五个变成零。大家自己打开面板点一下就行那边服务器上的 agent 也能自动调用工具不用再来问参数。如果你也在被反复跑操作折磨不用一开始就搞重框架先把你手里最常跑的三条命令固化成 Job跑通一次再谈扩展。工具本身不大但收益是立刻能感受到的。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号