跳至内容

OpenAI 函数调用教程

了解 OpenAI 新增的函数调用能力如何让 GPT 模型生成结构化 JSON 输出,解决由不规则输出引发的常见开发问题。
已更新 2026年10月6日  · 8分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

什么是 OpenAI 函数调用?

OpenAI API 擅长以系统化的方式生成响应。您可以管理提示、优化模型输出,并用几行代码来执行、构建语言类应用。

尽管有诸多优点,OpenAI API 过去却常令开发者和工程师头疼。原因何在?他们习惯于处理结构化数据类型,而处理像字符串这样的非结构化数据并不容易。

为获得一致的结果,开发者不得不使用正则表达式(RegEx)或提示工程从文本字符串中提取信息。

这正是 OpenAI 的函数调用功能大显身手之处。它允许 GPT-3.5 和 GPT-4 模型接收用户自定义函数作为输入并生成结构化输出。有了它,您无需再编写正则或进行提示工程。

在本教程中,我将一步步讲解 OpenAI 函数调用如何帮助解决由不规则模型输出引发的常见开发难题。

不使用函数调用的 OpenAI

在本节中,我们将使用 GPT-3.5-Turbo 模型且不启用函数调用来生成响应,看看输出是否一致。

在安装 OpenAI Python API 之前,您需要获取 API 密钥并在本地系统中进行设置。请参阅教程在 Python 中通过 OpenAI API 使用 GPT-3.5 和 GPT-4,了解如何获取并设置 API 密钥。该教程还包含在 DataCamp 的 AI 数据笔记本 DataLab 中设置环境变量的示例。

使用以下命令将 OpenAI Python API 升级到 V1:

pip install --upgrade openai -q

之后,使用 API 密钥初始化 OpenAI 客户端。

import os
from openai import OpenAI

client = OpenAI(
  api_key=os.environ['OPENAI_API_KEY'],
)

注意:OpenAI 不再为新用户提供免费额度,使用 API 需自行购买。

我们将写一段随机的学生描述。您可以自己编写,也可以用 ChatGPT 生成。

student_1_description = "David Nguyen is a sophomore majoring in computer science at Stanford University. He is Asian American and has a 3.8 GPA. David is known for his programming skills and is an active member of the university's Robotics Club. He hopes to pursue a career in artificial intelligence after graduating."

接下来,我们将编写一个提示,从文本中提取学生信息,并将输出返回为 JSON 对象。我们将提取学生描述中的姓名、专业、学校、成绩和社团。

# A simple prompt to extract information from "student_description" in a JSON format.
prompt1 = f'''
Please extract the following information from the given text and return it as a JSON object:

name
major
school
grades
club

This is the body of text to extract the information from:
{student_1_description}
'''

将提示添加到 OpenAI API 的对话补全模块以生成响应。

# Generating response back from gpt-3.5-turbo
openai_response = client.chat.completions.create(
    model = 'gpt-3.5-turbo',
    messages = [{'role': 'user', 'content': prompt_1}]
)

openai_response.choices[0].message.content

响应相当不错。让我们把它转成 JSON,更直观地查看。

'{\n  "name": "David Nguyen",\n  "major": "computer science",\n  "school": "Stanford University",\n  "grades": "3.8 GPA",\n  "club": "Robotics Club"\n}'

我们将使用 `json` 库把文本转换为 JSON 对象。

import json

# Loading the response as a JSON object
json_response = json.loads(openai_response.choices[0].message.content)
json_response

最终结果几乎完美。那么,为什么还需要函数调用?

{'name': 'David Nguyen',
 'major': 'computer science',
 'school': 'Stanford University',
 'grades': '3.8 GPA',
 'club': 'Robotics Club'}

让我们用相同的提示,换一段不同的学生描述。

student_2_description="Ravi Patel is a sophomore majoring in computer science at the University of Michigan. He is South Asian Indian American and has a 3.7 GPA. Ravi is an active member of the university's Chess Club and the South Asian Student Association. He hopes to pursue a career in software engineering after graduating."

我们只更换提示中的学生描述文本。

prompt2 = f'''
Please extract the following information from the given text and return it as a JSON object:

name
major
school
grades
club

This is the body of text to extract the information from:
{student_2_description}
'''

然后,使用第二个提示运行对话补全函数。

# Generating response back from gpt-3.5-turbo
openai_response = client.chat.completions.create(
    model = 'gpt-3.5-turbo',
    messages = [{'role': 'user', 'content': prompt_2}]
)

# Loading the response as a JSON object
json_response = json.loads(openai_response.choices[0].message.content)
json_response

如您所见,结果并不一致。它没有只返回一个社团,而是返回了 Ravi 加入的社团列表。这与第一位学生也不一致。

{'name': 'Ravi Patel',
 'major': 'computer science',
 'school': 'University of Michigan',
 'grades': '3.7 GPA',
 'club': ['Chess Club', 'South Asian Student Association']}

OpenAI 函数调用示例

为解决该问题,我们将使用最近引入的功能——函数调用。关键在于创建一个自定义函数,并将必要信息添加到字典列表中,以便 OpenAI API 理解其功能。

  • name:填写您刚创建的 Python 函数名。
  • description:函数的功能说明。
  • parameters:在“properties”中写出参数名称、类型与描述。这有助于 OpenAI API 识别我们要找的内容。

注意:请确保遵循正确的模式。阅读官方文档了解更多函数调用信息。

student_custom_functions = [
    {
        'name': 'extract_student_info',
        'description': 'Get the student information from the body of the input text',
        'parameters': {
            'type': 'object',
            'properties': {
                'name': {
                    'type': 'string',
                    'description': 'Name of the person'
                },
                'major': {
                    'type': 'string',
                    'description': 'Major subject.'
                },
                'school': {
                    'type': 'string',
                    'description': 'The university name.'
                },
                'grades': {
                    'type': 'integer',
                    'description': 'GPA of the student.'
                },
                'club': {
                    'type': 'string',
                    'description': 'School club for extracurricular activities. '
                }
                
            }
        }
    }
]

接下来,我们将把自定义函数添加到 "functions" 参数中,针对两段学生描述生成响应。之后,我们会将文本响应转换为 JSON 对象并打印。

student_description = [student_1_description,student_2_description]
for i in student_description:
    response = client.chat.completions.create(
        model = 'gpt-3.5-turbo',
        messages = [{'role': 'user', 'content': i}],
        functions = student_custom_functions,
        function_call = 'auto'
    )

    # Loading the response as a JSON object
    json_response = json.loads(response.choices[0].message.function_call.arguments)
    print(json_response)

如我们所见,输出变得统一。我们甚至得到了数值型的成绩而非字符串。对于构建无 bug 的 AI 应用而言,一致的输出至关重要。

{'name': 'David Nguyen', 'major': 'computer science', 'school': 'Stanford University', 'grades': 3.8, 'club': 'Robotics Club'} 

{'name': 'Ravi Patel', 'major': 'computer science', 'school': 'University of Michigan', 'grades': 3.7, 'club': 'Chess Club'}

多个自定义函数

您可以在对话补全函数中添加多个自定义函数。本节我们将看看 OpenAI API 的“魔法”能力:它如何自动选择正确的函数并返回合适的参数。

在 Python 的字典列表中,我们将添加另一个名为“extract_school_info”的函数,用于从文本中提取高校信息。

为实现这一点,您需要再添加一个包含名称、描述和参数的函数字典。

custom_functions = [
    {
        'name': 'extract_student_info',
        'description': 'Get the student information from the body of the input text',
        'parameters': {
            'type': 'object',
            'properties': {
                'name': {
                    'type': 'string',
                    'description': 'Name of the person'
                },
                'major': {
                    'type': 'string',
                    'description': 'Major subject.'
                },
                'school': {
                    'type': 'string',
                    'description': 'The university name.'
                },
                'grades': {
                    'type': 'integer',
                    'description': 'GPA of the student.'
                },
                'club': {
                    'type': 'string',
                    'description': 'School club for extracurricular activities. '
                }
                
            }
        }
    },
    {
        'name': 'extract_school_info',
        'description': 'Get the school information from the body of the input text',
        'parameters': {
            'type': 'object',
            'properties': {
                'name': {
                    'type': 'string',
                    'description': 'Name of the school.'
                },
                'ranking': {
                    'type': 'integer',
                    'description': 'QS world ranking of the school.'
                },
                'country': {
                    'type': 'string',
                    'description': 'Country of the school.'
                },
                'no_of_students': {
                    'type': 'integer',
                    'description': 'Number of students enrolled in the school.'
                }
            }
        }
    }
]

我们将用 ChatGPT 生成“斯坦福大学”的描述来测试该函数。

school_1_description = "Stanford University is a private research university located in Stanford, California, United States. It was founded in 1885 by Leland Stanford and his wife, Jane Stanford, in memory of their only child, Leland Stanford Jr. The university is ranked #5 in the world by QS World University Rankings. It has over 17,000 students, including about 7,600 undergraduates and 9,500 graduates23. "

创建学生与学校描述的列表,并传入 OpenAI 对话补全函数以生成响应。请确保您提供的是更新后的自定义函数。

description = [student_1_description, school_1_description]
for i in description:
    response = client.chat.completions.create(
        model = 'gpt-3.5-turbo',
        messages = [{'role': 'user', 'content': i}],
        functions = custom_functions,
        function_call = 'auto'
    )

    # Loading the response as a JSON object
    json_response = json.loads(response.choices[0].message.function_call.arguments)
    print(json_response)

GPT-3.5-Turbo 模型会根据不同的描述类型自动选择正确的函数。我们分别得到了关于学生与学校的完美 JSON 输出。

{'name': 'David Nguyen', 'major': 'computer science', 'school': 'Stanford University', 'grades': 3.8, 'club': 'Robotics Club'} 

{'name': 'Stanford University', 'ranking': 5, 'country': 'United States', 'no_of_students': 17000}

我们甚至可以在名称下看到,该响应是通过“extract_school_info”函数生成的。

函数调用的应用

在本节中,我们将构建一个稳定的文本摘要器,以特定方式概括学校与学生信息。

首先,我们将创建两个 Python 函数:extract_student_info 和 extract_school_info,它们从函数调用中接收参数并返回一段摘要字符串。

def extract_student_info(name, major, school, grades, club):
    
    """Get the student information"""

    return f"{name} is majoring in {major} at {school}. He has {grades} GPA and he is an active member of the university's {club}."

def extract_school_info(name, ranking, country, no_of_students):
    
    """Get the school information"""

    return f"{name} is located in the {country}. The university is ranked #{ranking} in the world with {no_of_students} students."
  1. 创建一个 Python 列表,包含第一位学生的描述、一个随机提示以及第一所学校的描述。加入随机提示是为了验证自动函数调用机制。
  2. 我们将使用 `descriptions` 列表中的每段文本来生成响应。
  3. 如果使用了函数调用,我们将获取函数名,并据此将响应中的相关参数应用到对应函数。否则,直接返回普通文本响应。
  4. 打印三个示例的输出。
descriptions = [
    student_1_description, 
    "Who was a Abraham Lincoln?",
    school_1_description
                ]

for i, sample in enumerate(descriptions):
    response = client.chat.completions.create(
        model = 'gpt-3.5-turbo',
        messages = [{'role': 'user', 'content': sample}],
        functions = custom_functions,
        function_call = 'auto'
    )
    
    response_message = response.choices[0].message
    
    if dict(response_message).get('function_call'):
        
        # Which function call was invoked
        function_called = response_message.function_call.name
        
        # Extracting the arguments
        function_args  = json.loads(response_message.function_call.arguments)
        
        # Function names
        available_functions = {
            "extract_school_info": extract_school_info,
            "extract_student_info": extract_student_info
        }
        
        fuction_to_call = available_functions[function_called]
        response_message = fuction_to_call(*list(function_args .values()))
        
    else:
        response_message = response_message.content
    
    print(f"\nSample#{i+1}\n")
    print(response_message)
  • Sample#1:GPT 模型选择了 “extract_student_info”,我们获得了关于该学生的简短摘要。
  • Sample#2:GPT 模型未选择任何函数,而是将提示视为普通问题,因此返回了亚伯拉罕·林肯的生平简介。
  • Sample#3:GPT 模型选择了 “extract_school_info”,我们获得了关于斯坦福大学的简短摘要。
Sample#1

David Nguyen is majoring in computer science at Stanford University. He has 3.8 GPA and he is an active member of the university's Robotics Club.

Sample#2

Abraham Lincoln was the 16th President of the United States. He served as president from March 1861 until his assassination in April 1865. Lincoln led the country through its greatest internal crisis, the American Civil War, and his Emancipation Proclamation declared slaves in Confederate territory to be free. He is known for his leadership, his commitment to preserving the Union, and his efforts to abolish slavery. Lincoln's presidency is widely regarded as one of the most transformative in American history.

Sample#3

Stanford University is located in the United States. The university is ranked #5 in the world with 17000 students.

结语

在本教程中,我们学习了 OpenAI 的函数调用功能;并了解了如何用它来生成一致的输出、创建多个函数以及构建可靠的文本摘要器。

如果您想进一步学习 OpenAI API,建议学习课程Working with OpenAI API,并使用OpenAI API in Python 速查表来创建您的首个 AI 项目。

常见问题

OpenAI 函数调用如何处理复杂的嵌套 JSON 输出?

OpenAI 函数调用允许您在函数架构中定义嵌套的 JSON 结构。通过在 parameters 属性中指定层级关系,您可以确保模型为复杂数据需求生成正确嵌套且结构化的 JSON 输出。

OpenAI 函数调用能与外部 API 或数据库一起使用吗?

可以。通过创建自定义函数,让其根据模型传入的参数执行 API 调用或数据库查询,OpenAI 函数调用可以与外部 API 或数据库集成。这样既能与外部系统动态交互,又能保持响应的一致性与结构化。

如果模型的函数调用与任何已定义的函数都不匹配会怎样?

如果模型的函数调用与已定义的函数或提供的架构不匹配,将不会触发函数调用,模型会将输入视为常规文本提示,并返回常规的文本响应。这样可以灵活应对多样化的输入类型。


Abid Ali Awan's photo
Author
Abid Ali Awan
LinkedIn
Twitter

作为一名持证的数据科学家,我热衷于利用前沿技术打造创新的机器学习应用。凭借在语音识别、数据分析与报告、MLOps、对话式人工智能以及自然语言处理方面的扎实背景,我不断打磨构建智能系统的能力,力求带来切实影响。除技术专长外,我也擅长沟通,能够将复杂概念提炼为清晰、简明的表述。因此,我成为数据科学领域备受关注的博主,与不断壮大的数据专业人士社区分享洞见与实践经验。目前,我专注于内容创作与编辑,借助大语言模型打造有力且吸引人的内容,帮助企业与个人更好地发挥数据价值。

主题
人工智能
大语言模型