2025 — 2026
Agentic Research Assistant
A LangGraph agent that works out for itself whether a question needs live data, then reaches YouTube and Reddit through an MCP server it calls mid-conversation.
The problem
A chatbot that searches on every turn is slow and wasteful, because plenty of questions don't need anything fetched. A chatbot with no tools at all is stale. The part I wanted to get right was the decision in between: on this turn, does this question need live data, and if so, from where?
Architecture
- 01
The graph puts the agent at the centre, with a conditional edge sending each turn either straight to a response or out to the tool node.
- 02
YouTube and Reddit search sit behind a FastMCP server as MCP tools, rather than being hardcoded into the agent.
- 03
Tool results come back into agent state, so the model reasons over what it fetched instead of just relaying it.
- 04
Session memory is checkpointed to SQLite, so conversation context survives across turns.
Decisions that mattered
MCP as the tool boundary instead of in-process functions
Writing search as plain Python functions inside the agent is quicker, and it locks the capability into that one app. Putting it behind a FastMCP server makes the boundary a protocol instead: any MCP client can use the same YouTube and Reddit tools, and I can rewrite the agent without touching them. It's more setup than one project strictly needs, which is rather the point of doing it.
Let the model make the routing decision
The easy version is a keyword rule: if the question mentions Reddit, call Reddit. That falls over on anything indirect, like asking what people are complaining about. Handing the decision to the model through a conditional edge covers those cases, and it also skips the tool call when the answer is already sitting in context, so latency and API spend track what the turn actually needs.
Persistent state, not a message buffer
Follow-up questions in research usually depend on something retrieved two turns earlier. Checkpointing the graph state to SQLite means those resolve against everything gathered so far in the session, instead of starting from nothing each time.
Stack
- Orchestration
- LangGraphConditional EdgesState Checkpointing
- Tools
- FastMCPYouTube APIReddit API
- Interface
- StreamlitSQLite