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에 배치한 후에는 앱을 배포할 차례입니다.
Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I