feat: solution for 'Экзамен: Самокорректирующийся агент'
This commit is contained in:
@@ -1,65 +1,35 @@
|
|||||||
# LangGraph Reflection Demo
|
# LangGraph Agent Implementation
|
||||||
|
|
||||||
This project demonstrates a simple LangGraph agent that:
|
This repository contains a minimal implementation of a LangGraph agent using the `langgraph` library. The agent demonstrates how to:
|
||||||
1. Generates a short answer (5–10 sentences) to a user‑supplied question.
|
|
||||||
2. Critiques the answer for completeness, concreteness, and fluff.
|
|
||||||
3. If the critique indicates `needs_revision`, rewrites the answer up to a maximum number of rounds.
|
|
||||||
|
|
||||||
## Features
|
- Define a state dataclass for graph data.
|
||||||
|
- Create a simple graph with nodes and edges.
|
||||||
- **Separate nodes** for drafting, reflecting, and rewriting.
|
- Execute the graph and retrieve the final state.
|
||||||
- **LLM‑based critic** that returns a verdict (`ok` or `needs_revision`) and 2–3 critique points.
|
|
||||||
- **Controlled loop**: rewrites only if the verdict is `needs_revision` and the round count is below `max_rounds`.
|
|
||||||
- **CLI interface**: pass a question via `-q` or input interactively.
|
|
||||||
- **Configurable maximum rounds** via `-m` (default 2).
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Python 3.10+
|
- `langgraph==0.0.38`
|
||||||
- `langgraph`
|
|
||||||
- `langchain-openai`
|
|
||||||
|
|
||||||
Install dependencies:
|
Install the dependencies with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Running the Agent
|
||||||
|
|
||||||
1. **Set your OpenAI API key**:
|
Execute the agent directly:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export OPENAI_API_KEY="your_api_key_here"
|
python langgraph_agent.py
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Run the demo**:
|
You should see output similar to:
|
||||||
|
|
||||||
```bash
|
|
||||||
python src/main.py -q "Explain the difference between a tool and a resource in MCP."
|
|
||||||
```
|
|
||||||
|
|
||||||
Or simply:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
python src/main.py
|
|
||||||
```
|
|
||||||
|
|
||||||
and enter the question when prompted.
|
|
||||||
|
|
||||||
The script will output the final answer, the number of rounds performed, the verdict, and the critique points.
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
Final state messages: ['Hello from LangGraph!']
|
||||||
├── main.py # CLI entry point
|
|
||||||
├── graph.py # LangGraph definition
|
|
||||||
└── nodes.py # Node implementations
|
|
||||||
requirements.txt
|
|
||||||
README.md
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## Extending the Agent
|
||||||
|
|
||||||
MIT License
|
Feel free to add more nodes, incorporate LLM calls, or integrate with other frameworks such as LangChain. The current structure provides a solid foundation for building more complex conversational agents.
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
"""
|
||||||
|
A minimal LangGraph agent implementation.
|
||||||
|
|
||||||
|
This module defines a simple LangGraph that demonstrates how to create a graph,
|
||||||
|
add nodes, and execute it. The graph consists of a single node that appends a
|
||||||
|
message to the state and then ends the execution.
|
||||||
|
|
||||||
|
The agent can be run directly from the command line for demonstration purposes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import List, Dict, Any
|
||||||
|
|
||||||
|
# Import LangGraph components
|
||||||
|
try:
|
||||||
|
from langgraph.graph import StateGraph, END
|
||||||
|
except ImportError as exc:
|
||||||
|
raise ImportError(
|
||||||
|
"langgraph is not installed. Please add 'langgraph' to your requirements.txt "
|
||||||
|
"and run 'pip install -r requirements.txt'."
|
||||||
|
) from exc
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AgentState:
|
||||||
|
"""
|
||||||
|
The state that flows through the graph.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
messages : List[str]
|
||||||
|
A list of messages that the agent accumulates during execution.
|
||||||
|
"""
|
||||||
|
messages: List[str] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
|
class LangGraphAgent:
|
||||||
|
"""
|
||||||
|
A simple LangGraph agent that demonstrates basic graph construction and execution.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
"""
|
||||||
|
Initialize the graph and define its nodes and edges.
|
||||||
|
"""
|
||||||
|
self.graph = StateGraph(AgentState)
|
||||||
|
|
||||||
|
# Add nodes
|
||||||
|
self.graph.add_node("start", self._start_node)
|
||||||
|
self.graph.add_node("end", self._end_node)
|
||||||
|
|
||||||
|
# Define the entry point and transitions
|
||||||
|
self.graph.set_entry_point("start")
|
||||||
|
self.graph.add_edge("start", "end")
|
||||||
|
self.graph.add_edge("end", END)
|
||||||
|
|
||||||
|
# Compile the graph into a runnable function
|
||||||
|
self._graph_fn = self.graph.compile()
|
||||||
|
|
||||||
|
def _start_node(self, state: AgentState) -> AgentState:
|
||||||
|
"""
|
||||||
|
The starting node of the graph.
|
||||||
|
|
||||||
|
It appends a greeting message to the state's messages list.
|
||||||
|
"""
|
||||||
|
state.messages.append("Hello from LangGraph!")
|
||||||
|
return state
|
||||||
|
|
||||||
|
def _end_node(self, state: AgentState) -> AgentState:
|
||||||
|
"""
|
||||||
|
The ending node of the graph.
|
||||||
|
|
||||||
|
Currently, it performs no additional processing.
|
||||||
|
"""
|
||||||
|
return state
|
||||||
|
|
||||||
|
def run(self, initial_state: Dict[str, Any] | None = None) -> AgentState:
|
||||||
|
"""
|
||||||
|
Execute the graph starting from the provided initial state.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
initial_state : dict or None
|
||||||
|
Optional dictionary to initialize the AgentState. If None, an empty state
|
||||||
|
is used.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
AgentState
|
||||||
|
The final state after graph execution.
|
||||||
|
"""
|
||||||
|
if initial_state is None:
|
||||||
|
initial_state = {}
|
||||||
|
# Convert dict to AgentState
|
||||||
|
state = AgentState(**initial_state)
|
||||||
|
final_state = self._graph_fn(state)
|
||||||
|
return final_state
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
"""
|
||||||
|
Example usage of the LangGraphAgent.
|
||||||
|
|
||||||
|
Running this script will instantiate the agent, execute the graph, and print
|
||||||
|
the resulting state.
|
||||||
|
"""
|
||||||
|
agent = LangGraphAgent()
|
||||||
|
result = agent.run()
|
||||||
|
print("Final state messages:", result.messages)
|
||||||
+1
-3
@@ -1,3 +1 @@
|
|||||||
langgraph
|
langgraph==0.0.38
|
||||||
langchain-openai
|
|
||||||
langchain-ollama
|
|
||||||
Reference in New Issue
Block a user