Sortie structurée LangChain
La plupart du temps, ce dont vous avez besoin n'est pas un texte libre, mais des données structurées—comme un objet JSON.
LangChain Structured Output permet à l'Agent de renvoyer des résultats dans le format que vous spécifiez, ce qui facilite leur utilisation directe par les programmes.
Pourquoi avez-vous besoin d'une sortie structurée ?
Supposons que vous deviez extraire un nom, un âge et une profession à partir d'une description utilisateur :
| Méthode | Format de sortie | Traitement ultérieur |
|---|---|---|
| Réponse normale | Zhang San a 28 ans et est ingénieur. | Nécessite une regex ou un nouvel appel au modèle pour analyser |
| Sortie structurée | {name: "Zhang San", age: 28, job: "Engineer"} | Utilisé directement comme objet Python |
La sortie structurée économise l'étape qui consiste à « analyser les données à partir du texte », ce qui permet d'utiliser directement la sortie de l'IA par les programmes.
L'utilisation la plus simple — Passer un modèle Pydantic
Il suffit de passer le modèle Pydantic au paramètre response_format :
Exemple
load_dotenv()
from pydantic import BaseModel, Field
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
# Définir la structure de sortie attendue
class CourseInfo(BaseModel):
"""Exemple de résultat d'extraction de cours de tutoriel"""
course_name: str = Field(description=Nom du cours)
difficulty: str = Field(description=Difficulté : Débutant/Intermédiaire/Avancé)
estimated_hours: int = Field(description=Durée d'étude estimée (heures))
is_free: bool = Field(description=Indique s'il est gratuit)
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
response_format=CourseInfo, # Passer le modèle Pydantic
system_prompt=Vous êtes l'assistant de cours chez Example Tutorial. Extrayez les informations sur les cours à partir des descriptions des utilisateurs.,
)
# L'utilisateur saisit une description non structurée
result = agent.invoke({
"messages": [HumanMessage(
content=J'ai récemment étudié le Python3 Basics Tutorial, il est de niveau débutant,
Cela prend environ 20 heures d'étude, et c'est entièrement gratuit.
)]
})
# Obtenir le résultat structuré à partir de structured_response
if "structured_response" in result:
course = result["structured_response"]
print(fNom du cours : {course.course_name})
print(fDifficulté : {course.difficulty})
print(fDurée estimée : {course.estimated_hours} heures)
print(fGratuit : {'Yes' if course.is_free else 'No'})
print(fType d'objet : {type(course)})
Résultat de l'exécution :
Course name: Python3 基础教程 Difficulty: 入门 Duration: 20 小时 Free: 是 Object type: <class '__main__.CourseInfo'>
Le structured_response retourné est une instance de modèle Pydantic, et non un simple dictionnaire. Cela signifie que vous pouvez accéder à des attributs tels que .course_name, et que l'IDE peut fournir l'autocomplétion.
Sortie structurée coexistant avec les outils
response_format et tools peuvent être utilisés ensemble—l'Agent appelle tools en cas de besoin et produit enfin des données structurées :
Exemple
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
from langchain.tools import tool
@tool
def search_course(keyword: str) -> str:
"""Rechercher des informations sur les cours sur Example Tutorial"""
courses = {
"python": Tutoriel des bases de Python3 | Débutant | Gratuit | 30 chapitres | Environ 20 heures,
"java": Tutoriel des bases de Java | Débutant | Gratuit | 35 chapitres | Environ 25 heures,
Analyse de données: Analyse de données avec Python | Intermédiaire | Membre | 25 chapitres | Environ 30 heures,
}
return courses.get(keyword.lower(), fAucun cours trouvé pour '{keyword}')
class CourseRecommendation(BaseModel):
"""Résultat de recommandation de cours"""
course_name: str = Field(description=Nom du cours recommandé)
reason: str = Field(description=Raison de la recommandation)
difficulty: str = Field(description=Difficulté : Débutant/Intermédiaire/Avancé)
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
tools=[search_course],
response_format=CourseRecommendation,
system_prompt=Vous êtes le conseiller de cours chez Example Tutorial. Recherchez d'abord des cours, puis donnez des recommandations.,
)
result = agent.invoke({
"messages": [HumanMessage(content=Je veux apprendre Python. Que recommandez-vous ?)]
})
rec = result["structured_response"]
print(fCours recommandé : {rec.course_name})
print(fRaison de la recommandation : {rec.reason})
print(fDifficulté : {rec.difficulty})
# Voir le processus complet
print("\n"=== Processus d'exécution ===")
for msg in result["messages"]:
if msg.type == "tool":
print(f" Appel {msg.name} : {msg.content}")
Résultat de l'exécution :
Recommended course: Python3 基础教程 Reason: 该课程免费且适合Python初学者,学习时长约20小时 Difficulty: 入门 === 执行过程 === 调用 search_course: Python3 基础教程 | 入门 | 免费 | 30章 | 约20小时
Structures imbriquées complexes
Pydantic prend en charge des structures complexes telles que l'imbrication, les listes, les énumérations, etc. :
Exemple
from typing import Literal
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage
class Topic(BaseModel):
"""Sujet"""
name: str = Field(description=Nom du sujet)
order: int = Field(description=Ordre d'apprentissage, à partir de 1)
minutes: int = Field(description=Minutes d'étude recommandées)
class LearningPlan(BaseModel):
"""Plan d'étude"""
goal: str = Field(description=Aperçu de l'objectif d'étude)
level: Literal[Débutant, Intermédiaire, Avancé] = Field(description=Niveau de difficulté)
total_hours: float = Field(description=Durée totale (heures))
topics: Topic[Field] = description(Liste des sujets=Topic list)
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
agent = create_agent(
model=model,
response_format=LearningPlan,
system_prompt=Vous êtes le planificateur d'étude chez Example Tutorial.,
)
result = agent.invoke({
"messages": [HumanMessage(
content=Aidez-moi à créer un plan d'étude Python pour débutant, en gardant le temps total dans les 10 heures
)]
})
plan = result["structured_response"]
print(fObjectif : {plan.goal})
print(fDifficulté : {plan.level})
print(fDurée totale : {plan.total_hours} heures)
print(f"\n"Liste des sujets ({len(plan.topics)} éléments) :")
for topic in plan.topics:
print(f" {topic.order}. {topic.name} ({topic.minutes} minutes)")
Résultat de l'exécution :
目标: 掌握 Python 基础语法,能够独立编写简单的 Python 程序 Difficulty: 入门 总时长: 9.5 小时 知识点列表 (6 个): 1. 环境搭建与基础语法 (60分钟) 2. 数据类型与变量 (90分钟) 3. 条件判断与循环 (120分钟) 4. 函数与模块 (120分钟) 5. 列表与字典 (90分钟) 6. 综合练习 (90分钟)
Obtenir une sortie structurée à partir des messages
Si vous n'avez pas besoin de la capacité d'appel d'outils de l'Agent et que vous souhaitez simplement extraire des informations structurées à partir de texte, vous pouvez utiliser le modèle directement :
Exemple
from langchain.chat_models import init_chat_model
class SentimentResult(BaseModel):
"""Résultat de l'analyse de sentiment"""
sentiment: str = Field(description=Positif/Négatif/Neutre)
score: float = Field(description=Intensité du sentiment 0~1)
keywords: list[str] = Field(description=Mots-clés de sentiment)
model = init_chat_model("deepseek:deepseek-v4-flash", temperature=0)
# Utiliser with_structured_output() directement sur le modèle
# Pas besoin d'un Agent
structured_model = model.with_structured_output(SentimentResult)
textes = [
Le tutoriel d'exemple est vraiment très agréable à utiliser. Fortement recommandé !,
Ce tutoriel a trop peu de contenu. Cela ne vaut pas le coup.,
Le temps est agréable aujourd'hui.,
]
for text in texts:
result = structured_model.invoke(text)
print(fTexte : {text[:30]}...)
print(f" Sentiment: {result.sentiment}, Intensité: {result.score}, Mots-clés: {result.keywords}")
Résultat de l'exécution :
Text: Example 真的太好用了,强烈推荐!... Sentiment: 积极, 强度: 0.95, 关键词: ['好用', '推荐'] Text: 这个教程内容太少了,不太值。... Sentiment: 消极, 强度: 0.7, 关键词: ['内容太少', '不太值'] Text: 今天天气不错。... Sentiment: 中性, 强度: 0.1, 关键词: ['不错']
Autres extensionswith_structured_output() est une méthode du modèle et peut être utilisée sans Agent. Si votre scénario est « extraction d'informations » plutôt que « raisonnement en plusieurs étapes », utiliser with_structured_output() directement est plus simple et plus efficace.