diff --git a/docs/docs/cloud/concepts/api.md b/docs/docs/cloud/concepts/api.md index 3e5cd0742..f8e948285 100644 --- a/docs/docs/cloud/concepts/api.md +++ b/docs/docs/cloud/concepts/api.md @@ -8,13 +8,26 @@ The LangGraph Cloud API consists of a few core data models: [Assistants](#assist ### Assistants -An assistant is a configured instance of a [`CompiledGraph`][compiledgraph]. It abstracts the cognitive architecture of the graph and contains instance specific configuration and metadata. Multiple assistants can reference the same graph but can contain different configuration and metadata, which may differentiate the behavior of the assistants. An assistant (i.e. the graph) is invoked as part of a run. +When building agents, it is fairly common to make rapid changes that *do not* alter the graph logic. For example, simply changing prompts or the LLM selection can have significant impacts on the behavior of the agents. Assistants offer an easy way to make and save these types of changes to agent configuration. This can have at least two use-cases: -The LangGraph Cloud API provides several endpoints for creating and managing assistants. See the [API reference](../reference/api/api_ref.html#tag/assistantscreate) for more details. +* Assistants give developers a quick and easy way to modify and version graph version for experimentation. +* Assistants can be modified via LangGraph Studio, offering a no-code way to configure agents (e.g., for business users). #### Configuring Assistants -You can save custom assistants from the same graph to set different default prompts, models, and other configurations without changing a line of code in your graph. This allows you the ability to quickly test out different configurations without having to rewrite your graph every time, and also give users the flexibility to select different configurations when using your LangGraph application. See [this how-to](../how-tos/configuration_cloud.md) for information on how to configure a deployed graph. +In practice, an assistant is just an *instance* of a graph with a specific configuration. Because of this, multiple assistants can reference the same graph but can contain different configurations, such as prompts, models, and other graph configuration options. The LangGraph Cloud API provides several endpoints for creating and managing assistants. See the [API reference](../reference/api/api_ref.html#tag/assistantscreate) and [this how-to](../how-tos/configuration_cloud.md) for more details on how to create assistants. + +#### Versioning Assistants + +![assistant versions](./assistant_version.png) + +Once you've created an assistant, you can save and version it to track changes to the configuration over time. You can think about this at three levels: + +1) The graph lays out the general agent application logic +2) The agent configuration options represent parameters that can be changed +3) Assistant versions save and track specific settings of the agent configuration options + +For example, if you have an agent that helps for planning trips, you can create a new assistant *for each user* that passes specific user preferences (e.g., desired airline and car service). As each user interacts with their own assistant, assistant versions can be saved that track the specific desires of the user. Read [this how-to](../how-tos/assistant_versioning.md) to learn how you can use assistant versioning through both the [Studio](../how-tos/index.md/#langgraph-studio) and the SDK. ### Threads diff --git a/docs/docs/cloud/concepts/assistant_version.png b/docs/docs/cloud/concepts/assistant_version.png new file mode 100644 index 000000000..3406673fc Binary files /dev/null and b/docs/docs/cloud/concepts/assistant_version.png differ diff --git a/docs/docs/cloud/how-tos/assistant_versioning.md b/docs/docs/cloud/how-tos/assistant_versioning.md new file mode 100644 index 000000000..3fe4fc7a7 --- /dev/null +++ b/docs/docs/cloud/how-tos/assistant_versioning.md @@ -0,0 +1,183 @@ +# How to version assistants + +In this how-to guide we will walk through how you can create and manage different assistant versions. If you haven't already, you can read [this](../concepts/api.md/#versioning-assistants) conceptual guide to gain a better understanding of what assistant versioning is. This how-to assumes you have a graph that is configurable, which means you have defined a config schema and passed it to your graph as follows: + +=== "Python" + + ```python + class Config(BaseModel): + model_name: Literal["anthropic", "openai"] = "anthropic" + system_prompt: str + + agent = StateGraph(State, config_schema=Config) + ``` + +=== "Javascript" + + ```js + const ConfigAnnotation = Annotation.Root({ + modelName: Annotation({ + default: () => "anthropic", + }), + systemPrompt: Annotation + }); + + // the rest of your code + + const agent = new StateGraph(StateAnnotation, ConfigAnnotation); + ``` + +## Setup + +First let's set up our client and thread. If you are using the Studio, just open the application to the graph called "agent". If using cURL, you don't need to do anything except copy down your deployment URL and the name of the graph you want to use. + +=== "Python" + + ```python + from langgraph_sdk import get_client + + client = get_client(url=) + # Using the graph deployed with the name "agent" + graph_name = "agent" + ``` + +=== "Javascript" + + ```js + import { Client } from "@langchain/langgraph-sdk"; + + const client = new Client({ apiUrl: }); + // Using the graph deployed with the name "agent" + const graphName = "agent"; + ``` + +## Create an assistant + +For this example, we will create an assistant by modifying the model name that is used in our graph. We can create a new assistant called "openai_assistant" for this: + +=== "Python" + + ```python + openai_assistant = await client.assistants.create(graph_name, config={"configurable": {"model_name": "openai"}}, name="openai_assistant") + ``` + +=== "Javascript" + + ```js + const openaiAssistant = await client.assistants.create({graphId: graphName, config: { configurable: {"modelName": "openai"}}, name: "openaiAssistant"}); + ``` + +=== "CURL" + + ```bash + curl --request POST \ + --url /assistants \ + --header 'Content-Type: application/json' \ + --data '{ + "graph_id": "agent", + "config": {"model_name": "openai"}, + "name": "openai_assistant" + }' + ``` + +### Using the studio + +To create an assistant using the studio do the following steps: + +1. Click on the "Create New Assistant" button: + +![click create](./img/click_create_assistant.png) + +2. Use the create assistant pane to enter info for the assistant you wish to create, and then click create: + +![create](./img/create_assistant.png) + +3. See that your assistant was created and is displayed in the Studio + +![view create](./img/create_assistant_view.png) + +4. Click on the edit button next to the selected assistant to manage your created assistant: + +![create edit](./img/edit_created_assistant.png) + +## Create a new version for your assistant + +Let's now say we wanted to add a system prompt to our assistant. We can do this by using the `update` endpoint as follows. Please note that you must pass in the ENTIRE config (and metadata if you are using it). The update endpoint creates new versions completely from scratch and does not rely on previously entered config. In this case, we need to continue telling the assistant to use "openai" as the model. + +=== "Python" + + ```python + openai_assistant_v2 = await client.assistants.update(openai_assistant['assistant_id'], config={"configurable": {"model_name": "openai", "system_prompt": "You are a helpful assistant!"}}) + ``` + +=== "Javascript" + + ```js + const openaiAssistantV2 = await client.assistants.update(openaiAssistant['assistant_id'], {config: { configurable: {"modelName": "openai", "systemPrompt": "You are a helpful assistant!"}}}); + ``` + +=== "CURL" + + ```bash + curl --request PATCH \ + --url /assistants/ \ + --header 'Content-Type: application/json' \ + --data '{ + "config": {"model_name": "openai", "system_prompt": "You are a helpful assistant!"} + }' + ``` + +### Using the studio + +1. First, click on the edit button next to the `openai_assistant`. Then, add a system prompt and click "Save New Version": + +![create new version](./img/create_new_version.png) + +2. Then you can see it is selected in the assistant dropdown: + +![see version dropdown](./img/see_new_version.png) + +3. And you can see all the version history in the edit pane for the assistant: + +![see versions](./img/see_version_history.png) + +## Point your assistant to a different version + +After having created multiple versions, we can change the version our assistant points to both by using the SDK and also the Studio. In this case we will be resetting the `openai_assistant` we just created two versions for to point back to the first version. When you create a new version (by using the `update` endpoint) the assistant automatically points to the newly created version, so following the code above our `openai_assistant` is pointing to the second version. Here we will change it to point to the first version: + +=== "Python" + + ```python + await client.assistants.set_latest(openai_assistant['assistant_id'], 1) + ``` + +=== "Javascript" + + ```js + await client.assistants.setLatest(openaiAssistant['assistant_id'], 1); + ``` + +=== "CURL" + + ```bash + curl --request POST \ + --url /assistants//latest \ + --header 'Content-Type: application/json' \ + --data '{ + "version": 1 + }' + ``` + + +### Using the studio + +To change the version, all you have to do is click into the edit pane for an assistant, select the version you want to change to, and then click the "Set As Current Version" button + +![set version](./img/select_different_version.png) + +## Using your assistant versions + +Whether you are a business user iterating without writing code, or a developer using the SDK - assistant versioning allows you to quickly test different agents in a controlled environment, making it easy to iterate fast. You can use any of the assistant versions just how you would a normal assistant, and can read more about how to stream output from these assistants by reading [these guides](https://langchain-ai.github.io/langgraph/cloud/how-tos/#streaming) or [this one](https://langchain-ai.github.io/langgraph/cloud/how-tos/invoke_studio/) if you are using the Studio. + +!!! warning "Deleting Assistants" + Deleting as assistant will delete ALL of it's versions, since they all point to the same assistant ID. There is currently no way to just delete a single version, but by pointing your assistant to the correct version you can skip any versions that you don't wish to use. \ No newline at end of file diff --git a/docs/docs/cloud/how-tos/img/click_create_assistant.png b/docs/docs/cloud/how-tos/img/click_create_assistant.png new file mode 100644 index 000000000..74da8f160 Binary files /dev/null and b/docs/docs/cloud/how-tos/img/click_create_assistant.png differ diff --git a/docs/docs/cloud/how-tos/img/create_assistant.png b/docs/docs/cloud/how-tos/img/create_assistant.png new file mode 100644 index 000000000..e80f14733 Binary files /dev/null and b/docs/docs/cloud/how-tos/img/create_assistant.png differ diff --git a/docs/docs/cloud/how-tos/img/create_assistant_view.png b/docs/docs/cloud/how-tos/img/create_assistant_view.png new file mode 100644 index 000000000..5cdbc098e Binary files /dev/null and b/docs/docs/cloud/how-tos/img/create_assistant_view.png differ diff --git a/docs/docs/cloud/how-tos/img/create_new_version.png b/docs/docs/cloud/how-tos/img/create_new_version.png new file mode 100644 index 000000000..75be4b5f3 Binary files /dev/null and b/docs/docs/cloud/how-tos/img/create_new_version.png differ diff --git a/docs/docs/cloud/how-tos/img/edit_created_assistant.png b/docs/docs/cloud/how-tos/img/edit_created_assistant.png new file mode 100644 index 000000000..75b18cdc1 Binary files /dev/null and b/docs/docs/cloud/how-tos/img/edit_created_assistant.png differ diff --git a/docs/docs/cloud/how-tos/img/see_new_version.png b/docs/docs/cloud/how-tos/img/see_new_version.png new file mode 100644 index 000000000..3a7596914 Binary files /dev/null and b/docs/docs/cloud/how-tos/img/see_new_version.png differ diff --git a/docs/docs/cloud/how-tos/img/see_version_history.png b/docs/docs/cloud/how-tos/img/see_version_history.png new file mode 100644 index 000000000..b956de5d4 Binary files /dev/null and b/docs/docs/cloud/how-tos/img/see_version_history.png differ diff --git a/docs/docs/cloud/how-tos/img/select_different_version.png b/docs/docs/cloud/how-tos/img/select_different_version.png new file mode 100644 index 000000000..284d33456 Binary files /dev/null and b/docs/docs/cloud/how-tos/img/select_different_version.png differ diff --git a/docs/docs/cloud/how-tos/index.md b/docs/docs/cloud/how-tos/index.md index 2cd943355..56cd7e925 100644 --- a/docs/docs/cloud/how-tos/index.md +++ b/docs/docs/cloud/how-tos/index.md @@ -77,6 +77,7 @@ LangGraph Cloud supports multiple types of runs besides streaming runs. Other guides that may prove helpful! - [How to configure agents](./configuration_cloud.md) +- [How to version assistants](./assistant_versioning.md) - [How to convert LangGraph calls to LangGraph cloud calls](./langgraph_to_langgraph_cloud.ipynb) - [How to integrate webhooks](./webhooks.md) - [How to copy threads](./copy_threads.md) diff --git a/docs/docs/cloud/reference/api/openapi.json b/docs/docs/cloud/reference/api/openapi.json index 97367b5b2..e52bfa301 100644 --- a/docs/docs/cloud/reference/api/openapi.json +++ b/docs/docs/cloud/reference/api/openapi.json @@ -334,6 +334,113 @@ } } }, + "/assistants/{assistant_id}/versions": { + "post": { + "tags": [ + "assistants/manage" + ], + "summary": "Get Assistant Versions", + "description": "Get all versions of an assistant.", + "operationId": "get_assistant_versions_assistants__assistant_id__versions_get", + "parameters": [ + { + "description": "The ID of the assistant.", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Assistant Id", + "description": "The ID of the assistant." + }, + "name": "assistant_id", + "in": "path" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/Assistant" + }, + "type": "array", + "title": "Response Search Assistants Assistants Search Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/assistants/{assistant_id}/change_version": { + "post": { + "tags": [ + "assistants/manage" + ], + "summary": "Change Assistant Version", + "description": "Change the version of an assistant.", + "operationId": "change_assistant_version__assistant_id__change_version__version_post", + "parameters": [ + { + "description": "The ID of the assistant.", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Assistant Id", + "description": "The ID of the assistant." + }, + "name": "assistant_id", + "in": "path" + }, + { + "description": "The version to change to.", + "required": true, + "schema": { + "type": "integer", + "title": "Version", + "description": "The version of the assistant to change to." + }, + "name": "version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Assistant" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, "/threads": { "post": { "tags": [ @@ -1760,6 +1867,14 @@ "metadata": { "type": "object", "title": "Metadata" + }, + "version": { + "type": "integer", + "title": "Version" + }, + "name": { + "type": "string", + "title": "Assistant Name" } }, "type": "object", @@ -1820,12 +1935,29 @@ "type": "object", "title": "Metadata", "description": "Metadata to merge with existing assistant metadata." + }, + "name": { + "type": "string", + "title": "Assistant Name", + "description": "The assistant name." } }, "type": "object", "title": "AssistantPatch", "description": "Payload for updating an assistant." }, + "AssistantVersionChange": { + "properties": { + "version": { + "type": "integer", + "title": "Version", + "description": "The assistant version." + } + }, + "type": "object", + "title": "AssistantVersionChange", + "description": "Payload for changing the version of an assistant." + }, "Config": { "properties": { "tags": { @@ -2268,7 +2400,8 @@ "messages", "updates", "events", - "debug" + "debug", + "custom" ] }, "type": "array" @@ -2280,7 +2413,8 @@ "messages", "updates", "events", - "debug" + "debug", + "custom" ] } ], @@ -2315,6 +2449,11 @@ ], "title": "Multitask Strategy", "default": "reject" + }, + "after_seconds": { + "type": "integer", + "title": "After Seconds", + "description": "Number of seconds to wait before starting the run." } }, "type": "object", @@ -2442,7 +2581,8 @@ "messages", "updates", "events", - "debug" + "debug", + "custom" ] }, "type": "array" @@ -2454,7 +2594,8 @@ "messages", "updates", "events", - "debug" + "debug", + "custom" ] } ], @@ -2487,6 +2628,11 @@ ], "title": "On Disconnect", "default": "cancel" + }, + "after_seconds": { + "type": "integer", + "title": "After Seconds", + "description": "Number of seconds to wait before starting the run." } }, "type": "object", @@ -2555,6 +2701,33 @@ "title": "SearchRequest", "description": "Payload for listing assistants." }, + "AssistantVersionsSearchRequest": { + "properties": { + "metadata": { + "type": "object", + "title": "Metadata", + "description": "Metadata to search for." + }, + "limit": { + "type": "integer", + "title": "Limit", + "description": "Maximum number to return.", + "default": 10, + "minimum": 1, + "maximum": 1000 + }, + "offset": { + "type": "integer", + "title": "Offset", + "description": "Offset to start from.", + "default": 0, + "minimum": 0 + } + }, + "type": "object", + "title": "SearchRequest", + "description": "Payload for listing assistant versions." + }, "ThreadSearchRequest": { "properties": { "metadata": { @@ -2859,4 +3032,4 @@ } } } -} \ No newline at end of file +} diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index b91d8034a..0e07c8d6e 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -247,6 +247,7 @@ nav: - Create Stateless Runs: "cloud/how-tos/stateless_runs.md" - Other: - Configure Agents: "cloud/how-tos/configuration_cloud.md" + - Versioning Assistants: "cloud/how-tos/assistant_versioning.md" - Convert LangGraph calls to LangGraph Cloud calls: "cloud/how-tos/langgraph_to_langgraph_cloud.ipynb" - Integrate Webhooks: 'cloud/how-tos/webhooks.md' - Copy Threads: 'cloud/how-tos/copy_threads.md'