AWS propose deux niveaux pour construire des systèmes RAG et agentiques : le managé (Bedrock Knowledge Bases, Bedrock Agents) et le code-first (votre graphe LangGraph). Ce n’est pas un choix idéologique mais d’ingénierie : chacun a sa zone de pertinence, et un système réel les combine souvent.
Bedrock Knowledge Bases : le RAG managé
Une Knowledge Base prend en charge tout le pipeline RAG : connexion à une source (S3, SharePoint, Confluence…), ingestion, chunking, embeddings, index (OpenSearch, Aurora, S3 Vectors), récupération (hybride incluse) et reranking. Vous ne gérez plus rien de tout cela. Deux API d’usage :
import boto3
agent_rt = boto3.client("bedrock-agent-runtime", region_name="eu-west-1")
# 1) Retrieve : renvoie les passages pertinents (vous gérez la génération)
passages = agent_rt.retrieve(
knowledgeBaseId="KB123",
retrievalQuery={"text": "Comment activer le SSO ?"},
retrievalConfiguration={"vectorSearchConfiguration": {
"numberOfResults": 5,
"overrideSearchType": "HYBRID", # dense + sparse, managé
}},
)
# 2) RetrieveAndGenerate : récupère ET génère la réponse, en une seule API
reponse = agent_rt.retrieve_and_generate(
input={"text": "Comment activer le SSO ?"},
retrieveAndGenerateConfiguration={
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
"knowledgeBaseId": "KB123",
"modelArn": "eu.anthropic.claude-sonnet-4-5-20250929-v1:0",
},
},
)
print(reponse["output"]["text"])
print(reponse["citations"]) # sources, pour la vérifiabilité
L’intégrer à LangGraph
Le plus puissant : utiliser une Knowledge Base comme outil de récupération dans
votre agent LangGraph. langchain-aws fournit le retriever prêt à l’emploi.
from langchain_aws import AmazonKnowledgeBasesRetriever
from langchain_core.tools import tool
kb = AmazonKnowledgeBasesRetriever(
knowledge_base_id="KB123",
retrieval_config={"vectorSearchConfiguration": {"numberOfResults": 5,
"overrideSearchType": "HYBRID"}},
)
@tool
def base_de_connaissances(requete: str) -> str:
"""Recherche dans la base de connaissances managée (Bedrock Knowledge Base)."""
docs = kb.invoke(requete)
return "\n\n".join(d.page_content for d in docs) or "AUCUN_RESULTAT"
On obtient le meilleur des deux mondes : la récupération managée d’AWS (zéro infra) et l’orchestration explicite de LangGraph (boucle corrective, garde-fous, HITL).
Bedrock Agents : l’agent managé
Un Bedrock Agent va plus loin : il orchestre lui-même la boucle de raisonnement, appelle des action groups (vos Lambda exposées comme outils), interroge des Knowledge Bases, et applique des Guardrails — le tout configuré, pas codé.
C’est séduisant pour un agent simple et standard. Mais on touche vite la limite du managé : dès qu’il faut une logique de flux sur-mesure (un routage métier particulier, une boucle évaluateur-optimiseur, un human-in-the-loop fin, un multi-agents non standard), la configuration ne suffit plus. C’est précisément ce que LangGraph exprime nativement.
Comparatif de décision
| Critère | Bedrock managé (KB / Agents) | LangGraph (code-first) |
|---|---|---|
| Vitesse de mise en place | Très rapide | Modérée |
| Contrôle du flux | Limité (configuré) | Total (codé) |
| Patterns avancés (boucles, multi-agents, HITL fin) | Difficile | Natif |
| Infra à opérer | Aucune | La vôtre (ou AgentCore) |
| Testabilité / versioning du flux | Faible | Élevée |
| Portabilité hors AWS | Faible | Élevée |
AgentCore Runtime : héberger LangGraph en managé
Le faux dilemme « managé vs code-first » se dissout avec Bedrock AgentCore Runtime : un environnement d’exécution serverless et isolé, agnostique du framework, qui héberge votre graphe LangGraph tel quel. On garde le contrôle du flux (LangGraph) et on délègue l’hébergement, l’isolation et les sessions (AgentCore).
# Esquisse : on emballe l'agent LangGraph derrière le contrat d'entrée d'AgentCore.
agent = construire_mon_graphe_langgraph() # votre logique, inchangée
def handler(requete: dict) -> dict:
"""Point d'entrée invoqué par AgentCore Runtime pour chaque requête/session."""
resultat = agent.invoke(
{"messages": [{"role": "user", "content": requete["prompt"]}]},
config={"configurable": {"thread_id": requete["session_id"]}},
)
return {"reponse": resultat["messages"][-1].content}
On combine alors AgentCore Memory (mémoire managée), Gateway (vos API exposées comme outils), Identity (accès délégués) et Observability — autour d’un cœur LangGraph qui reste lisible, testable et traçable.
Bonnes pratiques & pièges
- Démarrez managé (Knowledge Bases) pour le RAG : zéro infra, hybride et reranking inclus.
- Utilisez la KB comme outil de récupération DANS un agent LangGraph : managé + contrôle.
- Réservez Bedrock Agents aux agents standards (ReAct + outils + RAG).
- Passez code-first (LangGraph) dès que le flux est votre valeur ajoutée.
- Hébergez votre graphe LangGraph sur AgentCore Runtime pour déléguer l'infra sans perdre le contrôle.
- Citez les sources (citations Knowledge Bases) pour la vérifiabilité.
- Forcer un flux complexe dans Bedrock Agents : la config atteint vite sa limite.
- Réimplémenter à la main un RAG que Knowledge Bases gère très bien (ingestion, index, hybride).
- Confondre AgentCore (hébergement) et LangGraph (orchestration) : ils sont complémentaires.
- Oublier le versioning du flux : un avantage clé du code-first qu'on perd en tout-managé.
- Verrouiller toute la logique métier dans du managé non portable, sans stratégie de sortie.
Ce qu’il faut retenir
- Knowledge Bases = RAG managé de bout en bout (ingestion, index, hybride, reranking) ; intégrable comme outil d’un agent LangGraph.
- Bedrock Agents = agent managé, parfait pour le standard, vite limité sur le flux sur-mesure.
- LangGraph reste indispensable dès que l’orchestration est votre valeur ajoutée.
- AgentCore Runtime réconcilie les deux : il héberge votre graphe LangGraph en managé, avec Memory, Gateway, Identity et Observability.
- La règle : managé tant que c’est standard, code-first dès que ça ne l’est plus.
On a couvert le managé. Descendons d’un cran vers le contrôle total des modèles : SageMaker pour l’IA agentique.