ChatGPT的结构化输出与函数调用
ChatGPT已经成为编程行业的改变者。无论你看到哪里,公司都在寻求使用大型语言模型(LLM)为他们的业务增加价值的方法。作为开发者,我们在未来人职责中能够有意义地使用这项技术是非常重要的。
在处理ChatGPT时,最大的挑战之一是获得结构化输出。代码本质上在一个严格的边界内运行,并期望结构化的数据。这使得开发者难以利用基本提示并将其输入到我们的应用程序中,以发挥OpenAI聊天模型的强大功能。为了解决这个问题,OpenAI在他们的GPT-3.5和GPT-4模型中引入了函数调用。让我们更深入地看一下如何利用函数调用将OpenAI的LLM集成到我们作为开发者的工作中。
问题
让我们来处理一个假设情境。对于我们提供的输入段落,我们希望以以下 JSON 格式返回其摘要和关键词:
{
"summary": "Summary of the text",
"keywords": ["Summary", "text"]
}
如果我们使用文章的第一段提供提示给ChatGPT,我们会得到下面这样的输出:
当然,我们可以改进我们的提示,要求返回一个JSON对象,像这样:
我们正在取得进展,但要将这类返回结果集成到应用程序中,我们需要能够解析返回的文本并创建一个函数以提取其中有意义的数据。这为我们增加了更多工作量,并且由于语言模型响应的差异,几乎不能保证每次都能正常工作。
稳定性与函数调用
函数调用允许我们以一种方式向ChatGPT提供指令,从而提供更一致的数据返回。下面的示例是使用NodeJs和OpenAI客户端库,让我们深入了解它是如何工作的!
设置:
- 安装NodeJs
- 安装OpenAI客户端(npm或yarn)
- 创建OpenAI秘钥
复制问题:
首先,让我们看看如何将上述问题复制到我们的代码聊天补全请求中,以便向OpenAI的聊天补全功能发出请求。
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_SECRET",
});
client.chat.completions
.create({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content: `For a given paragraph, return a summary and a list of keywords that best represents the paragraph.
Return in JSON format:
\`\`\`json
{ "summary": "Summary of the paragraph", "keywords": ["KEYWORD1", "KEYWORD2"] }
\`\`\``,
},
{
role: "user",
content:
"ChatGPT has been a game changer in the programming industry. Everywhere you look, companies are looking for ways to add value to their business using large language models (LLM). As developers, the need to be able to use this technology meaningfully is important as we navigate our roles into the future.",
},
],
})
.then((data) => {
console.log(data.choices[0].message);
});
如果我们运行这段代码,有时候我们会得到类似的响应。你会注意到有时它会给我们想要的确切格式,但一致性的缺乏使其不可靠。
{
role: 'assistant',
content: 'Here is the summary and list of keywords for the provided paragraph:\n\n{\n' +
' "summary": "ChatGPT has revolutionized the programming industry by providing large language models (LLM). Companies are exploring ways to leverage this technology for business value. Developers need to understand and utilize LLM effectively for their role in the future.",\n' +
' "keywords": ["ChatGPT", "game changer", "programming industry", "companies", "value", "large language models", "LLM", "developers", "technology", "roles"]\n' +
'}'
}
相同的请求可以通过具有定义的架构的函数调用来增强。所定义的函数parseParagraph接受两个参数,摘要和关键词,以帮助ChatGPT理解响应的格式。
function parseParagraph(args: {
summary: string,
keywords: string[]
}) {
console.log("summary: ", args.summary)
console.log("summary: ", args.keywords)
}
const definitions = [
{
name: "parseParagraph",
description:
"Convert the paragraph and return a summary and array of keywords relevant to its content.",
parameters: {
type: "object",
properties: {
summary: {
type: "string",
description: "Summary of the paragraph."
},
keywords: {
type: "array",
items: {
type: "string",
description: "A keyword that represents a key concept in the paragraph."
}
}
},
required: ["summary", "keywords"],
},
},
];
更新您的聊天完成请求,并在提示中明确指出应调用定义的函数。
client.chat.completions
.create({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content: `For a given paragraph, return a summary and a list of keywords that best represents the paragraph then call parseParagraph({ summary: string, keywords: string[] }).`,
},
{
role: "user",
content:
"ChatGPT has been a game changer in the programming industry. Everywhere you look, companies are looking for ways to add value to their business using large language models (LLM). As developers, the need to be able to use this technology meaningfully is important as we navigate our roles into the future.",
},
],
function_call: "auto", // "auto" is default but we'll make it explicit
functions: definitions,
})
.then((data) => {
console.log(data.choices[0].message);
});
调用这个聊天完成请求应该返回这样的响应:
{
role: 'assistant',
content: null,
function_call: {
name: 'parseParagraph',
arguments: '{\n' +
' "summary": "ChatGPT has revolutionized the programming industry by providing large language models (LLM) that companies can utilize to add value to their business. It is crucial for developers to learn how to effectively use this technology in order to succeed in their roles.",\n' +
' "keywords": ["ChatGPT", "game changer", "programming industry", "companies", "large language models", "LLM", "add value", "developers", "technology", "roles"]\n' +
'}'
}
}
重要的部分在于现在content为空,而function_call有一个定义的对象。arguments属性应与定义的模式匹配,并且可以通过调用JSON.parse(data.choices[0].message.function_call.arguments)进行解析,其输出如下:
{
summary: 'ChatGPT has revolutionized the programming industry by providing large language models (LLM) that companies can utilize to add value to their business. It is crucial for developers to learn how to effectively use this technology in order to succeed in their roles.',
keywords: [
'ChatGPT',
'game changer',
'programming industry',
'companies',
'large language models',
'LLM',
'add value',
'developers',
'technology',
'roles'
]
}
你可以通过使用这个参数调用你定义的函数,在返回输出之前运行任何自定义的逻辑。
client.chat.completions
.create({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content: `For a given paragraph, return a summary and a list of keywords that best represents the paragraph then call parseParagraph({ summary: string, keywords: string[] }).`,
},
{
role: "user",
content:
"ChatGPT has been a game changer in the programming industry. Everywhere you look, companies are looking for ways to add value to their business using large language models (LLM). As developers, the need to be able to use this technology meaningfully is important as we navigate our roles into the future.",
},
],
function_call: "auto",
functions: definitions,
})
.then((data) => {
const funcArgs = JSON.parse(data.choices[0].message.function_call!.arguments)
return parseParagraph(funcArgs)
});
概要
函数调用是对OpenAI已经革新性技术的一项惊人补充。它使得与LLM的程序集成更加可靠,并为我们使用他们的工具满足自己的需求提供了灵活性。要了解有关微调和他们推荐的最佳实践的更多信息,请查看OpenAI的文档。
希望本文能为您提供关于如何在细调模型等解决方案之前充分利用OpenAI的LLM功能的更多思路。非常期待看到此项新变化给行业带来的发展!