Overview
- Build a chat prompt that includes a system instruction, a conversation history placeholder, the user input placeholder, and an
agent_scratchpadplaceholder. - Create an LLM (ChatOpenAI) and attach the Tavily search tool for web results.
- Wrap an
AgentExecutorwithRunnableWithMessageHistoryso each session can preserve history and the agent scratchpad. - Invoke the runnable agent with per-session IDs to support follow-up questions.
Key components
Imports and basic setup
We need imports for prompt templates, message history, runnables, the LLM, the Tavily search tool, and agent utilities. Theagent_scratchpad placeholder is used as the agent’s temporary workspace.
ChatPromptTemplate.from_messages(...)composes the prompt with system instructions, achat_historyplaceholder, the user input placeholder ({input}), and theagent_scratchpad.searchis the Tavily search tool used by the agent to retrieve web results.MessagesPlaceholderandChatMessageHistoryenable in-memory chat history persistence for a session.
Using
MessagesPlaceholder("agent_scratchpad") gives the agent a workspace to append intermediate reasoning and tool calls. This helps the LLM and the tool orchestrator maintain context across a single turn and between turns when history is preserved.Be careful with API keys in code or logs. Prefer environment variables, secrets managers, or encrypted stores. If a tool reads the key from the environment, do not hardcode it in production.
Create LLM, tools, and the message history
Create the LLM instance, assemble the tools list, and initialize an in-memoryChatMessageHistory for this demo.
Agent creation and wrapping with message history
- Use
create_tool_calling_agentto construct a tool-calling agent with the LLM, tools, and prompt. - Use
AgentExecutorto manage execution and orchestrate tool calls. - Wrap the executor with
RunnableWithMessageHistoryto provide session-aware message history retrieval.
ChatMessageHistory for any session_id. In production, map each session_id to its own persisted ChatMessageHistory (Redis, database, etc.).
Invoking the agent (examples)
When invoking the runnable agent, pass the user input using theinput key and include a config that carries a session_id. RunnableWithMessageHistory uses this session_id to look up and persist the chat history across calls.
Say hello to the agent:
Example: compute days until the tournament
A follow-up that relies on context and a date calculation:LLMs are not always reliable for precise arithmetic or time-based calculations unless you explicitly delegate the calculation to a deterministic tool (like a Python REPL or a date utility). For exact answers (e.g., “days until a date”), add a deterministic tool to the agent that performs the arithmetic and returns the correct result.
How the agent adds value over raw search
- A plain search tool typically returns raw documents, snippets, or URLs.
- The agent can call the search tool, aggregate results, and ask the LLM to synthesize a concise, user-friendly answer.
- With session-aware message history, follow-up questions that refer to earlier turns are handled naturally because the prompt includes previous chat and the agent scratchpad.
Extending this agent
To make the agent more robust and capable of deterministic computation:- Add a Python REPL or date-calculation tool so the agent can delegate numeric or date arithmetic to a deterministic environment.
- Persist
ChatMessageHistorypersession_idusing Redis, a database, or another storage backend for production usage. - Add more retrieval tools or structured data sources (APIs, knowledge bases) to broaden the agent’s factual coverage.
Conclusion and next steps
In this lesson we built a session-aware agent that:- Uses a search tool (Tavily) to fetch web results.
- Uses an LLM (ChatOpenAI) to synthesize and present answers.
- Persists message history via
RunnableWithMessageHistory. - Uses an
agent_scratchpadin the prompt to manage intermediate reasoning and tool calls.
- Add a deterministic tool (Python REPL or date calculator) to handle precise calculations.
- Implement a per-session persistent store for chat history (e.g., Redis).
- Explore multi-tool orchestration and richer prompts to improve answer reliability.
Links and references
- LangChain Python Docs
- Tavily — community tool integrations (check the relevant tool implementation in your SDK)
- OpenAI API and Chat Models