Парсер вывода
Языковая модель LLM выводит содержимое в текстовом формате, но при разработке приложений искусственного интеллекта мы хотим получать форматированное содержимое, например, преобразовывать результаты в целевые объекты, массивы и т. д., чтобы облегчить обработку программой. Для этого предоставляется парсер вывода, который форматирует возвращаемое моделью содержимое.
Функция парсера вывода состоит в форматировании результатов, возвращаемых языковой моделью. Парсер вывода должен реализовать два необходимых метода:
- "get_format_instructions": возвращает строку с инструкциями, в каком формате должна возвращаться языковая модель.
- "parse": преобразует содержимое, возвращенное моделью, в целевой формат.
Теперь давайте посмотрим на встроенные парсеры вывода в LangChain.
Pydantic Parser
Ниже приведен основной парсер вывода PydanticOutputParser
, инкапсулированный в LangChain. Этот парсер основан на библиотеке pydantic для Python и используется для преобразования результатов работы модели в объекты Python.
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain_core.pydantic_v1 import BaseModel, Field, validator
from langchain_openai import OpenAI
model = OpenAI(model_name="gpt-3.5-turbo-instruct", temperature=0.0)
class Joke(BaseModel):
setup: str = Field(description="вопрос для шутки")
punchline: str = Field(description="ответ для шутки")
@validator("setup")
def question_ends_with_question_mark(cls, field):
if field[-1] != "?":
raise ValueError("Плохо сформулированный вопрос!")
return field
parser = PydanticOutputParser(pydantic_object=Joke)
prompt = PromptTemplate(
template="Ответьте на запрос пользователя.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
prompt_and_model = prompt | model
output = prompt_and_model.invoke({"query": "Расскажи шутку."})
parser.invoke(output)
Пример возвращаемого результата:
Joke(setup='Почему курица пересекла дорогу?', punchline='Чтобы попасть на другую сторону!')
Интерфейс LCEL
Интерфейс Runnable
Парсер вывода реализует интерфейс Runnable, который является одним из основных строительных блоков языка выражений LangChain (LCEL). Он поддерживает методы вызова, такие как invoke
, ainvoke
, stream
, astream
, batch
, abatch
, astream_log
и т. д.
Применение парсеров вывода в LCEL
Парсер вывода может принимать строку или BaseMessage
в качестве входных данных и возвращать структурированные данные любого типа. Мы можем создавать и вызывать цепочку парсеров, добавляя парсер в последовательность Runnable.
chain = prompt | model | parser
chain.invoke({"query": "Расскажи шутку."})
Возвращает
Joke(setup='Почему курица пересекла дорогу?', punchline='Чтобы попасть на другую сторону!')
Некоторые парсеры могут предоставлять поток частичных объектов разбора, например SimpleJsonOutputParser
, в то время как другие не поддерживают потоковую передачу. Окончательный вывод зависит от того, может ли парсер собирать частичные объекты разбора.
from langchain.output_parsers.json import SimpleJsonOutputParser
json_prompt = PromptTemplate.from_template(
"Вернуть JSON-объект с ключом `answer` на вопрос: {question}"
)
json_parser = SimpleJsonOutputParser()
json_chain = json_prompt | model | json_parser
list(json_chain.stream({"question": "Кто изобрел микроскоп?"}))
[{},
{'answer': ''},
{'answer': 'Муравей'},
{'answer': 'Антон'},
{'answer': 'Антоний'},
{'answer': 'Антоний ван'},
{'answer': 'Антоний ван Ле'},
{'answer': 'Антоний ван Лев'},
{'answer': 'Антоний ван Левен'},
{'answer': 'Антоний ван Левенг'},
{'answer': 'Антоний ван Левенгук'}]
В LCEL мы можем создавать сложные потоки обработки данных, объединяя различные парсеры, чтобы удовлетворить различные требования.