Стратегии вывода LangChain
LangChain предоставляет три стратегии структурированного вывода. Понимание их различий и принципов работы поможет вам сделать лучший выбор в разных сценариях.
Обзор трёх стратегий
| Стратегия | Принцип | Поддержка моделей | Скорость отклика |
|---|---|---|---|
| ToolStrategy | Маскирует схему под инструмент; модель «вызывает» этот инструмент, чтобы вывести структурированные данные | Все модели, поддерживающие вызов функций | Медленнее (один дополнительный вызов инструмента) |
| ProviderStrategy | Использует нативную возможность структурированного вывода модели (например, response_format в OpenAI) | Некоторые модели (GPT-4o+, Claude 3+ и т. д.) | Быстрее (прямой вывод) |
| AutoStrategy | Автоматически определяет возможности модели и выбирает лучшую стратегию | Автоматическая адаптация | Автоматически выбирает оптимальный |
ToolStrategy — Режим вызова инструментов
ToolStrategy — самый совместимый подход. Он преобразует вашу Schema в «фальшивый инструмент», и модель выводит структурированные данные, вызывая этот инструмент.
Пример
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
class WeatherReport(BaseModel):
"""Отчёт о погоде"""
city: str = Field(description="Название города")
temperature: float = Field(description="Температура (по Цельсию)")
condition: str = Field(description="Погодные условия")
humidity: int = Field(description="Процент влажности")
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
# Явно указать использование ToolStrategy
agent = create_agent(
model=model,
response_format=ToolStrategy(schema=WeatherReport),
system_prompt="Вы — погодный ассистент. Создайте структурированный отчёт о погоде на основе описания пользователя.",
)
result = agent.invoke({
"messages": [HumanMessage(content="В Ханчжоу сегодня солнечно, 25 градусов, влажность 60%")]
})
report = result["structured_response"]
print(f"Город: {report.city}")
print(f"Температура: {report.temperature}°C")
print(f"Погодные условия: {report.condition}")
print(f"Влажность: {report.humidity}%")
# Просмотр процесса выполнения — вы можете увидеть дополнительное сообщение о вызове инструмента
print(f"\n"Всего сообщений: {len(result['messages'])}")
for msg in result["messages"]:
print(f" [{msg.type}]", end="")
if hasattr(msg, 'tool_calls') and msg.tool_calls:
print(f" Вызовы: {[tc['name'] for tc in msg.tool_calls]}")
elif msg.type == "tool":
print(f" {msg.content[:60]}")
else:
print(f" {str(msg.content)[:60]}")
Вывод:
City: 杭州 Temperature: 25.0°C Condition: 晴天 Humidity: 60% Total messages: 4 [human] 杭州今天晴天,温度25度,湿度60% [ai] 调用: ['WeatherReport'] [tool] Returning structured response: ... [ai]
Вы можете видеть, что ToolStrategy добавляет дополнительный шаг вызова инструмента (вызов "поддельного инструмента" с именем WeatherReport) перед формированием структурированного вывода.
handle_errors — Повторная попытка при ошибке
ToolStrategy поддерживает автоматический повтор при сбое структурированного вывода:
Пример
# handle_errors=True: если формат вывода неверен, передайте сообщение об ошибке обратно модели для повторной попытки
strategy_with_retry = ToolStrategy(
schema=WeatherReport,
handle_errors=True, # По умолчанию — False
)
# handle_errors также может быть пользовательским шаблоном сообщения об ошибке
strategy_custom_error = ToolStrategy(
schema=WeatherReport,
handle_errors="Формат неверный. Пожалуйста, исправьте его в соответствии с {error} и выведите снова.",
)
ProviderStrategy — нативный структурированный вывод
ProviderStrategy использует нативные возможности провайдера модели (например, параметр response_format у OpenAI). Не все модели поддерживают это.
Пример
from langchain.agents import create_agent
from langchain.agents.structured_output import ProviderStrategy
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
class CourseInfo(BaseModel):
"""Информация о курсе"""
name: str = Field(description="Название курса")
level: str = Field(description="Сложность: начальный/средний/продвинутый")
price: str = Field(description="Информация о цене")
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
# Явно указать ProviderStrategy
agent = create_agent(
model=model,
response_format=ProviderStrategy(schema=CourseInfo),
system_prompt="Вы — помощник по курсам для EXAMPLE.",
)
result = agent.invoke({
"messages": [HumanMessage(content="Учебник по основам Python 3 — бесплатный курс для начинающих.")]
})
course = result["structured_response"]
print(f"Курс: {course.name}")
print(f"Сложность: {course.level}")
print(f"Цена: {course.price}")
print(f"\n"Количество сообщений: {len(result['messages'])}") # Меньше, чем ToolStrategy
Вывод:
Course: Python3 基础教程 Difficulty: 入门 Price: 免费 Message count: 2
По сравнению с ToolStrategy, ProviderStrategy имеет меньше сообщений (2 против 4), потому что не требует дополнительного шага вызова инструмента.
В настоящее время ProviderStrategy в основном поддерживается OpenAI GPT-4o и выше, а также Claude 3 и выше. Если модель не поддерживает её, LangChain автоматически переключится на ToolStrategy. Вы можете проверить, поддерживает ли модель её, с помощью model.profile.
AutoStrategy — Автоматический выбор
Это наиболее рекомендуемый подход. Передайте модель Pydantic (вместо объекта стратегии), и LangChain автоматически выберет лучшую стратегию:
Пример
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
class Analysis(BaseModel):
"""Результат анализа"""
summary: str = Field(description="Резюме в одном предложении")
score: int = Field(description="Оценка 1~10")
pros: list[str] = Field(description="Список плюсов")
cons: list[str] = Field(description="Список минусов")
# Передайте напрямую модель Pydantic — LangChain автоматически выбирает стратегию
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
response_format=Analysis, # Передайте модель напрямую; стратегия выбирается автоматически
system_prompt="Вы — эксперт по оценке курсов. Оцените курс, описанный пользователем.",
)
result = agent.invoke({
"messages": [HumanMessage(
content="Курс Python от EXAMPLE: всеобъемлющее и систематическое содержание,"
"богат примерами и полностью бесплатен. Однако видеоуроки ограничены,"
"а охват продвинутого материала недостаточен."
)]
})
analysis = result["structured_response"]
print(f"Сводка: {analysis.summary}")
print(f"Оценка: {analysis.score}/10")
print(f"Плюсы: {', '.join(analysis.pros)}")
print(f"Минусы: {', '.join(analysis.cons)}")
Вывод:
Summary: Example Python 课程内容系统且免费,但缺乏视频教学和高级内容 Rating: 7/10 Pros: 内容系统全面, 实例丰富, 完全免费 Cons: 视频教程较少, 高级内容覆盖不够
Руководство по выбору среди трех стратегий
| Сценарий | Рекомендуемая стратегия | Причина |
|---|---|---|
| Не уверены, поддерживает ли модель нативный вывод | AutoStrategy (напрямую передать Pydantic) | Автоматически выбирает лучшую стратегию |
| Требуется совместимость с различными моделями | ToolStrategy | Работает со всеми моделями, поддерживающими вызов функций |
| Стремление к максимальной производительности | ProviderStrategy | Пропускает этап вызова инструментов, быстрее |
| Требуется повторная попытка при ошибке | ToolStrategy(handle_errors=True) | Только ToolStrategy поддерживает handle_errors |
Другие расширенияВ большинстве случаев достаточно напрямую передать модель Pydantic (т. е. использовать AutoStrategy). Только когда требуется повторная попытка при ошибке или явный контроль над поведением стратегии, нужно явно указать ToolStrategy или ProviderStrategy.