ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

DeepSeek Harness 实战:Tools、MCP、Skill 三件套让 Agent 真正干活

DeepSeek Harness 实战:Tools、MCP、Skill 三件套让 Agent 真正干活 前两篇把 DeepSeek Harness 搭起来、把基本流程跑通之后很多朋友会卡在一个地方Agent 确实能聊了但干不了实事。你要它查个数据库它只会给你编一段 SQL要它看个设计稿它只能说“我理解你的设计”要它按你团队的规范走一遍发布流程它直接自由发挥。问题出在哪缺了手脚也缺了职业手册。这篇是系列第三篇重点解决“接入”这件事。我理解里的 DeepSeek Harness核心价值不是给你一个聊天框而是给你一个 Agent 运行时底座。真正让它从玩具变成生产力工具的是把外部工具接进来、把 MCP 生态接进来、把可复用的 Skill 沉淀下来。这篇我会把 Tools、MCP、Skill 三件事从头到尾拆一遍包括配置怎么写、坑在哪儿、以及我实际用下来的取舍。1. 先理清楚Tools、MCP、Skill 到底分别解决什么问题1.1 DeepSeek Harness 的整体工作方式是怎样的简单说DeepSeek Harness 是一个围绕大模型打造的 Agent 执行框架。它不像 LangChain 那样给你一堆抽象链也不像普通 API 调用那样一问一答。它的核心思路是你给 Harness 一个目标它会自己去拆解任务、决定调用哪些工具、按什么顺序执行最后把结果组装成你需要的输出。这里面的关键点在于“工具”不是一个可选功能而是 Agent 能力的一半。没有工具的 Agent本质上是记忆加语言模型它能做的只是文本生成一旦接上工具它才拥有读写文件、查询接口、操作浏览器、执行命令这些真实世界操作能力。DeepSeek Harness 的设计里工具调用信号由模型自主产生Harness 只负责调度和执行这种设计让它在复杂任务里表现非常灵活。实操时你会发现Harness 的工作方式可以拆成三层对话层负责理解用户意图调度层负责决定下一步动作执行层负责真正调用外部能力。而 MCP 和 Skill 恰好分别作用于执行层和调度层。理解这个分层之后你才知道该把配置写在哪儿、排查问题时该看哪层日志。1.2 三者不是并列关系而是三层协作关系很多人刚接触时会把 Tools、MCP、Skill 当成三个并列概念实际上它们的定位完全不同**Tools工具**是最底层的能力单元一个 Tool 就是一个可被模型调用的函数比如“查询天气”“读取文件”“执行命令”。**MCP模型上下文协议**是工具的供给协议它解决的问题是“工具从哪里来”通过 MCP Server 可以一次性接入一整套外部系统能力比如蓝湖的设计稿、数据库的元数据、Figma 的文件资源。**Skill技能**是任务层面的编排模板它决定“模型拿到目标后按什么套路干活”包括系统提示、工具偏好、步骤约束、输出格式约定等。我打一个比方Tool 是工具箱里的一把把螺丝刀MCP 是给你提供整套工具的供应商Skill 则是老师傅脑子里那套“换空调滤芯”的操作流程。老师傅也要用螺丝刀他拧哪颗螺丝都有自己的顺序——这就像 Agent 在执行 Skill 时会去调用 Tool而 Tool 又可能来自某个 MCP Server。三者的关系我整理成一张表方便快速对照维度ToolsMCPSkill本质可执行函数协议与服务器提示词流程模板解决的问题模型怎么操作世界工具怎么批量供给任务怎么按套路执行作用层级执行层供给层调度层典型载体Python 函数/REST APIMCP Server 配置YAML/Markdown 文件依赖关系Skill 和 Agent 都会调用为 Agent 提供环境内部可以引用多个 Tool在实际使用 DeepSeek Harness 时我建议你脑子里始终挂着这张表。出了问题先定位是工具本身没执行成功还是工具根本没被供给进来还是 Agent 没有按 Skill 的流程走。分层定位能省下大量排查时间。2. 接入工具Tools最原始的“给 Agent 装手脚”方式2.1 工具接入的本质用 JSON Schema 描述函数在 MCP 出现之前给 Agent 接工具是一件“手工作坊”式的事。DeepSeek Harness 的早期版本和很多 Agent 框架一样要求你把自己写的函数包装成 JSON Schema 格式注册给模型让模型在对话过程中决定是否调用。这个过程说白了就是三步写一个函数、用 Schema 描述它、注册到 Harness。模型看到你的描述后如果觉得某个任务需要这个函数就会生成一个带参数的调用指令Harness 执行后再把结果返回给模型。为什么需要用 JSON Schema因为大模型本质上是文本输入输出它不理解 Python 对象也不理解内存地址。你只有把函数的名称、参数类型、返回值语义用纯文本告诉它它才知道“这时候可以调用 get_weather(city上海) 来获取天气”。Schema 写得好不好直接决定了模型能不能正确调用这比代码逻辑本身更重要。2.2 最简实战注册一个自定义工具这里给一个最小可用的示例场景是给 Harness 增加一个“查询服务器负载”的工具。假设你已经装好了 DeepSeek Harness并且有一个 Python 扩展目录# tools/system_health.py import psutil from deepseek_harness.tool import tool tool( nameget_server_load, description获取当前服务器的 CPU、内存和磁盘使用率返回百分比数值, parameters{ type: object, properties: {}, required: [] } ) def get_server_load(): cpu psutil.cpu_percent(interval1) mem psutil.virtual_memory().percent disk psutil.disk_usage(/).percent return {cpu: cpu, memory: mem, disk: disk}然后在 Harness 的配置文件里注册这个工具# harness_config.yaml tools: - name: get_server_load module: tools.system_health enabled: true这样配置好之后你启动 Harness 时问一句“现在服务器负载高吗”模型就会自动调用这个函数拿到真实数据再组织语言回答。这一步对新手来说最大的意义是让你直观理解“工具调用”到底是怎么发生的——不是写死在流程里而是模型自己判断要不要用。2.3 工具接入踩过的几个坑工具接入看似简单实际操作里坑不少。我这段时间试下来最典型的几个问题第一Description 写得不清楚模型会乱用工具。比如你只写“获取服务器信息”模型可能在任何场景都调用它甚至在不需要系统信息时也调用。正确做法是把“什么情况下用”“返回什么”写明白比如“当用户询问 CPU、内存、磁盘使用率时使用返回值为百分比”。第二参数校验要放宽不要在函数入口做太严格的类型判断。模型生成参数时偶尔会多传字符串、少传必填字段你要做的是在函数内部做容错而不是让 Harness 直接报错。否则一次参数异常可能导致整个任务中断。第三工具返回结果要尽量短。模型上下文窗口有限如果工具返回一长串 JSON不仅浪费 token还会干扰模型对后续步骤的判断。我在实际项目中会做一个统一的后处理把工具返回结果截断到关键字段比如只有“负载高/低”加上几个数字。3. MCP一次接入全局复用3.1 MCP 到底帮你省掉了什么MCPModel Context Protocol这半年来讨论度非常高本质原因是它解决了 Agent 工具接入的碎片化问题。以前每接一个系统你都要单独写适配代码接数据库写一套、接设计稿写一套、接监控平台再写一套。每个系统一个 SDK、一种认证方式、一套错误处理工作量翻倍还不好维护。MCP 的思路是统一标准MCP Server 把自己的工具以标准接口暴露出来MCP Host比如 DeepSeek Harness通过一套协议去发现和调用。对 Agent 框架来说只需要做好一个 MCP 客户端就能接入成百上千个不同的 MCP Server。对 DeepSeek Harness 来说接入 MCP 之后最大的改变是“工具供给从手写变成了配置”。之前每加一个工具你得写函数、写 Schema、写注册配置有了 MCP你只需要启动一个 MCP Server再告诉 Harness 去连接它工具列表会自动同步过来。这也是官方现在主推的接入方式。3.2 DeepSeek Harness 接入 MCP Server 的完整配置拿一个最常用的场景举例接入文件系统 MCP让 Agent 获得读写本地文件的能力。第一步你需要先装好 MCP Server 端程序这里用官方维护的 filesystem 服务示例npm install -g modelcontextprotocol/server-filesystem然后在 DeepSeek Harness 的配置里声明这个 MCP Server# harness_config.yaml mcp_servers: fs_local: transport: stdio command: npx args: - modelcontextprotocol/server-filesystem - /Users/me/workspace env: # 如果需要认证类环境变量统一写在这里 MCP_FS_TOKEN: ${FS_TOKEN}注意这里的 transport 有两个选项stdio 和 streamable http。本机工具用 stdio 最方便不需要额外开端口远程服务则用 streamable http 指定 URL。配置好之后重启 Harness 或者执行热加载命令Harness 会自动和 MCP Server 握手服务器上暴露的工具列表会被拉取到本地。连接成功后你可以直接问 Harness“帮我看看 workspace 目录下有哪些 Python 文件并统计每个文件的行数。”它会通过 filesystem MCP 的工具列表来完成这个操作而你不需要写一行文件遍历代码。这个体验上的差距是很多人在接入 MCP 之后再也不愿意回去手写工具的直接原因。3.3 什么场景值得接 MCP什么场景不必MCP 很好但也不是所有场景都需要上。以我的实际经验来分个类值得接的场景有三类。一类是通用能力比如文件系统、数据库、HTTP 请求这些工具几乎每个 Agent 都需要接一次全局受益。第二类是专业领域能力比如设计稿标注领域蓝湖有自己的 MCP ServerAgent 接上去之后可以直接读取设计稿中的标注信息、切图资源这在设计协作流程里非常实用。第三类是内部系统比如公司的监控平台、发布平台、知识库通过 MCP 封装后能让 Agent 直接操作省去在 Harness 里逐个注册工具的繁琐过程。不必接的场景也有三类。一是临时用过一次就丢的小功能直接手写工具更轻量二是对性能和延迟要求极高的调用因为 MCP 多了一层协议解析会比本地函数调用慢几毫秒到几十毫秒三是工具本身需要极强安全性控制的场景MCP 的权限粒度不一定能满足你的要求不如在工具函数里做精细化鉴权。3.4 两个典型 MCP Server 接入示例我实测过两个比较有代表性的 MCP Server对理解 MCP 的价值很有帮助。一个是蓝湖 MCP。做前端开发的人都知道以前要让 AI 理解设计稿你得人肉描述样式、间距、配色费时费力。接入蓝湖 MCP 之后Agent 可以直接读取蓝湖项目里的设计稿数据拿到的已经是结构化的颜色、字体、尺寸信息前端可以直接照着还原。这个 Server 的接入方式和 filesystem 类似但需要额外获取一个访问令牌在蓝湖账号中心的“个人设置”里生成然后配置到 env 里面。另一个是 Figma MCP。Figma 的 MCP Server 可以读取 Figma 文件中的页面结构、节点属性、导出资源对设计稿转代码这条链路帮助很大。这里经常有人问 Figma MCP Token 在哪获取简单说就是 Figma 个人设置里的 Access Token勾选 file content 读取权限即可。获取后配置到环境变量 FIGMA_ACCESS_TOKEN连接时 Harness 会自动读取。从我自己的经历看接完这几个 MCP 之后我对 Agent 的可用性判断标准彻底变了。以前写一个“读取设计稿并生成样式代码”的流程可能要半天现在配置好 MCP模型天然会用这些工具你只需要把流程目标说清楚。4. Skill把“经验”变成可复用的“给养”4.1 Skill 和 Agent 的区别不是技能点是作战手册Skill 是我认为 DeepSeek Harness 里最被低估的一个概念。很多人把它理解成“给 Agent 多加一个技能”比如代码审查技能、SQL 生成技能。这么理解不能说错但没有抓到重点。更准确的说法是Skill 是任务的“作战手册”。它不只是告诉 Agent “你有这个能力”而是规定了“接到这类任务时你按什么步骤来、优先用哪些工具、输出格式是什么、遇到边界情况怎么处理”。它比普通的系统提示词更结构化也更工程化。Agent 本身是一个通用执行器Skill 则是绑定在特定任务类型上的专业知识包。同一个 Agent 加载不同的 Skill面对同一句话会产生完全不同的行为路径。比如同样是“帮我看一下数据库”没有 Skill 的 Agent 可能直接去查数据而加载了“SQL 安全评审 Skill”的 Agent 会先检查当前环境、再检查是否有 where 条件、再决定是否给出执行建议。DeepSeek Harness 对 Skill 的支持有几个核心文件Skill 目录、Skill 配置、Skill 内容文件。内容文件里用自然语言写清楚任务执行的规则和流程Harness 会在任务匹配时把它注入到上下文里。4.2 编写一个 Skill 的完整流程我拿一个实际用过的“数据库 SQL 生成与审查” Skill 做例子展示完整结构。首先是目录结构skills/ sql_review/ SKILL.md rules/ query.sql.example write.sql.example references/ schema_guide.mdSKILL.md 是这个技能的主文件DeepSeek Harness 会优先读取它--- name: sql_review description: 根据数据库表结构生成 SQL并在执行前检查安全性。在用户提出数据库查询、导出、修改数据等需求时使用。 tools: - query_database - get_table_schema - execute_sql --- # SQL 生成与审查 ## 适用场景 - 用户需要查询数据 - 用户需要生成报表 - 用户需要更新或删除数据 ## 执行步骤 1. 先获取数据库 schema 列表定位相关表。 2. 根据用户描述的目标字段生成 SQL。 3. 安全检查SELECT 语句必须带有明确的 WHERE 条件UPDATE/DELETE 必须带有主键或唯一索引条件。 4. 将最终 SQL 展示给用户确认明确告知影响行数。 5. 只有用户确认后才执行 execute_sql。 ## 输出格式 - 生成的 SQL 放在代码块中 - 附带一张结果说明表表名、字段、条件、影响行数 - 如果存在安全风险先输出风险提示再输出 SQL ## 边界情况 - 如果表结构信息不足调用 get_table_schema 多次获取 - 如果用户需求模糊先澄清再生成不要猜测这样写的好处是规则非常明确Agent 在加载这个 Skill 后面对数据库类需求时会自动按这些规则行动。即使底层模型是重量级还是轻量级行为都会稳定在“先看结构、再生成、再确认、后执行”这条路径上。4.3 Skill 如何被触发和调度Skill 的触发机制有两种理解这个很关键。第一种是关键字匹配。Harness 会读取用户输入和每个 Skill 的 description 做匹配。比如用户说“帮我导出昨天的订单明细”Harness 检索到 desc 里有“导出”“报表”就会把 sql_review 这个 Skill 注入到上下文中。这个机制要求 description 写得很准确最好覆盖用户可能使用的各种说法。第二种是显式指定。在 DeepSeek Harness 的配置或对话指令里直接写“使用 sql_review 技能”发布命令Agent 就会强制加载指定 Skill。这种方式适合自动化流程中已经知道任务类型的情况避免模型选错 Skill。实际使用中我发现一个很重要的技巧Skill 的 description 不要只写一句话要把触发场景、包含的关键词、不适用的场景都写出来。比如 sql_review 的 description 可以扩展为“当用户需要查询数据库、生成报表、导出数据、修改或删除记录时使用不适用于一般性的文件操作”。4.4 Skill 调试与迭代把规则写细Skill 不是写一遍就完事的东西。我实际用下来每个 Skill 都要根据 Agent 的表现持续迭代。我自己的做法是建立一个“失败案例库”每当我发现 Agent 在某个任务上没有按预期执行就把这个案例记录到 Skill 的 SKILL.md 里补充一条规则。比如一开始我的 SQL Skill 没有要求展示影响行数结果 Agent 经常在执行 DELETE 之前不提示风险。后来我在规则里加了一句“UPDATE/DELETE 必须输出影响行数预估”问题立刻改善了。这种“从失败中补规则”的迭代方式基本上是 Skill 工程的核心方法论。Debug 时还有一个实用技巧DeepSeek Harness 的日志里会显示当前加载了哪些 Skill、模型是否读取了 Skill 内容。如果发现任务没有按照预期执行先看日志确认 Skill 是否被触发再看 SKILL.md 里的规则是否足够具体。很多时候问题不是模型不行而是 Skill 写得不够清晰。5. 三合一实战一个“异常巡检与汇报”场景5.1 需求描述与方案选型讲了这么多理论干脆用一个完整案例把三者串起来。这里我选的场景是“服务器异常巡检与汇报”——不少团队都有这种需求逻辑不复杂但很能说明三者的配合方式。需求是用户每天上班后问 Harness 一句“看看今天服务器有没有异常”Harness 要检查服务器负载、检查磁盘、翻一下最近日志里的错误然后把结果汇总成一段报告并可以推送消息到群里。这里的方案选型很典型服务器指标查询和日志读取用 Tools 做因为这些是只在本机生效的轻量能力如果团队中还有其他系统需要读取比如数据库慢查询、监控平台接口就值得统一走 MCP 了。我在这个案例里把监控数据源通过一个自定义 MCP Server 暴露出来同时保留两个本地 Tools 做聚合处理。5.2 配置拆解首先是 MCP Server 侧用一个简单的 HTTP 方式暴露监控接口mcp_servers: monitor_center: transport: streamable-http url: http://localhost:8300/mcp env: MONITOR_TOKEN: ${MONITOR_TOKEN}然后是 Tools 注册在本地实现报告生成和消息推送tool( namesend_report_to_group, description把巡检结果发送到企业微信群当巡检完成并且存在异常时使用, parameters{...} ) def send_report_to_group(report_text: str): # 调用企业微信 webhook 发送报告 pass最后是 Skill规定整个巡检任务的执行路径--- name: daily_inspection description: 服务器日常巡检检查负载、磁盘、错误日志并生成报告。当用户提到巡检、异常检查、看看服务器状态等场景时使用。 tools: - get_server_load - get_error_logs - send_report_to_group --- # 巡检执行规则 1. 先调用 get_server_load 获取系统负载数据。 2. 再查看最近 30 分钟的错误日志。 3. 如果任一指标异常调用 send_report_to_group 推送报告。 4. 最终输出包含摘要、异常项、建议动作的 Markdown 报告。5.3 运行效果复盘这个案例配好后用户输入“今天机器没啥问题吧”Harness 的调度过程是这样的先匹配到 daily_inspection Skill然后按 Skill 里定义的优劣排序依次调用 get_server_load、get_error_logs最后根据结果决定是否触发 send_report_to_group。整个过程几乎不需要用户干预Agent 自己按手册走完了流程。我用这个案例测试过好几种配置组合最有价值的结论是Skill 里定义的“工具偏好顺序”非常有用。以前没有 Skill 时模型可能先读日志再查负载顺序随意现在 Skill 里明确了先后顺序输出的报告结构也更稳定了。另外一个心得是Skill 里应该写清楚“什么情况下不要做什么”。比如我在巡检 Skill 里加了一条“如果没有异常不要发送群消息”避免 Agent 每天早上给全群发一条“正常”的骚扰消息。这类负面指令对 Agent 行为的约束往往比正面指令更有效。6. 常见问题与排查技巧实录6.1 工具不调用模型一直用“猜”的这是接入工具之后最常遇到的问题。你明明注册好了工具模型却偏不用自己编一个答案给你。排查思路按优先级排列第一步看工具描述。把 description 改得更精确明确写“当用户询问 xx 时必须调用此工具”避免抽象描述。第二步看工具的返回格式如果历史调用中工具总是报错模型会学会“避开这个工具”你需要先修复工具的稳定性。第三步看模型配置的温度参数如果 temperature 设置太高模型更倾向于自由发挥而不是调用工具建议调试时设置 temperature0。我实测过的经验是绝大多数“不调用工具”的问题都是第一步没有做到位。模型对工具描述的理解是很字面的你写“获取服务器状态”它可能只在用户同样说“服务器状态”时才触发。改写成“获取服务器 CPU、内存、磁盘使用率信息当用户询问负载、运行状态、卡顿原因时使用”之后触发率会明显提升。6.2 MCP 连接失败或找不到 ServerMCP 接入失败的常见症状有两类。第一类是 Harness 启动时直接报错提示无法连接某个 MCP Server这类问题通常出在网络或地址配置上特别是 streamable-http 模式的 URL 写错、端口没开、Token 失效。排查方法是先用 curl 手动请求一下 MCP endpoint确认服务本身是否存活。第二类是启动不报错但对话中提示找不到某个工具。这类问题通常是 MCP Server 注册了但工具列表还没有同步到 Harness。我用的办法是查看 Harness 的 tool list 命令输出确认 MCP 工具有没有加载进去。如果确实没加载重启 Harness 或者触发一次热加载。这里特别提醒一下环境变量的问题。MCP Server 的 Token、密钥一般通过 env 传入但很多新手把环境变量直接写到配置文件里然后提交到代码仓库导致密钥泄露。正确做法是使用系统的环境变量注入方案配置里只写占位符运行时再注入真实值。6.3 Skill 匹配不准确、规则被忽略Skill 不是万能的你写了规则它不一定照做。我遇到过两类问题Skill 没有被触发以及 Skill 被触发但规则执行不彻底。第一种问题的排查方向是 description 的匹配度。Harness 的匹配是用文本相似度计算如果 description 过于宽泛一次可能匹配上多个 Skill如果过于具体用户换个说法就匹配不上。我的建议是 description 里写 2 到 3 个常见说法并把不适用场景也列出来减少误匹配。第二种问题通常不是模型的错而是 SKILL.md 里的规则不够指令化。比如说“确保 SQL 安全”这种含糊描述模型不知道怎么执行就只会轻描淡写地加一句“请确认 SQL 是否正确”。改写成具体步骤比如“UPDATE 语句必须带有 WHERE且 WHERE 引用的字段必须在 schema 中存在”模型就能稳定执行了。6.4 团队协作时 Skill 的版本管理最后说一个容易被忽略的问题Skill 上线之后怎么管理版本。我见过不少团队Skill 直接改在线上环境改坏了大家都受影响想回滚都不知道从哪里回。我的做法是把 Skill 目录纳入代码仓库走 Git 管理。每个 Skill 更新时走正常的代码评审流程合入之后再部署到 Harness 环境。这样每一次改动都有记录出问题也能快速回滚。对于已经有 CI/CD 流程的团队这个成本几乎为零但收益非常明显。DeepSeek Harness 本身支持从远程 Git 仓库加载 Skill这一点实测下来很稳定。团队里维护一个 skills 仓库成员提 MR 加新 Skill经过评审后自动同步到测试环境和生产环境。这套流程跑通之后Skill 的迭代速度会快很多。我这个系列写到这里想强调一个观点DeepSeek Harness 的 Tools、MCP、Skill 三件套本质上是一个从“能力供给”到“流程规范”的完整闭环。MCP 解决工具从哪里来Tools 解决能力怎么执行Skill 解决任务怎么编排。三者配合好了Agent 才真正像一个有经验的人而不是一个只会提建议的顾问。根据我个人的实际操作体验建议接入顺序是先做 Tools把一个简单的真实函数跑通然后接一个现成的 MCP Server感受一下“工具即插即用”的爽快最后再花心思写 Skill把日常重复任务慢慢沉淀成技能包。前面两步半天就能完成第三步需要长期迭代。但正是这个迭代过程才是把 DeepSeek Harness 从“能跑”变成“好用”的关键。
返回列表