Custom RAG Agent with LangChain
This article is for custom agent development: writing a Python agent class because the built-in configurable agent is not enough. For standard search and retrieval-augmented generation, configure the built-in agent with the CLI instead - see Configuring Tools.
Use this pattern when you want to run a LangChain retrieval pipeline inside an Agents SDK agent. The example below uses ZAVLangchainStore as the retriever source and ChatOpenAI as the LangChain chat model.
Prerequisites
- Completed Getting Started with the Agents SDK
- Familiar with Custom Agent Development
Install the LangChain extra:
pip install zetaalpha.agents[langchain,langchain-openai]
Step 1: Create a Custom Agent
Change to your agents project directory and scaffold a custom agent:
za agents add --custom "my_langchain_rag_agent"
This creates my_langchain_rag_agent.py in your agents project:
<agents project>/
├── .gitignore
├── __init__.py
├── my_langchain_rag_agent.py
├── agent_setups.json
└── env/
└── agent_setups.json
Step 2: Implement the LangChain RAG Pipeline
Replace the contents of my_langchain_rag_agent.py with:
from typing import List, Optional
from langchain import hub
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
from zav.agents_sdk import ChatAgent, ChatAgentClassRegistry, ChatMessage
from zav.agents_sdk.adapters import ZAVLangchainStore
@ChatAgentClassRegistry.register()
class LangChainRAG(ChatAgent):
agent_name = "my_langchain_rag_agent"
def __init__(
self,
zav_langchain_store: ZAVLangchainStore,
client: ChatOpenAI,
):
self.retriever = zav_langchain_store.as_retriever()
self.llm = client
async def execute(self, conversation: List[ChatMessage]) -> Optional[ChatMessage]:
prompt = hub.pull("rlm/rag-prompt")
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{"context": self.retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| self.llm
| StrOutputParser()
)
answer_msg = await rag_chain.ainvoke(conversation[-1].content)
return ChatMessage(
sender="bot",
content=answer_msg,
)
The agent converts the Zeta Alpha store into a LangChain retriever, uses the LangChain Hub RAG prompt, and returns the chain output as a chat message.
Step 3: Run the Agent Locally
Run the local development UI:
za agents dev --reload
You can also serve the agent as an API:
za agents serve --reload
Then call the chat endpoint:
curl -X POST "http://localhost:8000/chats/responses?tenant=zetaalpha" \
-H "Content-Type: application/json" \
-d '{
"agent_identifier": "my_langchain_rag_agent",
"conversation": [
{"sender": "user", "content": "What is a transformer?"}
]
}'
The response should contain the LangChain-generated answer.