Let's think this through for a moment
This exercise set is more challenging than the first one, combining the RAG/Memory concepts from the Intermediate chapter with the Agents/Tools concepts from the Advanced chapter. The tasks ramp up gradually, starting from embeddings/similarity search, moving through conversational memory, and finally building an agent with a custom tool. Running through these tasks yourself will give you a deeper understanding of the whole RAG pipeline and agent decision-making logic. There's no new teaching here — it's purely meant as practice for concepts already covered in earlier lessons.
Exercises
Task 1: Embed a custom text with 3-4 facts and use similarity_search() to find the nearest chunk to a query. Task 2: Connect a RetrievalQA chain to ConversationBufferMemory and ask two follow-up questions in a row. Task 3: Wrap a custom Tool with Tool() that either reverses a string or counts its characters. Task 4: Add both the document retrieval tool and Task 3's custom tool, initialize an agent with verbose=True, and observe from the log which tool the agent picks and when.
Code Example
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from langchain.agents import Tool, initialize_agent, AgentType
from langchain_core.documents import Document
# Task 1: custom text ကို embed + similarity search
facts = [
"LangChain သည် LLM application များ တည်ဆောက်ရန် framework တစ်ခုဖြစ်သည်။",
"RAG သည် Retrieval-Augmented Generation ၏ အတိုကောက်ဖြစ်သည်။",
"Vector store များသည် embeddings များကို သိမ်းဆည်းပြီး similarity search ပြုလုပ်သည်။",
]
docs = [Document(page_content=f) for f in facts]
vectorstore = Chroma.from_documents(docs, OpenAIEmbeddings())
# TODO: vectorstore.similarity_search("RAG ဆိုတာဘာလဲ?", k=1) ကို run ကြည့်ပါ
# Task 2: memory ပါသော conversational RAG
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
conv_chain = ConversationalRetrievalChain.from_llm(
llm=llm, retriever=vectorstore.as_retriever(), memory=memory
)
# TODO: question 2 ခု ဆက်တိုက် invoke() လုပ်ကြည့်ပါ
# Task 3: custom tool
def reverse_text(text: str) -> str:
return text[::-1]
reverse_tool = Tool(
name="text_reverser",
func=reverse_text,
description="ပေးထားသော text ကို reverse ပြန်ပေးရန် အသုံးပြုပါ",
)
# Task 4: tool 2 ခုပါသော agent
document_tool = Tool(
name="document_search",
func=lambda q: conv_chain.invoke({"question": q})["answer"],
description="Fact document ထဲက data နှင့် ပတ်သက်တဲ့ မေးခွန်းများကို ဖြေရန် အသုံးပြုပါ",
)
agent = initialize_agent(
tools=[document_tool, reverse_tool],
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
)
# TODO: agent.invoke({"input": "..."}) ကို tool နှစ်ခုစလုံး trigger ဖြစ်အောင် query 2 မျိုးနှင့် run ကြည့်ပါ
After each task, you'll see the similarity search result, the memory-aware follow-up answer, and the agent's tool-selection reasoning log in the terminal.5-Minute Try-It
In 5 minutes, run Task 4's agent with both the query 'reverse the word LangChain' and the query 'what is RAG', and confirm the agent picks the right tool each time.
A Quick Warning
Running an agent with verbose=True is great for debugging and learning, but in production the logs can get overwhelming, so you should switch to a structured tracing tool like LangSmith instead.