Spaces:
Running
Download src/react_agent/README.md from LeoWalker/learningfocused-mcp: direct link, hf CLI and curl.
- Browser
- Download file 7.29 kB
-
https://huggingface.co/spaces/LeoWalker/learningfocused-mcp/resolve/main/src/react_agent/README.md
- Command line
-
hf download hf://spaces/LeoWalker/learningfocused-mcp/src/react_agent/README.md
-
curl -L -o README.md https://huggingface.co/spaces/LeoWalker/learningfocused-mcp/resolve/main/src/react_agent/README.md
React Agent
A lightweight LangChain ReAct agent for querying the Future of Education podcast knowledge base.
Overview
This agent implements the ReAct pattern (Reason β Act/tool call β Observe β repeat) using langchain.agents.create_agent. It's intended for fast, tool-grounded Q&A over the local stores (Chroma + Neo4j).
Features:
- Conversation memory via LangGraph's SQLite checkpointer (survives process restart)
- Multi-provider support (OpenAI, Anthropic, Google, Fireworks)
- Streaming tool calls and responses
When to use this vs deep_research_agent:
- React Agent: Quick questions, single-topic lookups, testing tools
- Deep Research Agent: Complex multi-part research, comprehensive reports, cross-episode synthesis
File Structure
| File | Purpose |
|---|---|
graph.py |
Main agent using langchain.agents.create_agent |
checkpointer.py |
SqliteSaver helper (gitignored .checkpoints/react_agent.sqlite) |
prompts.py |
System prompt guiding agent behavior |
configuration.py |
Settings (model, max iterations, etc.) with model registry |
utils.py |
Helper functions for model creation and tool management |
tools.py |
Re-exports shared tools (Chroma, Neo4j) |
chat_cli.py |
Interactive terminal interface |
__init__.py |
Package exports |
Architecture
User Query
β
βΌ
βββββββββββββββββββββββββββββββββββββββ
β ReAct Agent (create_agent) β
β βββββββββββββββββββββββββββββββ β
β β 1. Reason: What do I need? β β
β β 2. Act: Call a tool ββββββΌβββ Tools:
β β 3. Observe: Read result β β β’ search_knowledge_base (Chroma)
β β 4. Repeat or Answer β β β’ query_knowledge_graph (Neo4j)
β βββββββββββββββββββββββββββββββ β β’ inspect_graph_schema
βββββββββββββββββββββββββββββββββββββββ
β
βΌ
Answer
Implementation Details
Dynamic Schema Loading
The agent dynamically loads the Neo4j graph schema at startup (in prompts.py) to minimize tool calls. This allows the agent to write Cypher queries immediately without needing an initial inspect_graph_schema call, reducing latency and cost.
Multi-Provider Support
Model creation is delegated to the shared factory in src/llm/factory.py, which supports multiple providers and validates the required API key env var for the chosen model.
Model names accept stable aliases (recommended) that are mapped to provider-specific IDs under the hood:
- OpenAI:
gpt-5,gpt-5-mini - Anthropic:
claude-sonnet-4-20250514(alias), plus internal IDs likeclaude-sonnet-4-5 - Google Gemini:
gemini-flash-latest(alias)
Model Configuration
Models are configured via the Configuration class which supports:
- Model selection (default:
gemini-flash-latest) - Max tokens (default: 4000)
- Temperature (default: 0.0)
- Timeout (default: 30 seconds)
- Max iterations (default: 25)
Configuration can be overridden at runtime via RunnableConfig.
Usage
Interactive Chat
# Interactive chat (prints the full thread_id)
uv run python -m src.react_agent.chat_cli
Replay a thread after restart
Checkpoints are stored at .checkpoints/react_agent.sqlite (gitignored; override with REACT_AGENT_CHECKPOINT_PATH). The CLI prints the full thread_id. Pass it back on the next process to continue the same conversation:
# Process 1 β start a chat and copy the printed thread_id
uv run python -m src.react_agent.chat_cli
# thread_id: 550e8400-e29b-41d4-a716-446655440000
# You: Remember that my favorite episode is about Two Hour Learning.
# ... type exit ...
# Process 2 β same thread_id continues the conversation
uv run python -m src.react_agent.chat_cli --thread-id 550e8400-e29b-41d4-a716-446655440000
# You: What did I say my favorite episode was?
You can also set REACT_AGENT_THREAD_ID instead of --thread-id.
Programmatic Usage
from src.react_agent.graph import react_agent, get_react_agent
from langchain_core.messages import HumanMessage
# Use default agent with durable SQLite conversation memory
# Pass a thread_id so the same conversation survives process restart
result = await react_agent.ainvoke(
{"messages": [HumanMessage(content="What is Two Hour Learning?")]},
config={"configurable": {"thread_id": "my-session-123"}}
)
# Follow-up questions in the same thread remember context
result = await react_agent.ainvoke(
{"messages": [HumanMessage(content="Tell me more about that")]},
config={"configurable": {"thread_id": "my-session-123"}}
)
# Create agent with custom config
from langchain_core.runnables import RunnableConfig
config = RunnableConfig(
configurable={
"model": "claude-sonnet-4-5",
"max_tokens": 8000,
"temperature": 0.1,
"thread_id": "custom-thread"
}
)
custom_agent = get_react_agent(config)
result = await custom_agent.ainvoke({
"messages": [HumanMessage(content="What is Two Hour Learning?")]
}, config=config)
Comparison with deep_research_agent
| Aspect | React Agent | Deep Research Agent |
|---|---|---|
| Framework | LangChain create_agent |
LangGraph custom graph |
| Graph complexity | Single ReAct loop | Multi-node (clarify β brief β supervisor β researchers β report) |
| Use case | Quick Q&A | In-depth research |
| Tool access | Direct | Delegated via researchers |
| Output | Single response | Structured report |
| State | Minimal (messages + checkpointer memory) | Rich (brief, notes, iterations) |
| Memory | SqliteSaver checkpointer (disk, by thread_id) | Graph state |
| Model creation | Provider-specific classes | init_chat_model with configurable fields |
Tools Available
The agent has access to these tools (re-exported from deep_research_agent.tools):
- search_knowledge_base(query) - Semantic search over podcast transcripts and episode summaries in ChromaDB
- query_knowledge_graph(query) - Run Cypher queries against the Neo4j knowledge graph
- inspect_graph_schema() - Get the Neo4j schema (nodes, relationships) to help write Cypher
Configuration
Default settings in configuration.py:
- Model:
gemini-flash-latest - Max iterations: 25 (safety limit)
- Max tokens: 4000
- Temperature: 0 (deterministic)
- Timeout: 30 seconds
Override via RunnableConfig:
from langchain_core.runnables import RunnableConfig
config = RunnableConfig(
configurable={
"model": "gpt-5",
"max_iterations": 5,
"max_tokens": 8000,
"temperature": 0.1
}
)
result = await react_agent.ainvoke(input, config=config)
Or set environment variable:
export REACT_AGENT_DEFAULT_MODEL="claude-sonnet-4-20250514"
Dependencies
Dependencies are managed in the repoβs pyproject.toml. The key runtime pieces are LangChain (+ provider integrations) and python-dotenv.