Skip to content

Commit ea4fbda

Browse files
committed
Move to prompts.py
1 parent 23408cc commit ea4fbda

File tree

12 files changed

+289
-63
lines changed

12 files changed

+289
-63
lines changed

.codespellignore

Whitespace-only changes.

.env.example

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
TAVILY_API_KEY=...
2+
3+
# To separate your traces from other application
4+
LANGSMITH_PROJECT=retrieval-agent
5+
6+
# The following depend on your selected configuration
7+
8+
## LLM choice:
19
ANTHROPIC_API_KEY=....
210
FIREWORKS_API_KEY=...
311
OPENAI_API_KEY=...
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# This workflow will run integration tests for the current project once per day
2+
3+
name: Integration Tests
4+
5+
on:
6+
schedule:
7+
- cron: "37 14 * * *" # Run at 7:37 AM Pacific Time (14:37 UTC) every day
8+
workflow_dispatch: # Allows triggering the workflow manually in GitHub UI
9+
10+
# If another scheduled run starts while this workflow is still running,
11+
# cancel the earlier run in favor of the next run.
12+
concurrency:
13+
group: ${{ github.workflow }}-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
jobs:
17+
integration-tests:
18+
name: Integration Tests
19+
strategy:
20+
matrix:
21+
os: [ubuntu-latest]
22+
python-version: ["3.11", "3.12"]
23+
runs-on: ${{ matrix.os }}
24+
steps:
25+
- uses: actions/checkout@v4
26+
- name: Set up Python ${{ matrix.python-version }}
27+
uses: actions/setup-python@v4
28+
with:
29+
python-version: ${{ matrix.python-version }}
30+
- name: Install dependencies
31+
run: |
32+
curl -LsSf https://astral.sh/uv/install.sh | sh
33+
uv venv
34+
uv pip install -r pyproject.toml
35+
uv pip install -U pytest-asyncio vcrpy
36+
- name: Run integration tests
37+
env:
38+
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
39+
TAVILY_API_KEY: ${{ secrets.TAVILY_API_KEY }}
40+
LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }}
41+
LANGSMITH_TRACING: true
42+
LANGSMITH_TEST_CACHE: tests/casettes
43+
run: |
44+
uv run pytest tests/integration_tests

.github/workflows/unit-tests.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# This workflow will run unit tests for the current project
2+
3+
name: CI
4+
5+
on:
6+
push:
7+
branches: ["main"]
8+
pull_request:
9+
workflow_dispatch: # Allows triggering the workflow manually in GitHub UI
10+
11+
# If another push to the same PR or branch happens while this workflow is still running,
12+
# cancel the earlier run in favor of the next run.
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
unit-tests:
19+
name: Unit Tests
20+
strategy:
21+
matrix:
22+
os: [ubuntu-latest]
23+
python-version: ["3.11", "3.12"]
24+
runs-on: ${{ matrix.os }}
25+
steps:
26+
- uses: actions/checkout@v4
27+
- name: Set up Python ${{ matrix.python-version }}
28+
uses: actions/setup-python@v4
29+
with:
30+
python-version: ${{ matrix.python-version }}
31+
- name: Install dependencies
32+
run: |
33+
curl -LsSf https://astral.sh/uv/install.sh | sh
34+
uv venv
35+
uv pip install -r pyproject.toml
36+
- name: Lint with ruff
37+
run: |
38+
uv pip install ruff
39+
uv run ruff check .
40+
- name: Lint with mypy
41+
run: |
42+
uv pip install mypy
43+
uv run mypy --strict src/
44+
- name: Check README spelling
45+
uses: codespell-project/actions-codespell@v2
46+
with:
47+
ignore_words_file: .codespellignore
48+
path: README.md
49+
- name: Check code spelling
50+
uses: codespell-project/actions-codespell@v2
51+
with:
52+
ignore_words_file: .codespellignore
53+
path: src/
54+
- name: Run tests with pytest
55+
run: |
56+
uv pip install pytest
57+
uv run pytest tests/unit_tests

README.md

Lines changed: 114 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,118 @@
11
# LangGraph ReAct Agent Template
22

3-
This LangGraph template implements a simple, extensible ReAct agent.
3+
[![CI](https://github.com/langchain-ai/react-agent/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/langchain-ai/react-agent/actions/workflows/unit-tests.yml)
4+
[![Integration Tests](https://github.com/langchain-ai/react-agent/actions/workflows/integration-tests.yml/badge.svg)](https://github.com/langchain-ai/react-agent/actions/workflows/integration-tests.yml)
5+
6+
This template showcases a [ReAct agent](https://arxiv.org/abs/2210.03629) implemented using [LangGraph](https://github.com/langchain-ai/langgraph), designed for [LangGraph Studio](https://github.com/langchain-ai/langgraph-studio). ReAct agents are uncomplicated, prototypical agents that can be flexibly extended to many tools.
47

58
![Graph view in LangGraph studio UI](./static/studio_ui.png)
69

7-
## Repo Structure
8-
9-
```txt
10-
├── LICENSE
11-
├── README.md
12-
├── langgraph.json
13-
├── poetry.lock
14-
├── pyproject.toml
15-
├── react_agent
16-
│   ├── __init__.py
17-
│   ├── graph.py
18-
│   └── utils
19-
│   ├── __init__.py
20-
│   ├── configuration.py # Define the configurable variables
21-
│   ├── state.py # Define state variables and how they're updated
22-
│   ├── tools.py # Define the tools your agent can access
23-
│   └── utils.py # Other sundry utilities
24-
└── tests # Add whatever tests you'd like here
25-
├── integration_tests
26-
│   └── __init__.py
27-
└── unit_tests
28-
└── __init__.py
10+
The core logic, defined in `src/react_agent/graph.py`, demonstrates a flexible ReAct agent that iteratively reasons about user queries and executes actions, showcasing the power of this approach for complex problem-solving tasks.
11+
12+
## What it does
13+
14+
The ReAct agent:
15+
16+
1. Takes a user **query** as input
17+
2. Reasons about the query and decides on an action
18+
3. Executes the chosen action using available tools
19+
4. Observes the result of the action
20+
5. Repeats steps 2-4 until it can provide a final answer
21+
22+
By default, it's set up with a basic set of tools, but can be easily extended with custom tools to suit various use cases.
23+
24+
## Getting Started
25+
26+
Assuming you have already [installed LangGraph Studio](https://github.com/langchain-ai/langgraph-studio?tab=readme-ov-file#download), to set up:
27+
28+
1. Create a `.env` file.
29+
30+
```bash
31+
cp .env.example .env
32+
```
33+
34+
2. Define required API keys in your `.env` file.
35+
36+
The primary [search tool](./src/react_agent/tools.py) [^1] used is [Tavily](https://tavily.com/). Create an API key [here](https://app.tavily.com/sign-in).
37+
38+
<!--
39+
Setup instruction auto-generated by `langgraph template lock`. DO NOT EDIT MANUALLY.
40+
-->
41+
42+
<details>
43+
<summary>Setup for `model_name` and `scraper_tool_model_name`</summary>
44+
The `llm` configuration defaults are shown below:
45+
46+
```yaml
47+
model_name: anthropic/claude-3-5-sonnet-20240620
48+
scraper_tool_model_name: accounts/fireworks/models/firefunction-v2
49+
```
50+
51+
Follow the instructions below to get set up, or pick one of the additional options.
52+
53+
### Anthropic Chat Models
54+
55+
To use Anthropic's chat models:
56+
57+
1. Sign up for an [Anthropic API key](https://console.anthropic.com/) if you haven't already.
58+
2. Once you have your API key, add it to your `.env` file:
59+
60+
```
61+
ANTHROPIC_API_KEY=your-api-key
62+
```
63+
### Fireworks Chat Models
64+
65+
To use Fireworks AI's chat models:
66+
67+
1. Sign up for a [Fireworks AI account](https://app.fireworks.ai/signup) and obtain an API key.
68+
2. Add your Fireworks AI API key to your `.env` file:
69+
70+
```
71+
FIREWORKS_API_KEY=your-api-key
72+
```
73+
#### OpenAI Chat Models
74+
75+
To use OpenAI's chat models:
76+
77+
1. Sign up for an [OpenAI API key](https://platform.openai.com/signup).
78+
2. Once you have your API key, add it to your `.env` file:
79+
```
80+
OPENAI_API_KEY=your-api-key
2981
```
3082
83+
</details>
84+
85+
86+
87+
<!--
88+
End setup instructions
89+
-->
90+
91+
92+
3. Customize whatever you'd like in the code.
93+
4. Open the folder LangGraph Studio!
94+
95+
## How to customize
96+
97+
1. **Add new tools**: Extend the agent's capabilities by adding new tools in [tools.py](./src/react_agent/tools.py). These can be any Python functions that perform specific tasks.
98+
2. **Select a different model**: We default to Anthropic's Claude 3 Sonnet. You can select a compatible chat model using `provider/model-name` via configuration. Example: `openai/gpt-4-turbo-preview`.
99+
3. **Customize the prompt**: We provide a default system prompt in [configuration.py](./src/react_agent/configuration.py). You can easily update this via configuration in the studio.
100+
101+
You can also quickly extend this template by:
102+
103+
- Modifying the agent's reasoning process in [graph.py](./src/react_agent/graph.py).
104+
- Adjusting the ReAct loop or adding additional steps to the agent's decision-making process.
105+
106+
## Development
107+
108+
While iterating on your graph, you can edit past state and rerun your app from past states to debug specific nodes. Local changes will be automatically applied via hot reload. Try adding an interrupt before the agent calls tools, updating the default system message in `src/react_agent/configuration.py` to take on a persona, or adding additional nodes and edges!
109+
110+
Follow up requests will be appended to the same thread. You can create an entirely new thread, clearing previous history, using the `+` button in the top right.
111+
112+
You can find the latest (under construction) docs on [LangGraph](https://github.com/langchain-ai/langgraph) here, including examples and other references. Using those guides can help you pick the right patterns to adapt here for your use case.
113+
114+
LangGraph Studio also integrates with [LangSmith](https://smith.langchain.com/) for more in-depth tracing and collaboration with teammates.
115+
31116
<!--
32117
Configuration auto-generated by `langgraph template lock`. DO NOT EDIT MANUALLY.
33118
{
@@ -37,7 +122,7 @@ Configuration auto-generated by `langgraph template lock`. DO NOT EDIT MANUALLY.
37122
"properties": {
38123
"system_prompt": {
39124
"type": "string",
40-
"default": "You are a helpful AI assistant.\nSystem time: {system_time}"
125+
"default": "You are a helpful AI assistant.\n\nSystem time: {system_time}"
41126
},
42127
"model_name": {
43128
"type": "string",
@@ -410,9 +495,13 @@ Configuration auto-generated by `langgraph template lock`. DO NOT EDIT MANUALLY.
410495
"variables": "OPENAI_API_KEY"
411496
}
412497
]
498+
},
499+
"max_search_results": {
500+
"type": "integer",
501+
"default": 10
413502
}
414503
}
415504
}
416505
}
417506
}
418-
-->
507+
-->

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ dependencies = [
1515
"langchain>=0.2.14",
1616
"langchain-fireworks>=0.1.7",
1717
"python-dotenv>=1.0.1",
18+
"langchain-community>=0.2.17",
19+
"tavily-python>=0.4.0",
1820
]
1921

2022

@@ -54,5 +56,7 @@ lint.ignore = [
5456
"D417",
5557
"E501",
5658
]
59+
[tool.ruff.lint.per-file-ignores]
60+
"tests/*" = ["D", "UP"]
5761
[tool.ruff.lint.pydocstyle]
5862
convention = "google"

src/react_agent/configuration.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,41 @@
22

33
from __future__ import annotations
44

5-
from dataclasses import dataclass, fields
5+
from dataclasses import dataclass, field, fields
66
from typing import Annotated, Optional
77

88
from langchain_core.runnables import RunnableConfig, ensure_config
99

10+
from react_agent import prompts
11+
1012

1113
@dataclass(kw_only=True)
1214
class Configuration:
1315
"""The configuration for the agent."""
1416

15-
system_prompt: str = "You are a helpful AI assistant.\nSystem time: {system_time}"
17+
system_prompt: str = field(default=prompts.SYSTEM_PROMPT)
18+
"""The system prompt to use for the agent's interactions.
19+
20+
This prompt sets the context and behavior for the agent.
21+
"""
22+
1623
model_name: Annotated[str, {"__template_metadata__": {"kind": "llm"}}] = (
1724
"anthropic/claude-3-5-sonnet-20240620"
1825
)
26+
"""The name of the language model to use for the agent's main interactions.
27+
28+
Should be in the form: provider/model-name.
29+
"""
30+
1931
scraper_tool_model_name: Annotated[
2032
str, {"__template_metadata__": {"kind": "llm"}}
2133
] = "accounts/fireworks/models/firefunction-v2"
34+
"""The name of the language model to use for the web scraping tool.
35+
36+
This model is specifically used for summarizing and extracting information from web pages.
37+
"""
38+
max_search_results: int = 10
39+
"""The maximum number of search results to return for each search query."""
2240

2341
@classmethod
2442
def from_runnable_config(

src/react_agent/graph.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Define a custom Reasoning and Action agent.
1+
"""Define a custom Reasoning and Action agent.
22
33
Works with a chat model with tool calling support.
44
"""

src/react_agent/prompts.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"""Default prompts used by the agent."""
2+
3+
SYSTEM_PROMPT = """You are a helpful AI assistant.
4+
5+
System time: {system_time}"""

0 commit comments

Comments
 (0)