This commit is contained in:
Harrison Chase
2025-03-05 18:23:12 -08:00
commit 9353228fce
6 changed files with 129 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
# Virtual environments
.venv
+36
View File
@@ -0,0 +1,36 @@
# LangGraph-Reflexion
This prebuilt graph is an agent that uses a reflection-style architecture to check and improve an initial agent's output.
This reflection agent uses two subagents:
- A "main" agent, which is the agent attempting to solve the users task
- A "critique" agent, which checks the main agents work and offers any critiques
The reflection agent has the following architecture:
1. First, the main agent is called
2. Once the main agent is finished, the critique agent is called
3. Based on the result of the critique agent:
- If the critique agent finds something to critique, then the main agent is called again
- If there is nothing to critique, then the overall reflection agent finishes
4. Repeat until the overall reflection agent finishes
We make some assumptions about the graphs:
- The main agent should take as input a list of messages
- The reflection agent should return a **user** message if there is any critiques, otherwise it should return **no** messages.
## Examples
Below are a few examples of how to use this reflection agent.
### LLM-as-a-Judge
In this example, the reflection agent uses another LLM to judge it's output
### Coding
Code is easy to "check" in deterministic ways. In this example, we use a linter to check Python code.
View File
+34
View File
@@ -0,0 +1,34 @@
from langgraph_reflexion import create_reflection_graph
from langchain.chat_models import init_chat_model
from langgraph.graph import StateGraph, MessagesState, START, END
from typing import TypedDict
def call_model(state):
return {"messages": init_chat_model(model="claude-3-7-sonnet-latest").invoke(state['messages'])}
graph = StateGraph(MessagesState).add_node(call_model).add_edge(START, "call_model").add_edge("call_model", END).compile()
class Finish(TypedDict):
finish: bool
critique_prompt = """Your job is to look at the conversation below, and look at the AI assistant's response.
Critique it. Make sure it is complete. Make sure it is well thoughtout. Make sure it does what the user wants.
If it is good, then call the `Finish` tool. If you don't call the `Finish` tool, your response will be sent back to the assistant, so make sure to include concrete feedback on how it can improve."""
def nl_critique(state, config):
response = init_chat_model(model="o3-mini", model_provider="openai").bind_tools([Finish]).invoke(
[{"role": "system", "content": critique_prompt}] + state['messages']
)
if len(response.tool_calls) == 1:
return
else:
return {"messages": [{"role": "user", "content": response.content}]}
critique_graph_general = StateGraph(MessagesState).add_node(nl_critique).add_edge(START, "nl_critique").add_edge("nl_critique", END).compile()
overall_graph = create_reflection_graph(graph, critique_graph_general)
+19
View File
@@ -0,0 +1,19 @@
[project]
name = "langgraph-reflexion"
version = "0.0.1"
description = "LangGraph agent that runs a reflection step"
readme = "README.md"
requires-python = ">=3.11"
dependencies = ["langgraph"]
authors = [{name = "Harrison Chase"}]
[tool.setuptools.packages.find]
where = ["src"]
[tool.uv.sources]
langgraph-reflexion = { workspace = true }
[dependency-groups]
dev = [
"langgraph-reflexion",
]
+30
View File
@@ -0,0 +1,30 @@
from typing import Optional, Type, Any, Literal
from langgraph.graph import END, START, StateGraph
from langgraph.graph.state import CompiledStateGraph
from langchain_core.messages import HumanMessage
def end_or_reflect(state) -> Literal[END, "graph"]:
if len(state["messages"]) == 0:
return END
last_message = state["messages"][-1]
if isinstance(last_message, HumanMessage):
return "graph"
else:
return END
def create_reflection_graph(
graph: CompiledStateGraph,
reflection: CompiledStateGraph,
state_schema: Optional[Type[Any]] = None,
config_schema: Optional[Type[Any]] = None,
) -> StateGraph:
_state_schema = state_schema or graph.builder.schema
rgraph = StateGraph(state_schema, config_schema=config_schema)
rgraph.add_node("graph", graph)
rgraph.add_node("reflection", reflection)
rgraph.add_edge(START, "graph")
rgraph.add_edge("graph", "reflection")
rgraph.add_conditional_edges("reflection", end_or_reflect)
return rgraph