GPT提示工程
GPT最佳实践六个策略
使用外部工具

《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/blob/main/examples/vector_databases/README.md (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())

最后,对于向量搜索和函数调用是两个比较独立的主题,有空再聊聊。

参考

https://platform.openai.com/docs/guides/gpt-best-practices/strategy-use-external-tools (opens in a new tab)