Retour à l'accueil

Comment sauvegarder le contenu de raisonnement dans LangChain pour les modèles CoT

L'article explique pourquoi LangChain ignore le contenu de raisonnement dans les modèles CoT et propose un patch fonctionnel pour sauvegarder ce bloc dans additional_kwargs. Convient aux développeurs utilisant des fournisseurs comme polza.ai ou StepFun via une API compatible OpenAI.

Perte de contenu de raisonnement dans LangChain ? Voici comment la corriger
Advertisement 728x90

## Sauvegarder le Contenu de Raisonnement dans LangChain : Correctif pour les Modèles CoT

Quand on travaille avec des modèles CoT via LangChain, les développeurs se heurtent à la perte du contenu de raisonnement — le bloc clé de raisonnement généré par le modèle avant la réponse finale. Ce n'est pas un bug mais la conséquence d'une décision architecturale : des classes comme ChatOpenAI respectent strictement l'API officielle OpenAI, ignorant les champs non standards comme reasoning, reasoning_content ou reasoning_details. Le résultat, ce sont des temps de réponse plus lents et une UX dégradée, car les utilisateurs ne voient pas les étapes de réflexion intermédiaires de l'IA. Voici comment y remédier au niveau du code sans attendre une mise à jour officielle.

Pourquoi LangChain Ignore le Contenu de Raisonnement

LangChain se positionne comme un framework universel compatible avec une large gamme de fournisseurs de LLM. Pour éviter la fragmentation, ses classes principales (comme ChatOpenAI) implémentent uniquement la spécification officielle de l'API Chat Completion OpenAI. Des champs comme reasoning_content, reasoning et assimilés sont des extensions introduites par DeepSeek, xAI, vLLM et d'autres. Chaque fournisseur utilise sa propre nomenclature et son propre format, ce qui crée le chaos :

  • DeepSeek → reasoning_content
  • vLLM → passé de reasoning_content à reasoning
  • xAI / OpenRouter → peut utiliser reasoning_details

Pour supporter toutes les variantes dans ChatOpenAI, il faudrait :

Google AdInline article slot
  • Surveiller en permanence les changements d'API des fournisseurs tiers.
  • Maintenir une liste croissante de mappings de champs.
  • Transformer ChatOpenAI en adaptateur universel — ce qui va à l'encontre de son objectif.

C'est pourquoi les développeurs LangChain recommandent d'utiliser des classes spécialisées comme ChatDeepSeek. Mais la plupart des fournisseurs (y compris polza.ai, StepFun et d'autres) proposent encore des API au format OpenAI — et c'est là que le problème persiste.

Comment Appliquer le Correctif dans base.py

La solution consiste à modifier deux fonctions dans le code source de LangChain : _convert_dict_to_message et _convert_delta_to_message_chunk. Celles-ci gèrent la conversion des réponses brutes des LLM en objets Message utilisés dans le framework. Il faut ajouter l'extraction du champ reasoning et le sauvegarder dans additional_kwargs.

Voici le correctif minimal :

Google AdInline article slot
def _convert_dict_to_message(_dict):
    ...
    content = _dict.get("content", "") or ""
    reasoning = _dict.get("reasoning", "") or ""  # added
    additional_kwargs: dict = {}
    if reasoning:  # added
        additional_kwargs['reasoning_content'] = reasoning  # added
    if function_call := _dict.get("function_call"):
        additional_kwargs["function_call"] = dict(function_call)
    tool_calls = []
    ...

De même pour le mode streaming :

def _convert_delta_to_message_chunk(_dict):
    ...
    id_ = _dict.get("id")
    role = cast(str, _dict.get("role"))
    content = cast(str, _dict.get("content") or "")
    reasoning = cast(str, _dict.get("reasoning", "") or "")  # added
    additional_kwargs: dict = {}
    if reasoning:  # added
        additional_kwargs['reasoning_content'] = reasoning  # added
    ...

Ce correctif :

  • Ne casse pas l'architecture existante.
  • Préserve la compatibilité avec l'API officielle.
  • Ajoute le support de reasoning_content pour tout fournisseur qui renvoie un champ reasoning.

Exemple d'Utilisation avec Sortie Streaming

Après application du correctif, le contenu de raisonnement devient disponible dans additional_kwargs pour chaque chunk. Voici comment configurer la sortie :

Google AdInline article slot
from langchain_openai import ChatOpenAI

model = ChatOpenAI(
    model="stepfun/step-3.5-flash",
    openai_api_base="https://api.polza.ai/v1",
    openai_api_key="your_api_key",
)

for chunk in model.stream('Hello!'):
    if "reasoning_content" in chunk.additional_kwargs:
        print(chunk.additional_kwargs['reasoning_content'], end="", flush=True)
    else:
        print(chunk.content, end="", flush=True)

Désormais, les utilisateurs peuvent voir le processus de raisonnement du modèle en temps réel — c'est particulièrement précieux dans les applications CoT, où les étapes intermédiaires comme l'analyse de données, la comparaison d'hypothèses et les vérifications logiques sont cruciales.

Approches Alternatives et Limites

Bien que le correctif soit efficace, il présente des limites :

  • Modification locale : Les changements n'affectent que votre copie de LangChain. Ils seront perdus lors des mises à jour du package.
  • Incompatibilité de noms de champs : Si un fournisseur utilise reasoning_details au lieu de reasoning, il faudra adapter le code.
  • Absence de standardisation : Sans accord unifié entre fournisseurs, chaque cas nécessite un ajustement manuel.

Alternatives propres :

  • Custom MessageConverter — créez votre propre classe héritant de BaseMessageConverter et surchargez la logique d'analyse.
  • Couche intermédiaire — interceptez les réponses HTTP du fournisseur avant qu'elles n'atteignent LangChain et normalisez les champs.
  • LangChain Expression Language (LCEL) — enveloppez l'appel au modèle dans un RunnableLambda qui extrait le raisonnement avant de le passer à la chaîne.

Cependant, ces méthodes sont plus complexes et exigent une bonne connaissance des entrailles du framework. Pour un MVP ou un correctif rapide, modifier base.py est la solution optimale.

Points Clés à Retenir

  • Le contenu de raisonnement est perdu non pas à cause d'un bug, mais parce que LangChain suit strictement l'API OpenAI.
  • Le correctif ajoute le support du champ reasoning dans additional_kwargs sans casser la compatibilité descendante.
  • Il fonctionne pour les appels normaux et streaming.
  • Il nécessite une réapplication manuelle après chaque mise à jour de LangChain.
  • Il améliore l'UX des applications CoT en rendant le processus de réflexion du modèle transparent pour les utilisateurs.

— Editorial Team

Advertisement 728x90

Lire ensuite