[DeepSeek Harness深度拆解-10]工具如何定义和注册

发布时间:2026/10/21 5:33:36
[DeepSeek Harness深度拆解-10]工具如何定义和注册 工具对于Agent的作用不言而喻。虽然不同的Agent框架针对工具具有不同的定义和注册方式但是工具的大部分描述信息是为LLM提供的因为最终决定调用哪个工具决定于LLM针对推理任务的理解和当前可用工具的描述所以DSH针对工具的定义也不会有什么太特别的地方。如果硬要说特别的化那就是源于DSH建立在Cordis之上需要以插件的形式调用相应的服务来注册工具。这篇文章我们将通过一系列的实例来体现工具定义和注册的编程模式。1. 在自定义插件中定义和注册工具为了便于Debug我们依然采用源码的方式启动DSH。我们在根目录上创建一个名为./explor的目录并在其中定义插件和对应的补丁文件具体的目录结构如下。我们在DeepSeek Harness深度拆解-06在自定义插件中体验LLM的动态路由就是采用这种方式来体现LLM的动态路由机制的。./explor ├── src | └── tool_explor.ts ├── cordis.patch.yml ├── package.json └── tsconfig.json工具的定义和注册都体现在./explor/src/tool_explor.ts这个.ts文件中。如代码所示我们具体注册的是一个通过ToolDefinition接口表示的工具定义该接口基于与工具相关的大部分类型都由deepseek-ai/dsh-tools这个包提供。我们按照此接口定义了一个用来根据指定城市提供天气信息的工具并利用字段name、description和parameters指定了工具的名称、描述和输入参数的JSON Schema。output字段利用schema提供工具输出对象的结构render提供了一个函数将工具函数返回的对象转换成LLM能够识别的内容。import{Context}fromdeepseek-ai/cordisimport{ToolDefinition}fromdeepseek-ai/dsh-toolsexportconstnametool_explorexportasyncfunctionapply(ctx:Context){consttool:ToolDefinition{name:get_weather,description:Get the specified citys weather information.,parameters:{type:object,properties:{city:{type:string,description:The city to look up weather for.},},required:[city],},output:{schema:{type:string},render:(_args,value:string)[{type:text,text:value}],},asyncexecute(args:any,_){returnIt is 20 °C raining in${args.city}right now.},}ctx.tools.register(tool)}至于工具在本地的执行逻辑则直接定义在execute字段对应的函数中。作为模拟我们返回一个固定的天气信息。我们定义的这个ToolDefinition对象最终需要利用ctx.tools返回的ToolRuntime对象的register方法进行注册。顾名思义作为工具执行的运行时ToolRuntime是与工具相关的最核心的类型我们将在后续的文章对它进行系统介绍。针对上面定义的插件我们修改了对应的补丁文件./explor/cordis.patch.yml。-insert:-id:tool_explorname:E:\dsh\deepseek-harness\explor\src\tool_explor.tsinject:[tools]接下来我们以源码的形式将源文件apps/cli/src/bin.ts作为启动程序以headlessProfile启动DSH。我们附件了上面这个补丁文件并提出我们的问题根据苏州目前的天气给出适合的着装建议。输出不仅给出了最终的答案还给出了它的推理过程。不论是最终答案还是推理流程都体现了针对get_weather工具的调用。E:\dsh\deepseek-harnessnpx tsx apps/cli/src/bin.ts --profile headless --patch ./explor/cordis.patch.yml 根据苏州目前的天气给出适合的着装建议 npm notice run deepseek-ai/dsh-root0.1.5-alpha.2 npx npm notice run tsx apps/cli/src/bin.ts --profile headless --patch ./explor/cordis.patch.yml 根据苏州目前的天气给出适合的着装建议 dsh: reasoning: The user is asking about current weather in Suzhou and clothing recommendations. I have a get_weather tool available. Let me use it to get Suzhous weather. This is a simple task. Let me call get_weather for Suzhou. dsh: reasoning: The weather is 20°C and raining in Suzhou. Let me give clothing recommendations. 根据苏州当前天气**20°C正在下雨**给你以下着装建议 ## ️ 苏州当前着装建议20°C 雨天 **核心原则防雨 舒适保暖叠穿更灵活** ### 上装 - 一件**长袖薄针织衫 / 卫衣 / 薄款毛衣**即可20°C 体感偏舒适但雨天会有凉意 - 怕冷的话可加一件**薄外套风衣、牛仔外套、针织开衫**方便随时穿脱 ### 外层重点 - 务必带**防水的风衣 / 冲锋衣**或**雨衣 / 雨伞**下雨天这是刚需 ### 下装 - **长裤**牛仔裤、休闲裤、西装裤都合适 - 不建议短裤雨天偏凉且容易淋湿 ### 鞋子 - 选择**防水或易干的鞋**皮鞋、皮面运动鞋避免帆布鞋、网面鞋容易渗水 - 条件允许可备一双换穿 ### 配饰 - 一把**折叠伞**随身携带 - 可选一顶帽子或轻便围巾防风防潮 --- **小结**20°C 的雨天属于不冷不热但潮湿的天气**叠穿 防水外层 防滑/防水鞋**是最稳妥的组合。出门记得带伞☔ 如果需要更详细的信息比如未来几小时降雨趋势可以告诉我。2. 调用defineTool函数定义工具虽然工具定义以ToolDefinition接口的方式定义但是按照这个结构自行构建工具还是比较繁琐所以deepseek-ai/dsh-tools还提供了一个专门用来定义工具的defineTool函数使用它可用是工具定义稍微简单一点。比如上面这个get_weather工具就可用改用如下的方式利用defineTool函数来定义。import{Context}fromdeepseek-ai/cordisimport{defineTool}fromdeepseek-ai/dsh-toolsexportconstnametool_explorexportasyncfunctionapply(ctx:Context){consttooldefineTool({name:get_weather,description:Get the specified citys weather information.,parameters:{city:{type:string,description:The city to look up weather for.},},output:{schema:{type:string},render:(_args,value:string)[{type:text,text:value}],},asyncexecute(args:any,_){returnIt is 20 °C raining in${args.city}right now.}})ctx.tools.register(tool)}3. 查看发送给LLM的工具信息之所以需要利用ToolDefinition接口来规范工具定义源于LLM对工具描述的要求。我们可用按照如下的方式通过监听llm/stream事件看看我们注册的工具最终以何种形态发送给LLM。import{Context}fromdeepseek-ai/cordisimport{defineTool}fromdeepseek-ai/dsh-toolsimport{GenerateOptions}fromdeepseek-ai/dsh-llmexportconstnametool_explorexportasyncfunctionapply(ctx:Context){...ctx.tools.register(tool)ctx.on(llm/stream,(options:GenerateOptions,next){consttooloptions.tools?.find(tt.nameget_weather)if(tool){console.log(get_weather tool in LLM (${options.provider}/${options.model}) request)console.log(JSON.stringify(tool,null,2))}returnnext()})}按照与上面一致的方式启动DSH会得到如下的输出结果。可用看出整个执行流程两次调用LLM并且都携带了针对注册工具的信息并且只包含Schema相关的信息即名称、描述和参数的数据结构。需要说明的是不同的LLM对注册工具的描述并不一致这样也是LLM适配器的一项核心工作。输入也表明了采用的模型是deepseek-official/deepseek-v4-pro。E:\dsh\deepseek-harnessnpx tsx apps/cli/src/bin.ts --profile headless --patch ./explor/cordis.patch.yml 根据苏州目前的天气给出适合的着装建议 npm notice run deepseek-ai/dsh-root0.1.5-alpha.2 npx npm notice run tsx apps/cli/src/bin.ts --profile headless --patch ./explor/cordis.patch.yml 根据苏州目前的天气给出适合的着装建议 get_weather tool in LLM request { name: get_weather, description: Get the specified citys weather information., parameters: { type: object, properties: { city: { type: string, description: The city to look up weather for. } } } } dsh: reasoning: The user is asking me to give clothing advice based on the current weather in Suzhou. I have a get_weather tool. Let me get the weather for Suzhou. get_weather tool in LLM request { name: get_weather, description: Get the specified citys weather information., parameters: { type: object, properties: { city: { type: string, description: The city to look up weather for. } } } } dsh: reasoning: The weather is 20°C and raining in Suzhou. Let me give appropriate clothing advice. 苏州现在气温 **20°C**正在下雨。根据这个天气情况建议如下着装 ## 穿衣建议20°C 雨天 **上衣** - 一件长袖衬衫、薄款针织衫或卫衣即可20°C 不会太冷单穿偏薄长袖正合适。 - 也可选择「短袖内搭 薄外套」的组合方便早晚或雨停后调节。 **外套关键** - 一定要带**防水/防风外套**比如冲锋衣、轻便雨衣或带帽子的防水夹克。 - 普通棉质外套不防水淋湿后会又冷又重不建议作为外层。 **下装** - 长裤牛仔裤、休闲裤、运动裤即可不需要加秋裤。 **鞋袜** - 建议穿**防滑、防水**的鞋比如防水运动鞋、雨鞋或皮面鞋避免网面运动鞋。 - 袜子选吸湿透气的可多备一双以防鞋袜被打湿。 ## ☂️ 出行提醒 - 带好雨伞雨天地面湿滑步行注意安全。 - 如果骑电动车/步行时间较长可考虑戴帽子或穿连帽外套。 - 20°C 加雨水体感会偏凉一点早晚出门可以多搭一件薄外套。 **一句话总结**薄长袖 防水外套 长裤 防滑鞋出门务必带伞。☔4. 利用约束控制工具的可见性默认情况下所有注册的工具都会发送给LLM但是我们知道发送太多与当前任务完全不相关的工具列表会造成负面的影响此时我们可用在Agent的范围内这里的范围指的就是DeepSeek Harness深度拆解-09:基于Scope的隔离机制是如何实现的介绍的Scope调用ToolRuntime的restrict方法允许或者拒绝相应的工具。比如在如下的演示程序中我们通过注册agent/created事件得到当前执行的Agent并在它提供的Context中以上述的方式禁用我们注册的get_weather工具。import{Context}fromdeepseek-ai/cordisimport{defineTool}fromdeepseek-ai/dsh-toolsimport{GenerateOptions}fromdeepseek-ai/dsh-llmimportdeepseek-ai/dsh-agentexportconstnametool_explorexportasyncfunctionapply(ctx:Context){...ctx.on(agent/created,(payload){payload.agent.ctx.tools.restrict({deny:[get_weather]})})}再次按照相同的方式启动DSH注册的get_weather工具将不会发送给LLM。通过LLM的推理可用看出它会启动一个web search任务访问和风天气 · 苏州得到真实的天气并最终给出着装建议。E:\dsh\deepseek-harnessnpx tsx apps/cli/src/bin.ts --profile headless --patch ./explor/cordis.patch.yml 根据苏州目前的天气给出适合的着装建议 npm notice run deepseek-ai/dsh-root0.1.5-alpha.2 npx npm notice run tsx apps/cli/src/bin.ts --profile headless --patch ./explor/cordis.patch.yml 根据苏州目前的天气给出适合的着装建议 dsh: reasoning: The user is asking for clothing suggestions based on current weather in Suzhou. This is a simple web search task. I need to find current weather in Suzhou and give clothing advice. Let me search for current weather in Suzhou. dsh: reasoning: Let me fetch a weather page to get current weather in Suzhou. Let me fetch the qweather or weather.com page. dsh: reasoning: I have the qweather data which is useful. The date shown is 2026-09-22 (this is a simulated/snapshot date, but Ill use whats available). Current conditions: 25°C, fog (雾), AQI 优 (excellent), 东北风 2级, humidity 80%, UV 中等, feels like 27°, today: 晴白天 23-29°C. Tomorrow 24-29°C, Thursday 24-30°C, Friday 25-31°C, etc. Note the date is 2026-09-22 in the fetched content. This is likely the harnesss simulated current date. I should present based on the fetched weather data. Current: 25°C, foggy, humidity 80%, feels 27°. Today high 29°, low 23°, sunny during day, cloudy at night. Northeast wind level 2. UV medium. AQI excellent. Clothing advice for Suzhou: late September, warm but humid, temp 23-29°C. Recommend lightweight breathable clothing, short sleeves, thin long sleeves, thin pants. Morning fog/humidity 80% means it may feel a bit muggy. Evening cooler ~23°C, bring a light jacket/cardigan. UV medium, sun protection. Let me give concise clothing advice in Chinese, citing sources. 根据我查到的苏州当前天气数据给出以下着装建议。 ## 苏州当前天气概览 - **气温**当前 25℃体感 27℃今天白天 2329℃晴夜间转多云 - **天气现象**雾相对湿度 80% - **风力**东北风 2 级 - **紫外线**中等 - **空气质量**优AQI 25PM2.5 25 - 未来几日气温走高周三至周五最高 2931℃最低 2425℃ 数据来源[和风天气 · 苏州](https://www.qweather.com/weather/suzhou-101190401.html) ## 着装建议 **核心思路夏末秋初白天偏热、早晚微凉、湿度大主打轻薄透气 一件可脱的外搭。** 1. **上身**短袖 T 恤、棉麻衬衫、薄款 Polo 衫即可怕晒或通勤可叠穿一件**薄款长袖衬衫或防晒衣**。 2. **下身**薄长裤休闲裤、薄牛仔裤、阔腿裤或及膝短裤都合适。 3. **早晚保暖**早间有雾、湿度达 80%体感偏闷夜间最低约 23℃ 并转多云建议随身带一件**薄外套、针织开衫或连帽卫衣**早晚和空调房内穿脱方便。 4. **鞋袜**透气运动鞋、帆布鞋或船鞋配薄棉袜适合长时间走动和苏州园林、古街游览。 5. **防晒与配件**紫外线中等白天户外建议戴**遮阳帽、太阳镜**并涂防晒霜湿度高可备把**晴雨两用伞**应对晨雾和可能的阵性降雨。 **一句话总结**白天轻装上阵短袖/薄长袖 薄长裤早晚加件薄外套即可兼顾防晒和透气。 需要我进一步结合某一天比如周末的具体气温再细化吗5. 工具执行前的最后一道关卡ToolRuntime还提供了一个guard方法我们将它视为执行工具的最后一道门卫。具体来说我们可以利用这个方法注册一个回调当Agent在执行工具函数之前会先调用此回调。如果此回调返回undefined意味着门卫放行继续完成目标工具的执行否则返回的字符串将会作为本次工具调用的结果并反馈给LLM。以下面的演示程序为例我们在agent/created事件的处理函数中改调guard方法注册的回调会根据作为参数的ToolExecution得到工具名称如果是get_weather我们直接返回这段文字:get_weather tool provides fake weather information only.import{Context}fromdeepseek-ai/cordisimport{defineTool}fromdeepseek-ai/dsh-toolsimport{GenerateOptions}fromdeepseek-ai/dsh-llmimportdeepseek-ai/dsh-agentexportconstnametool_explorexportasyncfunctionapply(ctx:Context){...ctx.on(agent/created,(payload){payload.agent.ctx.tools.guard(toolExecution{if(toolExecution.nameget_weather){returnget_weather tool provides fake weather information only.}returnundefined})})}我们依然采用相同的方式启动DSH此时会得到如下输出E:\dsh\deepseek-harnessnpx tsx apps/cli/src/bin.ts --profile headless --patch ./explor/cordis.patch.yml 根据苏州目前的天气给出适合的着装建议 npm notice run deepseek-ai/dsh-root0.1.5-alpha.2 npx npm notice run tsx apps/cli/src/bin.ts --profile headless --patch ./explor/cordis.patch.yml 根据苏州目前的天气给出适合的着装建议 get_weather tool in LLM (deepseek-official/deepseek-v4-pro) request { name: get_weather, description: Get the specified citys weather information., parameters: { type: object, properties: { city: { type: string, description: The city to look up weather for. } } } } dsh: reasoning: The user asks for clothing advice based on the current weather in Suzhou. I need to get the weather for Suzhou. I have a get_weather tool. Let me use it. get_weather tool in LLM (deepseek-official/deepseek-v4-pro) request { name: get_weather, description: Get the specified citys weather information., parameters: { type: object, properties: { city: { type: string, description: The city to look up weather for. } } } } dsh: reasoning: The get_weather tool provides fake weather information only. So I cannot use it for real weather. I should use web search to get current weather for Suzhou. Let me search the web for the current weather in Suzhou. get_weather tool in LLM (deepseek-official/deepseek-v4-pro) request { name: get_weather, description: Get the specified citys weather information., parameters: { type: object, properties: { city: { type: string, description: The city to look up weather for. } } } } dsh: reasoning: The search results dont give me the actual temperature. I need to fetch a page to get current weather. Let me fetch the qweather or weather.com page. Let me try to fetch a page that gives concrete data. Let me fetch the moji or qweather page. Actually, let me fetch the qweather page for Suzhou to get current conditions. get_weather tool in LLM (deepseek-official/deepseek-v4-pro) request { name: get_weather, description: Get the specified citys weather information., parameters: { type: object, properties: { city: { type: string, description: The city to look up weather for. } } } } dsh: reasoning: I got the weather data from qweather. Let me extract the key facts: - 苏州, 江苏, 2026-09-22, 星期二 - 当前 25°C, 阵雨 (shower) - 西北风 2级 - 湿度 81% - 体感温度 26° - 今天白天晴夜晚多云 - 穿衣指数: 热 - 舒适度指数: 较舒适 - 紫外线: 中等 - 今日 29°~23°, 明天 29°~24° So I can give dressing advice based on this. Current: 25°C, 阵雨, humidity 81%, feels like 26°, daytime high 29°, low 23°. Advice: light summer clothing, short sleeves, thin shirts. Bring umbrella/rain gear due to showers. Maybe light jacket for evening (23°). Breathable fabrics due to 81% humidity. Sun protection for moderate UV. Let me write a concise Chinese answer with citation. 根据和风天气的最新数据苏州当前2026-09-22天气为**阵雨25℃体感 26℃**西北风 2 级相对湿度 81%今天白天晴、夜间多云全天 23℃29℃。穿衣指数为「热」舒适度「较舒适」。 ## 着装建议 **白天2529℃体感偏热** - 以**轻薄透气**为主短袖 T 恤、薄衬衫、薄连衣裙、短裤或轻薄长裤。 - 面料选**纯棉、亚麻、速干**类避免不透气的化纤应对 81% 的高湿度。 **早晚23℃ 左右** - 温差约 6℃早晚略凉可备一件**薄款长袖、防晒衫或薄外套**进出空调房也能挡一挡。 **针对阵雨** - 务必带**伞或轻便雨具**穿**防水或快干**的鞋避免帆布鞋湿了难受。 **防晒** - 紫外线中等白天长时间户外可涂防晒、戴遮阳帽。 一句话总结**短袖 薄长裤/短裤为主随身带伞和一件薄外套**既应对阵雨又兼顾早晚温差。 来源[和风天气 · 苏州市](https://www.qweather.com/weather/suzhou-101190401.html)结合携带推理的输出我们可以大致看出内部的执行流程get_weather工具相关信息被发送给LLM并被选择Agent在执行此工具前会先执行guard方法注册的回调并返回一段文字。所有get_weather工具对应的函数并不会被执行前者返回的字符串将作为它的结果反馈给LLMLLM得到执行结果后决定采用web search方式获取天气但是得到信息不包含气温决定访问和风天气 · 苏州市获取完整天气信息在得到完整天气信息后作出最终的着装建议。这篇文章涉及到定义和注册工具相关的一些重要的接口、类型和函数比如ToolDefinition、ToolRestriction和ToolGuard以及defineTool函数在DeepSeek Harness深度拆解-10:深入探讨工具定义、约束和执行防御

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询