Skip to main content
Retrieval Augmented Generation (RAG) is a common pattern in LLM applications where you first retrieve relevant context from a knowledge base and then use that context to generate a response. LangWatch provides specific ways to capture RAG data, enabling better observability and evaluation of your RAG pipelines. By capturing the contexts (retrieved documents) used by the LLM, you unlock several benefits in LangWatch:
  • Specialized RAG evaluators (e.g., Faithfulness, Context Relevancy).
  • Analytics on document usage (e.g., which documents are retrieved most often, which ones lead to better responses).
  • Deeper insights into the retrieval step of your pipeline.
There are two main ways to capture RAG spans: manually creating a RAG span or using framework-specific integrations like the one for LangChain.

Manual RAG Span Creation

You can manually create a RAG span by decorating a function with @langwatch.span(type="rag"). Inside this function, you should perform the retrieval and then update the span with the retrieved contexts. The contexts should be a list of strings or RAGChunk objects. The RAGChunk object allows you to provide more metadata about each retrieved chunk, such as document_id and source. Here’s an example:
In this example:
  1. perform_rag is decorated with @langwatch.span(type="rag").
  2. Inside perform_rag, we simulate a retrieval step.
  3. langwatch.get_current_span().update(contexts=retrieved_docs) is called to explicitly log the retrieved documents.
  4. The generation step (generate_answer_from_context) is called, which itself can be another span (e.g., an LLM span).

LangChain RAG Integration

If you are using LangChain, LangWatch provides utilities to simplify capturing RAG data from retrievers and tools.

Capturing RAG from a Retriever

You can wrap your LangChain retriever with langwatch.langchain.capture_rag_from_retriever. This function takes your retriever and a lambda function to transform the retrieved Document objects into RAGChunk objects.

Key elements

  • langwatch.langchain.capture_rag_from_retriever(retriever, lambda document: ...): This wraps your existing retriever.
  • The lambda function lambda document: RAGChunk(...) defines how to map fields from LangChain’s Document to LangWatch’s RAGChunk. This is crucial for providing detailed context information.
  • The wrapped retriever is then used to create a tool, which is subsequently used in an agent or chain.
  • Remember to include langwatch.get_current_trace().get_langchain_callback() in your RunnableConfig when invoking the chain/agent to capture all LangChain operations.

Capturing RAG from a Tool

Alternatively, if your RAG mechanism is encapsulated within a generic LangChain BaseTool, you can use langwatch.langchain.capture_rag_from_tool.
The capture_rag_from_tool approach is generally less direct for RAG from retrievers because you have to parse the tool’s output (which is usually a string) to extract structured context information. capture_rag_from_retriever is preferred when dealing directly with LangChain retrievers. By effectively capturing RAG spans, you gain much richer data in LangWatch, enabling more powerful analysis and evaluation of your RAG systems. Refer to the SDK examples for more detailed implementations.