控制大型语言模型(LLM)输出格式及解析

42 min read

控制大型语言模型(LLM)输出格式及解析其结果的问题涉及到多个方面。首先,考虑到LLM的输出具有不确定性,我们需要一种方法来标准化输出,使其更易于程序解析。其次,我们还需要考虑如何有效地利用现有的API功能来实现这一目标。

方法概述

  1. 使用函数调用(Function Calling): 这是OpenAI推出的一项功能,允许LLM在输出最终结果之前,决定是否需要调用特定函数。此方法的优势在于可以控制输出格式为标准JSON,从而方便程序解析。

  2. 使用JSON模式: OpenAI最新的模型(如gpt-4和gpt-3.5-turbo)提供了JSON模式。通过设置API调用时的响应格式为JSON对象,可以使LLM的输出被限制为有效的JSON字符串。

  3. 可重复输出(Reproducible outputs): 通过设定种子参数(seed parameter),可以在一定程度上获得确定性输出。这对于需要可预测和可重复分析的场景非常有用。

实施细节

函数调用

  • 定义需要LLM输出的内容作为一个函数,但实际上不执行此函数。
  • 使用API时,将此函数作为参数传入,强制LLM调用此函数,从而获得结构化的JSON格式输出。

JSON模式

  • 在系统消息中明确指示模型产生JSON输出。
  • 设置响应格式为JSON对象,确保输出是有效的JSON字符串。

可重复输出

  • 通过设置种子参数确保输出的一致性。
  • 使用相同的输入参数(如prompt、temperature)确保输出稳定。

注意事项

  • 函数调用功能需要API支持。
  • JSON模式并不保证输出符合特定的模式,只保证它是有效的JSON。
  • 可重复输出可能因模型配置变化而有所不同。

示例

函数调用

import json

import openai

# 设置API密钥,推荐使用环境变量来管理密钥
openai.api_key = 'sk-'

# 使用新的客户端实例来创建文本生成请求
client = openai.OpenAI(api_key=openai.api_key)

functions = [{
  "name": "getUserInfo",
  "description": "Get user information",
  "parameters": {
    "type": "object",
    "properties": {
      "name": {"type": "string", "description": "User's fullname"},
      "age": {"type": "number", "description": "User's age"},
      "city": {"type": "string", "description": "User's city"}
    },
    "required": ["name", "age", "city"]
  }
}]


# 创建聊天完成请求
response = client.chat.completions.create(
  model="gpt-3.5-turbo",
  messages=[{"role": "user", "content": "My name is John, I'm 30 years old, and I live in New York."}],
  functions=functions,
  function_call={"name": "getUserInfo"} # 强制调用getUserInfo函数
)

# 提取函数调用的参数
function_call_arguments = response.choices[0].message.function_call.arguments

# 解析JSON
user_info = json.loads(function_call_arguments)

# 输出解析后的JSON对象
print(user_info)

JSON模式

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo-1106",
    "response_format": { "type": "json_object" },
    "messages": [
      {"role": "system", "content": "You are a helpful assistant designed to output JSON."},
      {"role": "user", "content": "Who won the world series in 2020?"}
    ]
  }'

可重复输出

import openai

# 设置API密钥,推荐使用环境变量来管理密钥
openai.api_key = 'sk-'

# 使用新的客户端实例来创建文本生成请求
client = openai.OpenAI(api_key=openai.api_key)

response = client.completions.create(
  model="text-davinci-003",  # 指定使用的模型
  prompt="请解释什么是机器学习?",
  max_tokens=50,
  temperature=0.7,
  n=1,
  stop=None,
  seed=123456  # 设置种子值
)

# 输出生成的文本
print(response.choices[0].text)

通过利用函数调用、JSON模式和可重复输出,可以有效地控制和解析大型语言模型的输出。这些方法不仅提高了输出的一致性,还为自动化处理提供了便利。不过,需要注意的是,这些方法可能需要特定API的支持,并且在实施时要注意细节以确保输出的准确性。