# OpenAI函数调用
OpenAI的新函数调用API改变了一切,包括MyScale。
OpenAI刚刚发布了许多更新,包括更便宜的16K上下文GPT-3.5 Turbo和更多可用的GPT-4模型。我们还获得了一个名为函数调用 (opens new window)的新API接口,这对开发人员来说是一个强大的工具。
函数调用改变了我们处理提示的方式。已经有很多尝试自动化结构化查询和向量搜索的好方法,例如LangChain的SQLChain (opens new window)和自查询检索器 (opens new window)。几乎所有这些方法都需要大量的提示,这意味着它们既昂贵又难以调整。OpenAI的新函数调用可以节省大量用于提示的令牌 - 您不需要使用多个长示例来演示函数的用法。
我们发现新发布的GPT-3.5(gpt-3.5-turbo-0613
)与新的函数调用非常配合。只需几次尝试,我们就成功开发出了一个与LangChain的自查询检索器等效的提示。无需定义运算符和比较器,只需提示。您可以在github (opens new window)上看到我们是如何实现的。
# 开始之前...
- 您需要安装一些依赖项:
pip3 install langchain openai clickhouse-connect
- 在MyScale上注册一个帐户,并在MyScale控制台上免费创建一个集群。
- 在控制台上获取您的连接详细信息。您将需要这些信息来运行笔记本。
- 您还需要有效的OpenAI API密钥。
不知道怎么做?请查看我们的集群管理官方文档。
# 查看提示
为了简单起见,我们重用了LangChain的向量存储和自查询检索器的一些辅助函数。
# 创建向量存储并插入数据
我们为您提供了来自ArXiv的8篇论文的元数据和摘要 (opens new window) (感谢arXiv (opens new window)提供其开放访问互操作性)。更多数据可以在我们的AWS存储 (opens new window)上找到。
现在看看代码:
import json
from langchain.schema import Document
from langchain.vectorstores import MyScale
from langchain.embeddings import HuggingFaceEmbeddings
def str2doc(_str):
j = json.loads(_str)
return Document(page_content=j['abstract'], metadata=j['metadata'])
with open('func_call_data.jsonl') as f:
docs = [str2doc(l) for l in f.readlines()]
vectorstore = MyScale.from_documents(
documents=docs, embedding=HuggingFaceEmbeddings())
# 定义元数据列
在这里,我们借用了LangChain的_format_attribute_info
函数。它帮助我们将AttributeInfo
转换为适合提示的纯字符串。
您可以根据需要修改此代码以使用更多的数据类型和函数。您可以使用函数定义列,例如,length(metadata.categories)
表示该类别的长度。在ClickHouse文档 (opens new window)上尝试找到更多有趣的函数,我们原生支持它们以及向量搜索。别忘了加入我们的Discord (opens new window),与我们分享您的新发现或新想法,我们将非常兴奋地与您一起改进它们!
from langchain.chains.query_constructor.base import _format_attribute_info, AttributeInfo
metadata_field_info=[
AttributeInfo(
name="metadata.pubdate",
description="论文发表日期,需要使用`parseDateTime32BestEffort()`将字符串格式的时间戳转换为可比较的格式。",
type="timestamp",
),
AttributeInfo(
name="metadata.authors",
description="作者姓名列表",
type="list[string]",
),
AttributeInfo(
name="metadata.title",
description="论文标题",
type="string",
),
AttributeInfo(
name="text",
description="论文摘要",
type="string",
),
AttributeInfo(
name="metadata.categories",
description="arxiv类别",
type="list[string]"
),
AttributeInfo(
name="length(metadata.categories)",
description="arxiv类别的长度",
type="int"
),
]
formated = _format_attribute_info(metadata_field_info)
# 函数调用构建过滤的向量搜索
与自查询检索器类似,基于函数调用的查询器也输出三个参数来调用向量存储的接口:
query
:将在后续转换为嵌入的查询字符串。where_str
:用于执行过滤的通用WHERE
字符串,但不包括WHERE
关键字。limit
:返回前limit
个元素,默认为4个。
这是我们使用OpenAI函数调用的方式:
import openai
# 简单吧?
query = "什么是贝叶斯网络?"
# 让我们对它做一些约束...
query += "请使用2013年2月之后发布的文章 "
# 还想要更多?关键词过滤器。
query += "并且摘要中包含`artificial`的文章 "
# 这样好多了!跨模态的论文...
query += "具有超过2个类别 "
# 我是一个计算机视觉的人,只想要一些计算机视觉的论文
query += "并且其类别中必须包含`cs.CV`。"
# 现在是结构化提示:
completion = openai.ChatCompletion.create(
# 我们使用了新的gpt模型
model="gpt-3.5-turbo-0613",
# 温度设置为0以确保稳定的行为
temperature=0,
# 现在是函数调用:
# 您需要:
# 1. 为函数命名。
# 2. 为您的函数提供描述
# 3. 在名称和类型中定义参数
functions=[{"name": "to_structued_sql",
"description":
("将查询转换为查询字符串和过滤字符串以进行过滤。"
"在检查元素是否在列表中时,请使用`has(column, element)`。"),
"parameters": {"type": "object",
"properties": {
"query": {"type": "string"},
"where_str": {"type": "string", },
"limit": {
"type": "integer",
"description": "默认为4"}
},
"required": ["subject", "where_str", "limit"]
}
},],
# 调用的函数名称,如果为'auto',模型将自行决定
function_call="auto",
# 这是我们的老朋友:聊天完成提示...
# 您可以编写一些规则来限制模型的行为。
messages=[
{
"role": "system",
"content": ("您需要提供`metadata`来构建SQL。"
"我将使用`parseDateTime32BestEffort()`"
"将字符串格式的时间戳转换为可比较的格式。"),
},
{
"role": "user",
"content": f"元数据:{formated}"
},
{
"role": "system",
"content": "现在您可以输入查询",
},
{
"role": "user",
"content": query
},
],
)
然后进行搜索!
与LangChain自查询检索器完全相同。而且它更灵活 - 它可以编写任何SQL...甚至是用户定义的函数。没有限制,所以自己制定一个案例吧!
ret = vectorstore.similarity_search(**search_kwargs)
for r in ret:
print(r)
# 使用函数调用的提示
以下是使用函数调用的一些建议:
- 可读性强的名称为LLM提供了更多信息,无论您是使用这种新的函数调用还是传统的提示。
- 如果您想对列设置一些规则,例如,在与其他值进行比较时进行类型转换,在我们的示例中,请使用列定义进行操作。规则应与相关数据紧密相关。
- LLM倾向于模仿其熟悉的数据之间的映射函数。就像这个演示一样,自然语言和SQL对LLM来说都很常见,所以结果超出了预期。
我们相信您可以发现更多!为什么不在Discord (opens new window)上与MyScale分享您的发现呢?
# 最后
我们相信这将是人们或智能系统与向量数据库一起工作的未来。我们对这样的升级和新功能感到非常兴奋,以开发一个更可扩展和稳定的AGI系统。🚀我们希望MyScale能帮助您成长和成功,我们将使这成为现实!立即加入我们的Discord (opens new window),收到一个温暖的拥抱!🤗 🤗