在《GPT最佳实践 - 提升Prompt效果的六个策略》 (opens in a new tab)中,我们介绍了OpenAI官方发布的"GPT 最佳实践"指南的六个策略,其中第五个策略是“使用外部工具”。
通过使用其他工具的输出来弥补GPT的不足。例如,使用文本检索系统来告诉GPT相关文档的信息,或者使用代码执行引擎来帮助GPT进行数学计算和代码运行。如果有其他工具可以更可靠或更有效地完成某个任务,就应该使用这些工具,以获得最佳效果。
具体方法:
- 使用基于嵌入的搜索实现高效的知识检索
- 通过代码执行来进行更准确的计算或调用外部API
- 让模型访问特定的函数
使用基于嵌入的搜索实现高效的知识检索
如果将外部信息作为输入的一部分提供给模型,那么模型可以充分利用这些信息,以生成更可靠和最新的结果。例如,如果用户提出有关特定电影的问题,那么将关于该电影的一些高质量的信息(例如演员、导演等)添加到模型的输入中可能会很有用。
嵌入技术可以用于实现高效的知识检索,从而在运行时动态地将相关信息添加到模型输入中。
文本嵌入,是一种可以用来度量文本字符串之间关联性的向量。相似或相关的字符串在向量空间中会更加接近,而不相关的字符串则较远。基于这一事实,以及向量搜索算法高效的特点,我们可以使用嵌入技术来实现高效的知识检索。
具体来说,可以将文本语料库分割成多个片段,并且每个片段可以被嵌入和存储。然后,可以对给定的查询进行嵌入,并进行向量搜索,以从语料库中找到与查询最相关的嵌入文本块(即在嵌入空间中距离最接近的片段)。
示例的实现可以在 OpenAI Cookbook 中找到。请参阅策略 提升GPT Prompt效果最佳实践 - 提供参考文本,以了解如何使用知识检索来最大程度地减少模型伪造事实的可能性。
在 OpenAI Cookbook 中,提供了一些向量数据库的介绍,以及如何使用的示例说明:
https://cookbook.openai.com/examples/vector_databases/readme (opens in a new tab)
https://github.com/openai/openai-cookbook/tree/main/examples/vector_databases (opens in a new tab)
AnalyticDB
Cassandra/Astra DB
AzureSearch
Chroma
Elasticsearch
Hologres
Kusto
Milvus
MyScale
MongoDB
Pinecone
PolarDB
Qdrant
Redis
SingleStoreDB
Typesense
Weaviate
Zilliz
通过代码执行来进行更准确的计算
我们不能依赖于GPT来进行精确的数学运算或复杂的长时间计算。在需要这样做的情况下,可以指示模型来编写和运行代码,而不是让它自己进行计算。具体来说,可以指示模型将要运行的代码放在指定的格式中,比如三个反引号。在输出结果后,我们可以提取并运行这段代码。最后,如果有需要,可以将代码执行引擎(比如Python解释器)的输出结果作为模型下一个查询的输入。
SYSTEM Prompt
你能够编写和执行Python代码,请将代码用三个反引号包含起来。
```代码放在这里```
然后根据要求执行这段代码,输出计算结果。
USER Prompt
请计算这个多项式的所有实根: 3*x**5 - 5*x**4 - 3*x**3 - 7*x - 10.
对于模型生成的代码,可以Copy出来自己去执行验证是否正确。
通过代码执行来进行更准确的计算 - 调用外部API
代码执行的另一个很好的用例是调用外部 API。如果一个模型接受了如何正确使用API的提示,它就可以编写并使用该 API 代码。可以通过为模型提供文档或展示如何使用API的代码示例,来指导模型如何使用API。
SYSTEM Prompt
你具备通过在三个反引号中编写Python代码和执行Python代码的能力。 现在,你可以使用以下Python代码模块,来帮助用户向他们的朋友发送消息:
```python
import message
message.write(to="Bob", message="嘿,下班后想见面吗?")
```
USER Prompt
请发送一条消息,告诉爱丽丝,我10点在咖啡店见她。
注意:执行模型生成的代码本质上并不安全,任何试图执行此操作的应用程序都应采取预防措施。特别是,需要使用沙盒代码执行环境来限制不受信任的代码可能造成的危害。
让模型访问特定的函数
聊天 API(Chat completions API) 允许在请求中传递"函数描述列表(a list of function descriptions)"。这使得模型能够根据提供的模式生成函数的参数(function arguments)。
调用API之后,以 JSON 格式返回生成的函数参数,这些参数可以用于执行函数调用(execute function calls)。然后,可以将函数调用返回的输出结果,反馈到接下来的模型请求中,以完成调用闭环。这是使用GPT模型调用外部函数(call external functions)的推荐方式。
要了解更多信息,请参阅OpenAI的 GPT 介绍指南中的函数调用部分以及 OpenAI Cookbook 中的更多函数调用示例。
https://platform.openai.com/docs/guides/function-calling (opens in a new tab)
https://cookbook.openai.com/examples/how_to_call_functions_with_chat_models (opens in a new tab)
import openai
import json
# Example dummy function hard coded to return the same weather
# In production, this could be your backend API or an external API
def get_current_weather(location, unit="fahrenheit"):
"""Get the current weather in a given location"""
weather_info = {
"location": location,
"temperature": "72",
"unit": unit,
"forecast": ["sunny", "windy"],
}
return json.dumps(weather_info)
def run_conversation():
# Step 1: send the conversation and available functions to GPT
messages = [{"role": "user", "content": "What's the weather like in Boston?"}]
functions = [
{
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["location"],
},
}
]
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=messages,
functions=functions,
function_call="auto", # auto is default, but we'll be explicit
)
response_message = response["choices"][0]["message"]
# Step 2: check if GPT wanted to call a function
if response_message.get("function_call"):
# Step 3: call the function
# Note: the JSON response may not always be valid; be sure to handle errors
available_functions = {
"get_current_weather": get_current_weather,
} # only one function in this example, but you can have multiple
function_name = response_message["function_call"]["name"]
function_to_call = available_functions[function_name]
function_args = json.loads(response_message["function_call"]["arguments"])
function_response = function_to_call(
location=function_args.get("location"),
unit=function_args.get("unit"),
)
# Step 4: send the info on the function call and function response to GPT
messages.append(response_message) # extend conversation with assistant's reply
messages.append(
{
"role": "function",
"name": function_name,
"content": function_response,
}
) # extend conversation with function response
second_response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=messages,
) # get a new response from GPT where it can see the function response
return second_response
print(run_conversation())
最后,对于向量搜索和函数调用是两个比较独立的主题,有空再聊聊。