构造一个能有效引导模型判断是否调用工具的Prompt,关键在于清晰定义工具、明确决策规则、严格约束输出格式。下面通过一个最简单的天气查询例子,分步拆解。
一、核心Prompt结构示例
假设我们只有一个工具:get_weather(获取天气)。以下是最简化的Prompt:
python
# 定义工具信息(通常从工具注册表中动态获取)
available_tools = [
{
"name": "get_weather",
"description": "获取指定城市的当前天气情况。输入必须是城市名称。",
"parameters": {
"location": {
"type": "string",
"description": "城市名称,例如:北京、上海、纽约"
}
}
}
]
def build_simple_prompt(user_query: str, tools: list) -> str:
"""
构建最简单的工具调用决策Prompt
"""
# 1. 角色与能力定义 system_role = "你是一个AI助手,可以根据问题决定是否调用工具。"
# 2. 工具描述(关键部分)
tools_text = "你可以使用的工具如下:
"
for tool in tools:
tools_text += f"- {tool['name']}: {tool['description']}
"
if "parameters" in tool:
params = tool["parameters"]
tools_text += f" 参数: {list(params.keys())}
"
# 3. 决策规则(核心引导)
decision_rules = """
决策规则:
1. 当用户询问某个地点的当前天气、温度、气候状况时,必须调用get_weather工具。
2. 其他所有问题(如问候、闲聊、知识问答),都直接回答,不要调用工具。
"""
# 4. 输出格式约束(强制结构化)
output_format = """
你必须严格按照以下JSON格式回复:
如果需要调用工具:
{"action": "call_tool", "tool": "工具名", "parameters": {"参数名": "参数值"}}
如果直接回答:
{"action": "direct_answer", "content": "你的回答内容"}
"""
# 5. 组合完整Prompt
full_prompt = f"""{system_role}
{tools_text}
{decision_rules}
{output_format}
用户问题:{user_query}
"""
return full_prompt
# 测试不同查询
test_queries = [
"北京今天天气怎么样?", # 应触发工具调用
"你好,请介绍一下你自己", # 应直接回答
"上海现在多少度?", # 应触发工具调用 "机器学习是什么?" # 应直接回答
]
for query in test_queries:
prompt = build_simple_prompt(query, available_tools)
print(f"问题: {query}")
print("生成的Prompt前200字符:", prompt[:200] + "...")
print("-" * 50)
二、Prompt各部分的详细作用
| Prompt部分 | 内容示例 | 设计目的 | 关键技巧 |
|---|---|---|---|
| 角色定义 | 你是一个AI助手... |
设定模型行为边界 | 简洁明确,避免歧义 |
| 工具描述 | get_weather: 获取指定城市的当前天气 |
让模型知道能做什么 | 1. 名称直观 2. 描述具体 3. 参数清晰 |
| 决策规则 | 当用户询问天气...必须调用工具 |
明确调用条件 | 1. 使用"必须"、"不要"等强引导词 2. 列举典型场景 |
| 输出格式 | {"action": "call_tool"...} |
强制结构化输出 | 1. 提供完整JSON示例 2. 指定键名 |
| 用户问题 | 北京今天天气怎么样? |
提供查询上下文 | 放在最后,清晰分隔 |
三、实际调用与解析流程
python
import json
import openai
def call_model_with_prompt(prompt: str) -> str:
"""调用大模型获取响应(简化示例)"""
# 实际应使用API调用,这里模拟返回
test_responses = {
"北京今天天气怎么样?": '{"action": "call_tool", "tool": "get_weather", "parameters": {"location": "北京"}}',
"你好,请介绍一下你自己": '{"action": "direct_answer", "content": "我是AI助手,可以帮你查询天气信息。"}',
"上海现在多少度?": '{"action": "call_tool", "tool": "get_weather", "parameters": {"location": "上海"}}',
"机器学习是什么?": '{"action": "direct_answer", "content": "机器学习是人工智能的一个分支,让计算机从数据中学习规律。"}'
}
# 模拟根据问题返回对应响应
for q, resp in test_responses.items():
if q in prompt: # 简化匹配逻辑
return resp
return '{"action": "direct_answer", "content": "我不确定如何回答这个问题。"}'
def process_user_query(user_query: str):
"""完整的查询处理流程"""
# 1. 构建Prompt
prompt = build_simple_prompt(user_query, available_tools)
print(f"[Prompt内容]\
{prompt}\
")
# 2. 调用模型
model_response = call_model_with_prompt(prompt)
print(f"[模型原始响应]\
{model_response}\
")
# 3. 解析响应 try:
response_data = json.loads(model_response)
if response_data["action"] == "call_tool":
tool_name = response_data["tool"]
parameters = response_data["parameters"]
print(f"✅ 模型决定调用工具: {tool_name}")
print(f" 参数: {parameters}")
# 4. 执行工具(模拟)
if tool_name == "get_weather":
weather = f"{parameters['location']}的天气:晴,25℃" # 模拟工具执行 print(f" 工具执行结果: {weather}")
return weather elif response_data["action"] == "direct_answer":
print(f"✅ 模型决定直接回答")
print(f" 回答内容: {response_data['content']}")
return response_data["content"]
except json.JSONDecodeError:
print("❌ 模型响应不是有效的JSON格式")
return "解析响应时出错"
return None
# 运行测试
print("=" * 60)
print("测试1: 天气查询")
result1 = process_user_query("北京今天天气怎么样?")
print("=" * 60)
print("\
测试2: 一般问答")
result2 = process_user_query("机器学习是什么?")
print("=" * 60)
四、Prompt设计的关键要点
-
工具描述要具体 :
python# 不好的描述 ❌ "获取天气"
好的描述 ✅
"获取指定城市的当前天气情况,包括温度、湿度和天气状况。输入必须是城市名称。"
2. **决策规则要明确**:
```python
# 模糊的规则 ❌ "有时候可以调用工具"
# 明确的规则 ✅ "当且仅当用户明确询问当前天气时调用get_weather工具,其他情况一律直接回答。"
-
输出格式要严格 :
python# 宽松的格式 ❌ "用JSON格式回复"
严格的格式 ✅
"""必须严格按照以下JSON格式回复:
{"action": "call_tool", "tool": "工具名", "parameters": {"参数名": "参数值"}}
或
{"action": "direct_answer", "content": "回答内容"}"""
4. **提供少量示例(Few-shot)可提高准确性**:
```python examples = """
示例:
用户:北京天气如何?
输出:{"action": "call_tool", "tool": "get_weather", "parameters": {"location": "北京"}}
用户:你好吗?
输出:{"action": "direct_answer", "content": "我很好,谢谢!"}
"""
五、常见问题与优化
| 问题 | 表现 | 优化方法 |
|---|---|---|
| 模型不遵循格式 | 返回自然语言而非JSON | 1. 在Prompt开头强调"必须严格按格式" 2. 提供更详细的格式示例 |
| 误判工具调用 | 不该调用时调用 | 1. 细化决策规则 2. 增加负面示例(什么情况不调用) |
| 参数提取错误 | 参数值不正确 | 1. 在工具描述中明确参数格式 2. 提供参数示例 |
| 多工具混淆 | 多个工具时选错 | 1. 清晰区分工具功能 2. 按优先级排序工具列表 |
总结 :构造工具调用Prompt的核心是清晰描述工具能力 + 明确决策规则 + 严格输出约束 。通过这个最简单的天气查询例子,可以看到模型如何根据Prompt的引导,将"北京今天天气怎么样?"解析为调用get_weather工具并提取location: "北京"参数。实际系统中,Prompt会更复杂(支持多工具、多轮对话等),但基本原理相同。