如何解析 JSON 輸出
先決條件
本指南假設您熟悉以下概念
雖然某些模型供應商支援內建方式來返回結構化輸出,但並非所有都支援。 我們可以使用輸出解析器來幫助使用者透過提示指定任意 JSON 模式、查詢模型以獲得符合該模式的輸出,並最終將該模式解析為 JSON。
注意
請記住,大型語言模型是洩漏的抽象概念! 您必須使用具有足夠容量的 LLM 來產生格式良好的 JSON。
JsonOutputParser
是內建選項,用於提示然後解析 JSON 輸出。 雖然它在功能上與 PydanticOutputParser
類似,但它也支援串流傳回部分 JSON 物件。
以下範例說明如何將其與 Pydantic 一起使用,以方便地宣告預期的模式
%pip install -qU langchain langchain-openai
import os
from getpass import getpass
if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = getpass()
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
model = ChatOpenAI(temperature=0)
# Define your desired data structure.
class Joke(BaseModel):
setup: str = Field(description="question to set up a joke")
punchline: str = Field(description="answer to resolve the joke")
# And a query intented to prompt a language model to populate the data structure.
joke_query = "Tell me a joke."
# Set up a parser + inject instructions into the prompt template.
parser = JsonOutputParser(pydantic_object=Joke)
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
chain = prompt | model | parser
chain.invoke({"query": joke_query})
{'setup': "Why couldn't the bicycle stand up by itself?",
'punchline': 'Because it was two tired!'}
請注意,我們正在將解析器的 format_instructions
直接傳遞到提示中。 您可以也應該嘗試在提示的其他部分新增您自己的格式提示,以增強或取代預設指示
parser.get_format_instructions()
'The output should be formatted as a JSON instance that conforms to the JSON schema below.\n\nAs an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}\nthe object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.\n\nHere is the output schema:\n\`\`\`\n{"properties": {"setup": {"title": "Setup", "description": "question to set up a joke", "type": "string"}, "punchline": {"title": "Punchline", "description": "answer to resolve the joke", "type": "string"}}, "required": ["setup", "punchline"]}\n\`\`\`'
串流
如上所述,JsonOutputParser
和 PydanticOutputParser
之間的主要區別在於 JsonOutputParser
輸出解析器支援串流部分區塊。 以下是其外觀
for s in chain.stream({"query": joke_query}):
print(s)
{}
{'setup': ''}
{'setup': 'Why'}
{'setup': 'Why couldn'}
{'setup': "Why couldn't"}
{'setup': "Why couldn't the"}
{'setup': "Why couldn't the bicycle"}
{'setup': "Why couldn't the bicycle stand"}
{'setup': "Why couldn't the bicycle stand up"}
{'setup': "Why couldn't the bicycle stand up by"}
{'setup': "Why couldn't the bicycle stand up by itself"}
{'setup': "Why couldn't the bicycle stand up by itself?"}
{'setup': "Why couldn't the bicycle stand up by itself?", 'punchline': ''}
{'setup': "Why couldn't the bicycle stand up by itself?", 'punchline': 'Because'}
{'setup': "Why couldn't the bicycle stand up by itself?", 'punchline': 'Because it'}
{'setup': "Why couldn't the bicycle stand up by itself?", 'punchline': 'Because it was'}
{'setup': "Why couldn't the bicycle stand up by itself?", 'punchline': 'Because it was two'}
{'setup': "Why couldn't the bicycle stand up by itself?", 'punchline': 'Because it was two tired'}
{'setup': "Why couldn't the bicycle stand up by itself?", 'punchline': 'Because it was two tired!'}
不使用 Pydantic
您也可以在不使用 Pydantic 的情況下使用 JsonOutputParser
。 這將提示模型返回 JSON,但不提供有關模式應為何的具體資訊。
joke_query = "Tell me a joke."
parser = JsonOutputParser()
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
chain = prompt | model | parser
chain.invoke({"query": joke_query})
{'response': "Sure! Here's a joke for you: Why couldn't the bicycle stand up by itself? Because it was two tired!"}
後續步驟
您現在已學習一種提示模型返回結構化 JSON 的方法。 接下來,查看關於取得結構化輸出的更廣泛指南,以了解其他技術。