1. Un RAG se diagnostique étape par étape #
La plupart des mauvaises réponses viennent de la recherche.
Les étapes #
| Mauvaise réponse due à... | Ce que montre la trace | Correction |
|---|---|---|
| Documents non pertinents | Span RETRIEVER : les passages ne parlent pas du sujet | Découpage, embeddings, filtres, recherche hybride |
| Bon document mal classé | Score faible, document en 5e position | Reranker, nombre de documents |
| Bon contexte, mauvaise réponse | Span LLM : la réponse contredit le contexte | Prompt, modèle, température |
| Contexte tronqué | Jetons d'entrée au maximum | Moins de documents, passages plus courts |
2. Instrumenter un RAG maison #
Quand aucun framework ne le fait pour vous.
Code #
from opentelemetry import trace
from openinference.semconv.trace import SpanAttributes, OpenInferenceSpanKindValues as Kind
tracer = trace.get_tracer("faq-rag")
def answer(question: str) -> str:
with tracer.start_as_current_span("faq-rag") as root:
root.set_attribute(SpanAttributes.OPENINFERENCE_SPAN_KIND, Kind.CHAIN.value)
root.set_attribute(SpanAttributes.INPUT_VALUE, question)
docs = retrieve(question) # span RETRIEVER (voir l'article OpenInference)
context = "\n".join(d.text for d in docs)
r = client.chat.completions.create( # span LLM créé automatiquement
model=model,
messages=[{"role": "system", "content": "Réponds uniquement à partir du contexte :\n" + context},
{"role": "user", "content": question}])
text = r.choices[0].message.content
root.set_attribute(SpanAttributes.OUTPUT_VALUE, text)
return textÀ savoir : Le span racine de type CHAIN porte la question et la réponse finale : c'est lui que l'on évaluera, et c'est lui que l'on exportera vers un dataset.3. Les agents #
Des traces plus profondes.
Ce qu'il faut voir #
- Chaque tour de l'agent : l'appel LLM qui décide, l'outil choisi et ses arguments (
tool_call.function.arguments), le résultat de l'outil. - Les boucles : un agent qui appelle dix fois le même outil coûte cher et répond lentement.
- Les erreurs d'outils : un span TOOL en erreur que l'agent a ignoré.
Les frameworks d'agents (OpenAI Agents SDK, LangGraph via LangChain, CrewAI, smolagents) ont leur instrumentation OpenInference : auto_instrument=True suffit si le paquet est installé.
Bonne Pratique : Mesurez le nombre de spans TOOL par trace : une hausse soudaine après un changement de prompt révèle souvent un agent qui tourne en rond.
4. Sessions et conversations #
Relier les échanges.
Sessions #
from openinference.instrumentation import using_session
with using_session(session_id=conversation_id):
reply = answer(question)Phoenix regroupe alors les traces d'une même conversation : on relit un échange complet, tour par tour, et l'on voit à quel moment il a déraillé.
