
DeepSeek Agent Harness 2026终极指南 – 第9章第45节 工具描述工程:让模型用对工具的提示词艺术
第44节讲了工具返回值设计,但还有一个问题——模型怎么知道该用哪个工具?你让Agent"查一下天气",它怎么知道要用get_weather而不是web_search?这节讲工具描述工程:怎么写工具描述让模型用对工具。这是工具开发的"提示词工程"。
本文导航
- 为什么工具描述很重要
- 工具描述的四要素
- 参数描述最佳实践
- 坏描述导致错误调用的实验
- A/B实验:好描述 vs 坏描述
- 小结
为什么工具描述很重要
工具描述是模型选择工具的唯一依据。模型看到:
{
"name": "get_weather",
"description": "获取天气",
"parameters": {…}
}
模型会想:
- “获取天气”——这是什么意思?获取哪个城市的天气?怎么获取?
- 如果用户说"北京明天天气怎么样",模型可能用这个工具
- 如果用户说"查一下DeepSeek最新消息",模型可能不会用这个工具
描述不清,模型选错工具。
好的工具描述:
- 明确:告诉模型这个工具做什么、不做什么
- 具体:告诉模型什么时候用、什么时候不用
- 示例:给模型看使用示例
工具描述的四要素
好的工具描述包含四个要素:
案例:get_weather工具
坏描述:
@tool
def get_weather(city: str) –> str:
"""获取天气"""
...
模型不知道:
- 获取哪个城市的天气?(参数city是什么意思)
- 什么时候用这个工具?(用户问什么问题时用)
- 什么时候不用?(用户问历史天气用不用)
好描述:
@tool
def get_weather(city: str) –> str:
"""
获取指定城市当前(今天)的天气信息。
何时使用:
– 用户询问某个城市今天/现在的天气
– 用户需要实时天气信息
何时不使用:
– 用户询问历史天气(昨天、上周)
– 用户询问天气预报(明天、下周)
– 用户询问非天气信息(温度、湿度单独查询)
参数:
– city: 城市中文名,如"北京"、"上海"、"深圳"
示例:
– 用户问"北京今天天气怎么样" → get_weather(city="北京")
– 用户问"上海现在下雨吗" → get_weather(city="上海")
"""
...
模型知道:
- 这个工具获取当前天气
- 用户问"今天天气"时用
- 用户问"历史天气"或"天气预报"时不用
- 参数是城市中文名
参数描述最佳实践
参数描述同样重要。模型需要知道:
- 参数是什么类型
- 参数有什么约束
- 参数的示例值
案例:run_bash工具的command参数
坏描述:
@tool
def run_bash(command: str, timeout: int = 30) –> str:
"""
执行bash命令。
参数:
– command: 命令
– timeout: 超时
"""
...
模型不知道:
- command是什么格式?字符串?列表?
- command支持什么命令?所有bash命令?
- timeout单位是什么?秒?毫秒?
好描述:
@tool
def run_bash(command: str, timeout: int = 30) –> str:
"""
执行bash命令。
参数:
– command: 要执行的bash命令(字符串形式),支持管道、重定向等。
例如:"ls -l"、"pytest tests/ -v"、"pip install requests"
– timeout: 超时秒数(整数),默认30秒。防止命令卡死。
大多数命令30秒内能完成,复杂命令可设60-120秒。
"""
...
模型知道:
- command是字符串,支持管道、重定向
- 有示例:“ls -l”、“pytest tests/ -v”
- timeout单位是秒,默认30秒
坏描述导致错误调用的实验
我们做一个实验:让Agent"查一下DeepSeek最新消息"。
实验设置:
- 有两个工具:get_weather(查天气)和web_search(搜索网页)
- 让Agent查DeepSeek最新消息
坏描述版本:
工具描述:
@tool
def get_weather(city: str) –> str:
"""获取信息"""
...
@tool
def web_search(query: str) –> str:
"""搜索"""
...
Agent反应:
- 看到"获取信息",可能用get_weather
- 看到"搜索",可能用web_search
- 两个描述都很模糊,Agent可能选错
实际结果:Agent可能用get_weather(city="DeepSeek"),报错"未找到城市DeepSeek的天气"。
好描述版本:
工具描述:
@tool
def get_weather(city: str) –> str:
"""
获取指定城市当前(今天)的天气信息。
何时使用:用户询问某个城市今天/现在的天气
何时不使用:用户询问非天气信息
"""
...
@tool
def web_search(query: str) –> str:
"""
搜索网页,获取最新信息。
何时使用:
– 用户询问最新新闻、动态
– 用户询问实时信息(股票、天气、赛事)
– 用户询问技术文档、API用法
何时不使用:
– 用户询问本地文件内容
– 用户询问代码逻辑
"""
...
Agent反应:
- 看到"获取天气",知道get_weather只用于天气
- 看到"搜索网页,获取最新信息",知道web_search用于最新信息
- 用户问"DeepSeek最新消息",Agent用web_search(query="DeepSeek最新消息")
实际结果:Agent正确用web_search,返回搜索结果。
结论:好描述让模型选对工具,坏描述让模型选错工具。
A/B实验:好描述 vs 坏描述
我们做一个A/B实验,对比好描述和坏描述的效果。
实验任务:让Agent完成5个任务
坏描述版本:
工具描述都很简单:
@tool
def get_weather(city: str) –> str:
"""获取天气"""
@tool
def web_search(query: str) –> str:
"""搜索"""
@tool
def read_file(path: str) –> str:
"""读文件"""
@tool
def run_bash(command: str) –> str:
"""执行命令"""
@tool
def grep(pattern: str) –> str:
"""搜索内容"""
结果:
- 任务1:✅ 正确用get_weather
- 任务2:❌ 用get_weather(city="DeepSeek"),报错
- 任务3:✅ 正确用read_file
- 任务4:✅ 正确用run_bash
- 任务5:❌ 用read_file一个个文件读,效率低
正确率:3/5 = 60%
好描述版本:
工具描述详细:
@tool
def get_weather(city: str) –> str:
"""获取指定城市当前天气。何时使用:用户询问天气。何时不使用:非天气信息。"""
@tool
def web_search(query: str) –> str:
"""搜索网页获取最新信息。何时使用:最新新闻、实时信息、技术文档。"""
@tool
def read_file(path: str) –> str:
"""读取文件内容。何时使用:查看单个文件内容。"""
@tool
def run_bash(command: str) –> str:
"""执行bash命令。何时使用:跑测试、装依赖、编译代码。"""
@tool
def grep(pattern: str) –> str:
"""按内容搜索文件。何时使用:找代码、找函数定义。"""
结果:
- 任务1:✅ 正确用get_weather
- 任务2:✅ 正确用web_search
- 任务3:✅ 正确用read_file
- 任务4:✅ 正确用run_bash
- 任务5:✅ 正确用grep
正确率:5/5 = 100%
结论:好描述让工具选择正确率从60%提升到100%。
小结
第9章总结
第9章核心工具集开发全部完成!我们给Agent装上了:
- 文件三件套(第40节):read_file、write_file、edit_file
- bash执行器(第41节):run_bash
- 代码检索(第42节):glob、grep
- 联网能力(第43节):web_search、web_fetch
- 返回值设计(第44节):结构化、token经济学
- 工具描述工程(第45节):让模型用对工具
Agent从"只能对话"升级到"能读改写代码、跑命令、找代码、查文档",真正成为你的编程助手。
下节预告
第9章工具集开发完成,Agent已经很强大了。但还有一个问题——安全。你让Agent"删除所有文件",它真的会执行rm -rf /。下一节进入第10章:安全与权限,给Agent系上安全带。第46节先做权限守卫:三级审批模型,危险操作需要用户确认。
如果觉得本文对你有帮助,欢迎点赞、收藏、关注三连! 本系列持续更新中,关注不迷路~



