-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
34 changed files
with
185 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: Check File Size | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
branches: | ||
- main | ||
workflow_dispatch: | ||
|
||
jobs: | ||
file-size-check: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Get changed files | ||
id: changed-files | ||
uses: tj-actions/changed-files@v44 | ||
- name: Filter by size | ||
run: | | ||
large_added_files=$(find ${{ steps.changed-files.outputs.added_files }} -maxdepth 0 -size +1M) | ||
if [ -n "$large_added_files" ]; then | ||
echo "Large files added: $large_added_files" | ||
echo "# Large files added:" >> $GITHUB_STEP_SUMMARY | ||
echo "$large_added_files" >> $GITHUB_STEP_SUMMARY | ||
exit 1 | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Rebuild Graph at Runtime | ||
|
||
You might need to rebuild your graph with a different configuration for a new run. For example, you might need to use a different graph state or graph structure depending on the config. This guide shows how you can do this. | ||
|
||
!!! note "Note" | ||
In most cases, customizing behavior based on the config should be handled by a single graph where each node can read a config and change its behavior based on it | ||
|
||
## Prerequisites | ||
|
||
Make sure to check out [this how-to guide](./setup.md) on setting up your app for deployment first. | ||
|
||
## Define graphs | ||
|
||
Let's say you have an app with a simple graph that calls an LLM and returns the response to the user. The app file directory looks like the following: | ||
|
||
``` | ||
my-app/ | ||
|-- requirements.txt | ||
|-- .env | ||
|-- openai_agent.py # code for your graph | ||
``` | ||
|
||
where the graph is defined in `openai_agent.py`. | ||
|
||
### No rebuild | ||
|
||
In the standard LangGraph API configuration, the server uses the compiled graph instance that's defined at the top level of `openai_agent.py`, which looks like the following: | ||
|
||
```python | ||
from langchain_openai import ChatOpenAI | ||
from langgraph.graph import END, MessageGraph | ||
|
||
model = ChatOpenAI(temperature=0) | ||
|
||
graph_workflow = MessageGraph() | ||
|
||
graph_workflow.add_node("agent", model) | ||
graph_workflow.add_edge("agent", END) | ||
graph_workflow.set_entry_point("agent") | ||
|
||
agent = graph_workflow.compile() | ||
``` | ||
|
||
To make the server aware of your graph, you need to specify a path to the variable that contains the `CompiledStateGraph` instance in your LangGraph API configuration (`langgraph.json`), e.g.: | ||
|
||
``` | ||
{ | ||
"dependencies": ["."], | ||
"graphs": { | ||
"openai_agent": "./openai_agent.py:agent", | ||
}, | ||
"env": "./.env" | ||
} | ||
``` | ||
|
||
### Rebuild | ||
|
||
To make your graph rebuild on each new run with custom configuration, you need to rewrite `openai_agent.py` to instead provide a _function_ that takes a config and returns a graph (or compiled graph) instance. Let's say we want to return our existing graph for user ID '1', and a tool-calling agent for other users. We can modify `openai_agent.py` as follows: | ||
|
||
```python | ||
from typing import Annotated, TypedDict | ||
from langchain_openai import ChatOpenAI | ||
from langgraph.graph import END, MessageGraph | ||
from langgraph.graph.state import StateGraph | ||
from langgraph.graph.message import add_messages | ||
from langgraph.prebuilt import ToolNode | ||
from langchain_core.tools import tool | ||
from langchain_core.messages import BaseMessage | ||
from langchain_core.runnables import RunnableConfig | ||
|
||
|
||
class State(TypedDict): | ||
messages: Annotated[list[BaseMessage], add_messages] | ||
|
||
|
||
model = ChatOpenAI(temperature=0) | ||
|
||
def make_default_graph(): | ||
"""Make a simple LLM agent""" | ||
graph_workflow = StateGraph(State) | ||
def call_model(state): | ||
return {"messages": [model.invoke(state["messages"])]} | ||
|
||
graph_workflow.add_node("agent", call_model) | ||
graph_workflow.add_edge("agent", END) | ||
graph_workflow.set_entry_point("agent") | ||
|
||
agent = graph_workflow.compile() | ||
return agent | ||
|
||
|
||
def make_alternative_graph(): | ||
"""Make a tool-calling agent""" | ||
|
||
@tool | ||
def add(a: float, b: float): | ||
"""Adds two numbers.""" | ||
return a + b | ||
|
||
tool_node = ToolNode([add]) | ||
model_with_tools = model.bind_tools([add]) | ||
def call_model(state): | ||
return {"messages": [model_with_tools.invoke(state["messages"])]} | ||
|
||
def should_continue(state: State): | ||
if state["messages"][-1].tool_calls: | ||
return "tools" | ||
else: | ||
return END | ||
|
||
graph_workflow = StateGraph(State) | ||
|
||
graph_workflow.add_node("agent", call_model) | ||
graph_workflow.add_node("tools", tool_node) | ||
graph_workflow.add_edge("tools", "agent") | ||
graph_workflow.set_entry_point("agent") | ||
graph_workflow.add_conditional_edges("agent", should_continue) | ||
|
||
agent = graph_workflow.compile() | ||
return agent | ||
|
||
|
||
# this is the graph making function that will decide which graph to | ||
# build based on the provided config | ||
def make_graph(config: RunnableConfig): | ||
user_id = config.get("configurable", {}).get("user_id") | ||
# route to different graph state / structure based on the user ID | ||
if user_id == "1": | ||
return make_default_graph() | ||
else: | ||
return make_alternative_graph() | ||
``` | ||
|
||
Finally, you need to specify the path to your graph-making function (`make_graph`) in `langgraph.json`: | ||
|
||
``` | ||
{ | ||
"dependencies": ["."], | ||
"graphs": { | ||
"openai_agent": "./openai_agent.py:make_graph", | ||
}, | ||
"env": "./.env" | ||
} | ||
``` | ||
|
||
See more info on LangGraph API configuration file [here](../reference/cli.md#configuration-file) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
-95.9 KB
(32%)
examples/chatbot-simulation-evaluation/img/virtual_user_diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.