LangSmith에 배포하거나 자체 호스팅하려면 애플리케이션이 configuration file로 구성되어야 합니다. 이 가이드에서는 package.json을 사용하여 프로젝트 종속성을 지정하고 JavaScript 애플리케이션을 배포용으로 설정하는 기본 단계를 설명합니다.
이 가이드는 이 repository를 기반으로 하며, 배포를 위한 애플리케이션 설정 방법에 대해 자세히 알아보려면 이 repository를 살펴보실 수 있습니다.
최종 repository 구조는 다음과 같습니다:
my-app/
├── src # all project code lies within here
│ ├── utils # optional utilities for your graph
│ │ ├── tools.ts # tools for your graph
│ │ ├── nodes.ts # node functions for your graph
│ │ └── state.ts # state definition of your graph
│ └── agent.ts # code for constructing your graph
├── package.json # package dependencies
├── .env # environment variables
└── langgraph.json # configuration file for LangGraph
LangSmith Deployment는 LangGraph graph 배포를 지원합니다. 그러나 graph의 node 구현에는 임의의 Python 코드가 포함될 수 있습니다. 이는 node 내에서 모든 프레임워크를 구현하고 LangSmith Deployment에 배포할 수 있음을 의미합니다. 이를 통해 핵심 애플리케이션 로직을 LangGraph 외부에 유지하면서도 배포, 확장 및 관찰 가능성을 위해 LangSmith를 계속 사용할 수 있습니다.
각 단계 후에 코드를 구성하는 방법을 보여주는 예제 파일 디렉토리가 제공됩니다.
종속성 지정
종속성은 package.json에 지정할 수 있습니다. 이러한 파일이 생성되지 않은 경우, 나중에 configuration file에서 종속성을 지정할 수 있습니다.
예제 package.json 파일:
{
"name": "langgraphjs-studio-starter",
"packageManager": "[email protected]",
"dependencies": {
"@langchain/community": "^0.2.31",
"@langchain/core": "^0.2.31",
"@langchain/langgraph": "^0.2.0",
"@langchain/openai": "^0.2.8"
}
}
앱을 배포할 때, 아래 나열된 호환 가능한 버전 범위를 준수하는 경우 선택한 package manager를 사용하여 종속성이 설치됩니다:
"@langchain/core": "^0.3.42",
"@langchain/langgraph": "^0.2.57",
"@langchain/langgraph-checkpoint": "~0.0.16",
예제 파일 디렉토리:
my-app/
└── package.json # package dependencies
환경 변수 지정
환경 변수는 선택적으로 파일(예: .env)에 지정할 수 있습니다. 배포를 위한 추가 변수를 구성하려면 Environment Variables reference를 참조하세요.
예제 .env 파일:
MY_ENV_VAR_1=foo
MY_ENV_VAR_2=bar
OPENAI_API_KEY=key
TAVILY_API_KEY=key_2
예제 파일 디렉토리:
my-app/
├── package.json
└── .env # environment variables
Graph 정의
graph를 구현합니다. Graph는 단일 파일 또는 여러 파일에 정의할 수 있습니다. 애플리케이션에 포함될 각 compiled graph의 변수 이름을 기록해 두세요. 변수 이름은 나중에 configuration file을 생성할 때 사용됩니다.
다음은 예제 agent.ts입니다:
import type { AIMessage } from "@langchain/core/messages";
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
import { ChatOpenAI } from "@langchain/openai";
import { MessagesAnnotation, StateGraph } from "@langchain/langgraph";
import { ToolNode } from "@langchain/langgraph/prebuilt";
const tools = [new TavilySearchResults({ maxResults: 3 })];
// Define the function that calls the model
async function callModel(state: typeof MessagesAnnotation.State) {
/**
* Call the LLM powering our agent.
* Feel free to customize the prompt, model, and other logic!
*/
const model = new ChatOpenAI({
model: "gpt-4o",
}).bindTools(tools);
const response = await model.invoke([
{
role: "system",
content: `You are a helpful assistant. The current date is ${new Date().getTime()}.`,
},
...state.messages,
]);
// MessagesAnnotation supports returning a single message or array of messages
return { messages: response };
}
// Define the function that determines whether to continue or not
function routeModelOutput(state: typeof MessagesAnnotation.State) {
const messages = state.messages;
const lastMessage: AIMessage = messages[messages.length - 1];
// If the LLM is invoking tools, route there.
if ((lastMessage?.tool_calls?.length ?? 0) > 0) {
return "tools";
}
// Otherwise end the graph.
return "__end__";
}
// Define a new graph.
// See https://langchain-ai.github.io/langgraphjs/how-tos/define-state/#getting-started for
// more on defining custom graph states.
const workflow = new StateGraph(MessagesAnnotation)
// Define the two nodes we will cycle between
.addNode("callModel", callModel)
.addNode("tools", new ToolNode(tools))
// Set the entrypoint as `callModel`
// This means that this node is the first one called
.addEdge("__start__", "callModel")
.addConditionalEdges(
// First, we define the edges' source node. We use `callModel`.
// This means these are the edges taken after the `callModel` node is called.
"callModel",
// Next, we pass in the function that will determine the sink node(s), which
// will be called after the source node is called.
routeModelOutput,
// List of the possible destinations the conditional edge can route to.
// Required for conditional edges to properly render the graph in Studio
["tools", "__end__"]
)
// This means that after `tools` is called, `callModel` node is called next.
.addEdge("tools", "callModel");
// Finally, we compile it!
// This compiles it into a graph you can invoke and deploy.
export const graph = workflow.compile();
예제 파일 디렉토리:
my-app/
├── src # all project code lies within here
│ ├── utils # optional utilities for your graph
│ │ ├── tools.ts # tools for your graph
│ │ ├── nodes.ts # node functions for your graph
│ │ └── state.ts # state definition of your graph
│ └── agent.ts # code for constructing your graph
├── package.json # package dependencies
├── .env # environment variables
└── langgraph.json # configuration file for LangGraph
API Config 생성
langgraph.json이라는 configuration file을 생성합니다. configuration file의 JSON 객체에 있는 각 키에 대한 자세한 설명은 configuration file reference를 참조하세요.
예제 langgraph.json 파일:
{
"node_version": "20",
"dockerfile_lines": [],
"dependencies": ["."],
"graphs": {
"agent": "./src/agent.ts:graph"
},
"env": ".env"
}
CompiledGraph의 변수 이름이 최상위 graphs 키의 각 하위 키 값 끝에 나타납니다(즉, :<variable_name>).
Configuration 위치
configuration file은 compiled graph와 관련 종속성을 포함하는 TypeScript 파일과 같은 수준이거나 더 높은 수준의 디렉토리에 배치되어야 합니다.
다음 단계
프로젝트를 설정하고 GitHub repository에 배치한 후에는 앱을 배포할 차례입니다.