Welcome to this video on building Reflexion Agents.
In this video, you'll build a Reflexion Agent by applying prompt engineering and schema design.
You'll analyze AI responses and tool call outputs, and create an iterative feedback loop using Responder and Revisor nodes.
Finally, you'll evaluate how citation-backed revisions improve the depth of responses.
To build Reflexion Agents, begin with the essential imports to set up your environment.
The next step is to configure the Tavily Search tool for use in your agent workflow.
Set up the API key for the Tavily Search service.
Create a Tavily Search tool instance that returns up to 5 results per query.
Test the search tool with a sample query about breakfast recipes.
The invoke method executes the search and returns structured results.
The search results return as a list of JSON dictionaries, each with a dictionary containing
keys like title, URL, and content.
Next, create an instance of the ChatOpenAI model using GPT.
Send the question to the LLM and extract the text response, such as,
Any ideas for a healthy breakfast?
The response is generic advice, like eating oatmeal, Greek yogurt, or avocado toast.
The purpose is to create a Reflexion Agent that generates the most cutting-edge, but
not yet proven, health ideas.
The agent uses Reflexion to improve and evolve its responses over time.
Create a system message to tell the LLM to behave like Dr. Paul Saladino, specializing
in controversial approaches like carnivore diets and extended fasting.
The first_instruction is a variable to alter the prompt.
Populate the first instruction variable with a specific prompt that requests a 250-word response.
Connect the LLM to the system message.
The model will now behave according to the defined persona, as illustrated in the diagram.
This setup is for demonstration purposes only.
Pass the same question.
The LLM responds with a suggestion for a carnivore diet, a diet that may have some benefits but
is not commonly recommended by mainstream health authorities.
Now alter the LLM output to match the requirements.
Create the reflection schema or class.
The fields describe what each field does.
The LLM outputs the missing field for what information is needed and the superfluous
field for what's unnecessary.
The AnswerQuestion class includes the answer, reflections, and search queries.
The Reflection class is instantiated in the AnswerQuestion class.
The LLM eventually outputs a JSON object with the attributes filled out.
Like before, chain the LLM to the system message.
This will be a node in the LangGraph graph.
You also need to bind the LLM to the AnswerQuestion schema using the bind_tools method.
Essentially, the LLM will treat the AnswerQuestion class like a function.
Pass the same message with the same question.
The LLM responds with a suggestion for a carnivore diet.
The result is not text but an AI message class that contains extensive information.
But for reflection, the focus is on the tool_calls attribute.
The tool_calls attribute contains the name of the class of the key-value pairs
such as answer, reflection, missing, and superfluous with their corresponding text outputs.
Response_list will be used to test the pipeline for one iteration.
It will be analogous to the state variable in LangGraph.
Append the user question and append the response from the responder.
You can extract the search queries from the response.
But let's create a LangGraph function for this purpose.
Create a function for extracting the search queries from the responder message as a node for LangGraph.
This node will also be used for the revisor.
The state will be like the response list.
Extract the AI message from the state.
Next, extract the tool call parameters.
Obtain the search queries from the LLM.
Call the search tool and wrap the result in a tool message.
Call the tool and append the tool response to response_list.
There are many Reflexion prompt templates.
Add a revisor system message guiding the LLM to act like Dr. Peter Accia, an expert in
longevity and evidence-based health, and support responses with evidence.
Update the prompt template to reflect this expert role.
Create a schema for the revisor.
The class is a subclass of answer question schema, so it will have the same fields and a citation list.
Chain the system message and bind the LLM to the revise answer schema.
This is another node in the LangGraph graph.
The revisor passes the response list to revisor_chain.
The result is an AI message.
The args tool_call attribute has all the key-value pairs of the schema.
Append the response to the response list.
Now you have the second AI message from the revisor.
You can feed the input back to the tool iteratively.
Create a conditional node function that counts tool messages as a proxy for the number of
iterations between the revisor and the search tools.
It will count each time the tool is called.
Build the graph by importing the necessary components.
Then initialize the message graph and set the maximum iteration limit to 4.
To create the graph, first add the respond node to the graph that uses the initial_chain.
Then, add the execute_tools node that runs the search queries generated by the draft node.
Finally, add a "revisor" node that uses the revisor_chain to improve the draft
response using the search results and original critique.
Next, connect the respond node to execute tools via an edge.
And connect the tool to the revisor via an edge.
Next, add the start and exit points.
First, add a conditional edge from the revisor via the event_loop function to
decide whether to continue iterating or end.
The end node is hidden in event_loop.
This outputs the response after a set number of iterations.
Finally, set the entry point to the draft responder node.
This is where the query is first processed.
Compile the graph.
Input the query, I'm pre-diabetic and need to lower my blood sugar, and I have heart issues.
The result is a human message followed by a list of alternating AI and tool messages.
You can extract the answer from the AI response.
The initial responder provided a general advocacy for animal-based nutrition, recommending
eggs, fatty meats, and organ foods, while avoiding grains and plant foods based on broad nutritional philosophy.
This is not medical advice.
Similarly, you can get the answer from the final revisor iteration.
The revisor improved it by adding five scientific citations, measurable outcomes like postprandial
glucose levels, and more precise guidance distinguishing processed from unprocessed foods.
Otherwise, neither response adequately addresses the heart health concerns from the original
query, focusing instead on blood sugar management while largely overlooking cardiovascular aspects.
In this video, you learned that
A search tool like Tavily can be configured and invoked to enhance AI responses with external data.
Prompt engineering and schema design guide the LLM to produce structured reflections
and focused answers.
The answer question and reflection schema capture answers, flag missing or irrelevant
details, and generate queries.
Tool outputs like tool_calls and schema fields help extract structured insights from AI messages.
LangGraph chains responder and revisor nodes into an iterative feedback loop using prompt
updates and evidence-based revisions.
A message graph orchestrates the Reflexion agent, managing node routing, iteration limits, and control flow.