Agent Frameworks

Connecter les LLM aux mainframes avec LangChain

Le logiciel d'entreprise est rarement un projet vierge. La plupart des grandes organisations font toujours tourner leur logique métier critique sur des mainframes, communiquant via des jobs par lots et des services web SOAP. Alors que les grands modèles de langage (LLM) deviennent l'interface de choix pour les applications modernes, le défi ne consiste plus seulement à construire des chatbots, mais à combler le fossé entre l'IA probabiliste et les systèmes legacy déterministes. LangChain fournit un cadre puissant pour abstraire cette complexité, permettant aux développeurs de construire des agents capables de raisonner sur des structures de données legacy sans nécessiter une modernisation complète de l'infrastructure.

Comprendre le défi d'intégration

L'intégration d'un LLM avec un système legacy pose deux problèmes distincts : le formatage des données et la gestion de l'état. Les systèmes mainframe, tels que ceux exécutant CICS ou Db2, s'appuient souvent sur des enregistrements de longueur fixe et des données hiérarchiques complexes (XML ou EDI). Les API SOAP, bien que basées sur des normes, sont souvent verbeuses et synchrones, ce qui les rend difficiles à appeler de manière fiable par les LLM sans des prompts structurés. Un prompt direct comme « Récupérer les détails de l'utilisateur pour l'ID 123 » échoue car le LLM ne connaît pas le schéma spécifique ni l'URL du point de terminaison. LangChain résout ce problème en nous permettant de définir des « Outils » qui encapsulent ces appels legacy, offrant au LLM une interface claire et typée pour interagir avec l'ancienne pile.

Construire le pont SOAP

La première étape consiste à encapsuler le service SOAP legacy dans un outil LangChain. Cela implique de définir le schéma d'entrée et la logique pour analyser l'enveloppe SOAP. Nous utilisons le décorateur @tool pour créer une fonction que le LLM peut invoquer. La clé ici est la gestion des erreurs ; les systèmes legacy retournent souvent des codes d'erreur opaques. L'outil doit les traduire en messages lisibles par l'homme que le LLM peut utiliser pour réessayer ou ajuster sa stratégie.

from langchain_core.tools import tool
import requests
from pydantic import BaseModel, Field

class LegacyUserRequest(BaseModel):
    """Récupère les détails de l'utilisateur depuis l'API SOAP legacy."""
    user_id: str = Field(..., description="L'identifiant unique de l'utilisateur")

@tool
def get_user_from_mainframe(user_id: str) -> str:
    """
    Se connecte au point de terminaison SOAP legacy pour récupérer les données de l'utilisateur.
    
    Args:
        user_id: L'ID de l'utilisateur à récupérer.
    """
    soap_envelope = f"""
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <soapenv:Body>
            <ns:GetUser>
                <ns:UserID>{user_id}</ns:UserID>
            </ns:GetUser>
        </soapenv:Body>
    </soapenv:Envelope>
    """
    headers = {
        "Content-Type": "application/soap+xml",
        "SOAPAction": "http://example.com/getUser"
    }
    
    try:
        response = requests.post("https://legacy.enterprise.com/api", data=soap_envelope, headers=headers)
        # Dans un scénario réel, vous analyseriez correctement la réponse XML
        # Ici, nous simulons un succès pour la concision
        if response.status_code == 200:
            return f"Utilisateur {user_id} trouvé : John Doe, Ingénieur Senior"
        else:
            return f"Erreur : L'API legacy a renvoyé {response.status_code}"
    except Exception as e:
        return f"Échec de la connexion : {str(e)}"

Gérer les jobs par lots du mainframe

Contrairement aux API SOAP, les jobs par lots du mainframe sont souvent asynchrones. Le LLM ne peut pas attendre la fin d'un job en temps réel. Une architecture d'agent robuste doit implémenter un motif de « interrogation » (polling) ou un mécanisme de webhook. Dans LangChain, vous pouvez créer une configuration d'outil en deux étapes : l'une pour soumettre le job et l'autre pour vérifier son statut. La logique de l'agent (généralement pilotée par une chaîne ReAct ou Plan-and-Execute) doit être instruite d'attendre ou de réessayer si le job est toujours « En cours ». Cela nécessite une ingénierie de prompts soignée pour empêcher le LLM d'halluciner des données qui n'ont pas encore été retournées.

from langchain.agents import AgentExecutor, create_react_agent
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate

llm = ChatOpenAI(model="gpt-4", temperature=0)

tools = [get_user_from_mainframe]

prompt = PromptTemplate.from_template("""
Répondez aux questions suivantes du mieux que vous pouvez.
Vous avez accès aux outils suivants :
{tools}

Utilisez le format suivant :

Question : la question d'entrée à laquelle vous devez répondre
Pensée : vous devriez toujours réfléchir à ce qu'il faut faire
Action : l'action à prendre, doit être l'une de [{tool_names}]
Entrée de l'action : l'entrée pour l'action
Observation : le résultat de l'action
... (cette séquence Pensée/Action/Entrée de l'action/Observation peut se répéter N fois)
Pensée : je connais maintenant la réponse finale
Réponse finale : la réponse finale à la question d'entrée originale

Commencez !

Question : {input}
Pensée : {agent_scratchpad}
""")

agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

response = agent_executor.invoke({
    "input": "Qui est l'utilisateur ID 123 ?"
})

Meilleures pratiques pour la conception d'agents legacy

Lors du déploiement de ces agents, tenez compte de la sécurité et de la latence. Les systèmes legacy sont souvent derrière des pare-feu stricts ; assurez-vous que votre agent s'exécute dans une zone réseau ayant la permission d'accéder à ces points de terminaison. De plus, les réponses SOAP peuvent être volumineuses. Il est conseillé de post-traiter la réponse XML/JSON au sein de la fonction outil pour extraire uniquement les champs pertinents avant de renvoyer la chaîne au LLM. Cela réduit l'utilisation des jetons et améliore la précision de la réponse finale du modèle.

Conclusion

Combler le fossé entre l'IA moderne et l'infrastructure legacy ne consiste pas à remplacer les anciens systèmes, mais à les augmenter. En utilisant LangChain pour créer des interfaces structurées et basées sur les outils pour les services Mainframe et SOAP, les développeurs peuvent permettre aux LLM d'agir comme un middleware intelligent. Cette approche permet aux entreprises d'exploiter la puissance de l'IA générative pour améliorer les flux de travail existants, offrant un accès en langage naturel aux données historiques critiques sans le surcoût massif d'une migration complète du système. À mesure que les cadres d'agents évoluent, ce motif d'« encapsulation » des systèmes legacy dans des couches sémantiques deviendra une pratique standard dans l'intégration d'entreprise.

Share: