Skip to main content
많은 AI 애플리케이션은 자연어를 통해 사용자와 상호작용합니다. 그러나 일부 사용 사례에서는 모델이 API, 데이터베이스 또는 파일 시스템과 같은 외부 시스템과 구조화된 입력을 사용하여 직접 인터페이스해야 합니다. 도구는 에이전트가 작업을 수행하기 위해 호출하는 구성 요소입니다. 도구는 잘 정의된 입력과 출력을 통해 모델이 외부 세계와 상호작용할 수 있도록 하여 모델의 기능을 확장합니다. 도구는 호출 가능한 함수와 해당 입력 스키마를 캡슐화합니다. 이러한 도구는 호환되는 챗 모델에 전달될 수 있으며, 모델이 도구를 호출할지 여부와 어떤 인수로 호출할지 결정할 수 있게 합니다. 이러한 시나리오에서 도구 호출은 모델이 지정된 입력 스키마에 부합하는 요청을 생성할 수 있도록 합니다.
서버 측 도구 사용일부 챗 모델(예: OpenAI, Anthropic, Gemini)은 웹 검색 및 코드 인터프리터와 같이 서버 측에서 실행되는 내장 도구를 제공합니다. 특정 챗 모델에서 이러한 도구에 액세스하는 방법을 알아보려면 프로바이더 개요를 참조하세요.

도구 생성

기본 도구 정의

도구를 생성하는 가장 간단한 방법은 langchain 패키지에서 tool 함수를 가져오는 것입니다. zod를 사용하여 도구의 입력 스키마를 정의할 수 있습니다:
import * as z from "zod"
import { tool } from "langchain"

const searchDatabase = tool(
  ({ query, limit }) => `Found ${limit} results for '${query}'`,
  {
    name: "search_database",
    description: "Search the customer database for records matching the query.",
    schema: z.object({
      query: z.string().describe("Search terms to look for"),
      limit: z.number().describe("Maximum number of results to return"),
    }),
  }
);

컨텍스트 액세스

중요한 이유: 도구는 에이전트 상태, 런타임 컨텍스트 및 장기 메모리에 액세스할 수 있을 때 가장 강력합니다. 이를 통해 도구는 컨텍스트 인식 의사 결정을 내리고 응답을 개인화하며 대화 전반에 걸쳐 정보를 유지할 수 있습니다.
도구는 ToolRuntime 매개변수를 통해 런타임 정보에 액세스할 수 있으며, 다음을 제공합니다:
  • State - 실행 과정에서 흐르는 변경 가능한 데이터(메시지, 카운터, 사용자 정의 필드)
  • Context - 사용자 ID, 세션 세부 정보 또는 애플리케이션별 구성과 같은 불변 구성
  • Store - 대화 전반에 걸친 영구 장기 메모리
  • Stream Writer - 도구 실행 시 사용자 정의 업데이트 스트리밍
  • Config - 실행을 위한 RunnableConfig
  • Tool Call ID - 현재 도구 호출의 ID

ToolRuntime

ToolRuntime을 사용하여 단일 매개변수로 모든 런타임 정보에 액세스할 수 있습니다. 도구 시그니처에 runtime: ToolRuntime을 추가하기만 하면 LLM에 노출되지 않고 자동으로 주입됩니다.
ToolRuntime: 도구가 state, context, store, streaming, config 및 tool call ID에 액세스할 수 있도록 하는 통합 매개변수입니다. 이는 별도의 @[InjectedState], @[InjectedStore], @[get_runtime], @[InjectedToolCallId] 어노테이션을 사용하는 이전 패턴을 대체합니다.

Context

runtime.context를 통해 사용자 ID, 세션 세부 정보 또는 애플리케이션별 구성과 같은 불변 구성 및 컨텍스트 데이터에 액세스할 수 있습니다. 도구는 config 매개변수를 통해 에이전트의 런타임 컨텍스트에 액세스할 수 있습니다:
import * as z from "zod"
import { ChatOpenAI } from "@langchain/openai"
import { createAgent } from "langchain"

const getUserName = tool(
  (_, config) => {
    return config.context.user_name
  },
  {
    name: "get_user_name",
    description: "Get the user's name.",
    schema: z.object({}),
  }
);

const contextSchema = z.object({
  user_name: z.string(),
});

const agent = createAgent({
  model: new ChatOpenAI({ model: "gpt-4o" }),
  tools: [getUserName],
  contextSchema,
});

const result = await agent.invoke(
  {
    messages: [{ role: "user", content: "What is my name?" }]
  },
  {
    context: { user_name: "John Smith" }
  }
);

메모리 (Store)

store를 사용하여 대화 전반에 걸쳐 영구 데이터에 액세스할 수 있습니다. store는 runtime.store를 통해 액세스되며 사용자별 또는 애플리케이션별 데이터를 저장하고 검색할 수 있습니다.
import * as z from "zod";
import { createAgent, tool } from "langchain";
import { InMemoryStore } from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";

const store = new InMemoryStore();

// 메모리 액세스
const getUserInfo = tool(
  async ({ user_id }) => {
    const value = await store.get(["users"], user_id);
    console.log("get_user_info", user_id, value);
    return value;
  },
  {
    name: "get_user_info",
    description: "Look up user info.",
    schema: z.object({
      user_id: z.string(),
    }),
  }
);

// 메모리 업데이트
const saveUserInfo = tool(
  async ({ user_id, name, age, email }) => {
    console.log("save_user_info", user_id, name, age, email);
    await store.put(["users"], user_id, { name, age, email });
    return "Successfully saved user info.";
  },
  {
    name: "save_user_info",
    description: "Save user info.",
    schema: z.object({
      user_id: z.string(),
      name: z.string(),
      age: z.number(),
      email: z.string(),
    }),
  }
);

const agent = createAgent({
  model: new ChatOpenAI({ model: "gpt-4o" }),
  tools: [getUserInfo, saveUserInfo],
  store,
});

// 첫 번째 세션: 사용자 정보 저장
await agent.invoke({
  messages: [
    {
      role: "user",
      content: "Save the following user: userid: abc123, name: Foo, age: 25, email: [email protected]",
    },
  ],
});

// 두 번째 세션: 사용자 정보 가져오기
const result = await agent.invoke({
  messages: [
    { role: "user", content: "Get user info for user with id 'abc123'" },
  ],
});

console.log(result);
// Here is the user info for user with ID "abc123":
// - Name: Foo
// - Age: 25
// - Email: [email protected]

Stream Writer

runtime.stream_writer를 사용하여 도구가 실행되는 동안 사용자 정의 업데이트를 스트리밍할 수 있습니다. 이는 도구가 수행하는 작업에 대한 실시간 피드백을 사용자에게 제공하는 데 유용합니다.
import * as z from "zod";
import { tool } from "langchain";

const getWeather = tool(
  ({ city }, config) => {
    const writer = config.streamWriter;

    // 도구가 실행되는 동안 사용자 정의 업데이트 스트리밍
    writer(`Looking up data for city: ${city}`);
    writer(`Acquired data for city: ${city}`);

    return `It's always sunny in ${city}!`;
  },
  {
    name: "get_weather",
    description: "Get weather for a given city.",
    schema: z.object({
      city: z.string(),
    }),
  }
);

Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I