Estrategias de salida de LangChain
LangChain ofrece tres estrategias de salida estructurada. Comprender sus diferencias y cómo funcionan te ayudará a tomar la mejor decisión en diferentes escenarios.
Resumen de las tres estrategias
| Estrategia | Principio | Compatibilidad de modelos | Velocidad de respuesta |
|---|---|---|---|
| ToolStrategy | Disfraza el Schema como una herramienta; el modelo "llama" a esta herramienta para generar datos estructurados. | Todos los modelos compatibles con function calling | Más lenta (una llamada a herramienta adicional) |
| ProviderStrategy | Usa la capacidad de salida estructurada nativa del modelo (como response_format de OpenAI) | Algunos modelos (GPT-4o+, Claude 3+, etc.) | Más rápida (salida directa) |
| AutoStrategy | Detecta automáticamente las capacidades del modelo y elige la mejor estrategia | Adaptación automática | Selección automática de la óptima |
ToolStrategy: modo de llamada a herramientas
ToolStrategy es el método más compatible. Convierte tu Schema en una "herramienta falsa" y el modelo genera datos estructurados llamando a esta herramienta.
Ejemplo
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):
"""Informe meteorológico"""
city: str = Field(description="Nombre de la ciudad")
temperature: float = Field(description="Temperatura (grados Celsius)")
condition: str = Field(description="Condición meteorológica")
humidity: int = Field(description="Porcentaje de humedad")
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
# Especificar explícitamente el uso de ToolStrategy
agent = create_agent(
model=model,
response_format=ToolStrategy(schema=WeatherReport),
system_prompt="Eres un asistente meteorológico. Genera un informe meteorológico estructurado según la descripción del usuario.",
)
result = agent.invoke({
"messages": [HumanMessage(content="Hoy hace sol en Hangzhou, temperatura 25 grados, humedad 60%")]
})
report = result["structured_response"]
print(f"Ciudad: {report.city}")
print(f"Temperatura: {report.temperature}°C")
print(f"Condición: {report.condition}")
print(f"Humedad: {report.humidity}%")
# Ver el proceso de ejecución: se puede observar que hay un mensaje adicional de llamada a herramienta
print(f"\nTotal de mensajes: {len(result['messages'])}")
for msg in result["messages"]:
print(f" [{msg.type}]", end="")
if hasattr(msg, 'tool_calls') and msg.tool_calls:
print(f" Llamada: {[tc['name'] for tc in msg.tool_calls]}")
elif msg.type == "tool":
print(f" {msg.content[:60]}")
else:
print(f" {str(msg.content)[:60]}")
Resultado de la ejecución:
Ciudad: 杭州 Temperatura: 25.0°C Condición: 晴天 Humedad: 60% Total de mensajes: 4 [human] 杭州今天晴天,温度25度,湿度60% [ai] 调用: ['WeatherReport'] [tool] Returning structured response: ... [ai]
Se puede ver que ToolStrategy añade un paso de llamada a herramienta (llama a la "herramienta falsa" llamada WeatherReport) antes de producir la salida estructurada.
handle_errors: reintento de errores
ToolStrategy admite reintentos automáticos cuando la salida estructurada falla:
Ejemplo
# handle_errors=True: cuando el formato de salida es incorrecto, se devuelve el mensaje de error al modelo para reintentar
strategy_with_retry = ToolStrategy(
schema=WeatherReport,
handle_errors=True, # Valor predeterminado: False
)
# handle_errors también puede ser una plantilla personalizada de mensaje de error
strategy_custom_error = ToolStrategy(
schema=WeatherReport,
handle_errors="Formato incorrecto. Corrígelo según {error} y vuelve a generar la salida",
)
ProviderStrategy: salida estructurada nativa
ProviderStrategy utiliza las capacidades nativas del proveedor del modelo (como el parámetro response_format de OpenAI). No todos los modelos lo admiten.
Ejemplo
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):
"""Información del curso"""
name: str = Field(description="Nombre del curso")
level: str = Field(description="Dificultad: principiante/intermedio/avanzado")
price: str = Field(description="Información de precio")
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
# Especificar explícitamente ProviderStrategy
agent = create_agent(
model=model,
response_format=ProviderStrategy(schema=CourseInfo),
system_prompt="Eres el asistente de cursos de Ejemplo.",
)
result = agent.invoke({
"messages": [HumanMessage(content="El tutorial básico de Python3 es un curso gratuito de nivel principiante")]
})
course = result["structured_response"]
print(f"Curso: {course.name}")
print(f"Dificultad: {course.level}")
print(f"Precio: {course.price}")
print(f"\nNúmero de mensajes: {len(result['messages'])}") # Menos que ToolStrategy
Resultado de la ejecución:
Curso: Python3 基础教程 Dificultad: 入门 Precio: 免费 Número de mensajes: 2
En comparación con ToolStrategy, ProviderStrategy genera menos mensajes (2 frente a 4) porque no requiere pasos adicionales de llamada a herramientas.
ProviderStrategy es compatible principalmente con GPT-4o de OpenAI y superiores, y Claude 3 y superiores. Si el modelo no lo admite, LangChain degrada automáticamente a ToolStrategy. Puedes verificar la compatibilidad del modelo con model.profile.
AutoStrategy: selección automática
Esta es la forma más recomendada. Pasa un modelo Pydantic (en lugar de un objeto de estrategia) y LangChain elegirá automáticamente la mejor estrategia:
Ejemplo
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
class Analysis(BaseModel):
"""Resultado del análisis"""
summary: str = Field(description="Resumen en una frase")
score: int = Field(description="Puntuación del 1 al 10")
pros: list[str] = Field(description="Lista de ventajas")
cons: list[str] = Field(description="Lista de desventajas")
# Pasar directamente el modelo Pydantic: LangChain elige la estrategia automáticamente
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
response_format=Analysis, # Pasar el modelo directamente y elegir la estrategia automáticamente
system_prompt="Eres un experto en evaluación de cursos. Evalúa el curso descrito por el usuario.",
)
result = agent.invoke({
"messages": [HumanMessage(
content="El curso de Python de Ejemplo: contenido completo y sistemático,"
"con abundantes ejemplos y totalmente gratuito. Sin embargo, tiene pocos videotutoriales,"
"y la cobertura de contenido avanzado es insuficiente."
)]
})
analysis = result["structured_response"]
print(f"Resumen: {analysis.summary}")
print(f"Puntuación: {analysis.score}/10")
print(f"Ventajas: {', '.join(analysis.pros)}")
print(f"Desventajas: {', '.join(analysis.cons)}")
Resultado de la ejecución:
Resumen: Ejemplo Python 课程内容系统且免费,但缺乏视频教学和高级内容 Puntuación: 7/10 Ventajas: 内容系统全面, 实例丰富, 完全免费 Desventajas: 视频教程较少, 高级内容覆盖不够
Guía para elegir entre las tres estrategias
| Escenario | Estrategia recomendada | Razón |
|---|---|---|
| No estás seguro de si el modelo admite salida nativa | AutoStrategy (pasar Pydantic directamente) | Elige automáticamente la estrategia óptima |
| Necesitas compatibilidad con varios modelos | ToolStrategy | Funciona con todos los modelos compatibles con function calling |
| Buscas el máximo rendimiento | ProviderStrategy | Omite el paso de llamada a herramientas, es más rápido |
| Necesitas reintentos ante errores | ToolStrategy(handle_errors=True) | Solo ToolStrategy admite handle_errors |
Otras extensionesEn la mayoría de los casos, basta con pasar directamente un modelo Pydantic (es decir, usar AutoStrategy). Solo necesitas especificar explícitamente ToolStrategy o ProviderStrategy cuando necesites reintentos ante errores o controlar claramente el comportamiento de la estrategia.