結構化輸出
概述
對於許多應用程式(例如聊天機器人),模型需要直接以自然語言回應使用者。但是,在某些情況下,我們需要模型以結構化格式輸出。例如,我們可能希望將模型輸出儲存在資料庫中,並確保輸出符合資料庫結構描述。這種需求促成了結構化輸出的概念,模型可以被指示以特定的輸出結構回應。
主要概念
(1) 結構描述定義: 輸出結構表示為結構描述,可以使用多種方式定義。(2) 返回結構化輸出: 模型被賦予這個結構描述,並被指示返回符合它的輸出。
建議用法
這個虛擬碼說明了使用結構化輸出時建議的工作流程。 LangChain 提供了一個方法 with_structured_output()
,它可以自動化將結構描述綁定到 模型 和解析輸出的過程。這個輔助函數適用於所有支援結構化輸出的模型提供者。
# Define schema
schema = {"foo": "bar"}
# Bind schema to model
model_with_structure = model.with_structured_output(schema)
# Invoke the model to produce structured output that matches the schema
structured_output = model_with_structure.invoke(user_input)
結構描述定義
核心概念是模型回應的輸出結構需要以某種方式表示。雖然您可以使用的物件類型取決於您使用的模型,但在 Python 中,通常允許或建議用於結構化輸出的常見物件類型。
結構化輸出最簡單和最常見的格式是類似 JSON 的結構,在 Python 中可以表示為字典 (dict) 或列表 (list)。當工具需要原始、靈活且最小開銷的結構化資料時,通常直接使用 JSON 物件(或 Python 中的 dict)。
{
"answer": "The answer to the user's question",
"followup_question": "A followup question the user could ask"
}
作為第二個範例,Pydantic 特別適用於定義結構化輸出結構描述,因為它提供了類型提示和驗證。以下是一個 Pydantic 結構描述的範例
from pydantic import BaseModel, Field
class ResponseFormatter(BaseModel):
"""Always use this tool to structure your response to the user."""
answer: str = Field(description="The answer to the user's question")
followup_question: str = Field(description="A followup question the user could ask")
返回結構化輸出
定義了結構描述後,我們需要一種方法來指示模型使用它。雖然一種方法是在提示中包含這個結構描述,並禮貌地要求模型使用它,但不建議這樣做。有幾種更強大的方法可以利用模型提供者 API 中的原生功能。
使用工具呼叫
許多 模型提供者支援 工具呼叫,這個概念在我們的 工具呼叫指南 中有更詳細的討論。簡而言之,工具呼叫涉及將工具綁定到模型,並且在適當的時候,模型可以決定呼叫這個工具,並確保其回應符合工具的結構描述。記住這一點,核心概念很簡單:只需將我們的結構描述作為工具綁定到模型即可! 以下是使用上面定義的 ResponseFormatter
結構描述的範例
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o", temperature=0)
# Bind responseformatter schema as a tool to the model
model_with_tools = model.bind_tools([ResponseFormatter])
# Invoke the model
ai_msg = model_with_tools.invoke("What is the powerhouse of the cell?")
工具呼叫的參數已經被提取為字典。這個字典可以選擇性地解析為 Pydantic 物件,以匹配我們原始的 ResponseFormatter
結構描述。
# Get the tool call arguments
ai_msg.tool_calls[0]["args"]
{'answer': "The powerhouse of the cell is the mitochondrion. Mitochondria are organelles that generate most of the cell's supply of adenosine triphosphate (ATP), which is used as a source of chemical energy.",
'followup_question': 'What is the function of ATP in the cell?'}
# Parse the dictionary into a pydantic object
pydantic_object = ResponseFormatter.model_validate(ai_msg.tool_calls[0]["args"])
JSON 模式
除了工具呼叫之外,一些模型提供者還支援一個稱為 JSON 模式
的功能。這支援 JSON 結構描述定義作為輸入,並強制模型產生符合規範的 JSON 輸出。您可以在 這裡 找到支援 JSON 模式的模型提供者表格。以下是如何將 JSON 模式與 OpenAI 一起使用的範例
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4o").with_structured_output(method="json_mode")
ai_msg = model.invoke("Return a JSON object with key 'random_ints' and a value of 10 random ints in [0-99]")
ai_msg
{'random_ints': [45, 67, 12, 34, 89, 23, 78, 56, 90, 11]}
結構化輸出方法
使用上述方法產生結構化輸出時,存在一些挑戰
(1) 當使用工具呼叫時,需要將工具呼叫參數從字典解析回原始結構描述。
(2) 此外,當我們想要強制結構化輸出時,需要指示模型始終使用該工具,這是一個提供者特定的設定。
(3) 當使用 JSON 模式時,需要將輸出解析為 JSON 物件。
考慮到這些挑戰,LangChain 提供了一個輔助函數 (with_structured_output()
) 來簡化流程。
這既將結構描述作為工具綁定到模型,又將輸出解析為指定的輸出結構描述。
# Bind the schema to the model
model_with_structure = model.with_structured_output(ResponseFormatter)
# Invoke the model
structured_output = model_with_structure.invoke("What is the powerhouse of the cell?")
# Get back the pydantic object
structured_output
ResponseFormatter(answer="The powerhouse of the cell is the mitochondrion. Mitochondria are organelles that generate most of the cell's supply of adenosine triphosphate (ATP), which is used as a source of chemical energy.", followup_question='What is the function of ATP in the cell?')
有關使用方式的更多詳細資訊,請參閱我們的 操作指南。