Skip to main content

개요

LangChain의 createAgent는 내부적으로 LangGraph의 런타임에서 실행됩니다. LangGraph는 다음과 같은 정보를 포함하는 Runtime 객체를 제공합니다:
  1. Context: 사용자 ID, 데이터베이스 연결 또는 에이전트 호출을 위한 기타 종속성과 같은 정적 정보
  2. Store: 장기 메모리에 사용되는 BaseStore 인스턴스
  3. Stream writer: "custom" 스트림 모드를 통해 정보를 스트리밍하는 데 사용되는 객체
런타임 정보는 도구미들웨어 내에서 접근할 수 있습니다.

접근

createAgent를 사용하여 에이전트를 생성할 때, 에이전트 Runtime에 저장된 context의 구조를 정의하기 위해 contextSchema를 지정할 수 있습니다. 에이전트를 호출할 때는 실행에 필요한 관련 구성과 함께 context 인수를 전달합니다:
import * as z from "zod";
import { createAgent } from "langchain";

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

const agent = createAgent({
  model: "openai:gpt-4o",
  tools: [
    /* ... */
  ],
  contextSchema, 
});

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

도구 내부에서

도구 내부에서 런타임 정보에 접근하여 다음을 수행할 수 있습니다:
  • 컨텍스트 접근
  • 장기 메모리 읽기 또는 쓰기
  • 커스텀 스트림에 쓰기 (예: 도구 진행 상황 / 업데이트)
도구 내부에서 Runtime 객체에 접근하려면 runtime 매개변수를 사용하세요.
import * as z from "zod";
import { tool } from "langchain";
import { type Runtime } from "@langchain/langgraph"; 

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

const fetchUserEmailPreferences = tool(
  async (_, runtime: Runtime<z.infer<typeof contextSchema>>) => { 
    const userName = runtime.context?.userName; 
    if (!userName) {
      throw new Error("userName is required");
    }

    let preferences = "The user prefers you to write a brief and polite email.";
    if (runtime.store) { 
      const memory = await runtime.store?.get(["users"], userName); 
      if (memory) {
        preferences = memory.value.preferences;
      }
    }
    return preferences;
  },
  {
    name: "fetch_user_email_preferences",
    description: "Fetch the user's email preferences.",
    schema: z.object({}),
  }
);

미들웨어 내부에서

미들웨어에서 런타임 정보에 접근하여 동적 프롬프트를 생성하거나, 메시지를 수정하거나, 사용자 컨텍스트를 기반으로 에이전트 동작을 제어할 수 있습니다. 미들웨어 내부에서 Runtime 객체에 접근하려면 runtime 매개변수를 사용하세요.
import * as z from "zod";
import { createAgent, createMiddleware, type AgentState, SystemMessage } from "langchain";
import { type Runtime } from "@langchain/langgraph"; 

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

// 동적 프롬프트 미들웨어
const dynamicPromptMiddleware = createMiddleware({
  name: "DynamicPrompt",
  beforeModel: (state: AgentState, runtime: Runtime<z.infer<typeof contextSchema>>) => {  
    const userName = runtime.context?.userName;  
    if (!userName) {
      throw new Error("userName is required");
    }

    const systemMsg = `You are a helpful assistant. Address the user as ${userName}.`;
    return {
      messages: [new SystemMessage(systemMsg), ...state.messages]
    };
  }
});

// 로깅 미들웨어
const loggingMiddleware = createMiddleware({
  name: "Logging",
  beforeModel: (state: AgentState, runtime: Runtime<z.infer<typeof contextSchema>>) => {  
    console.log(`Processing request for user: ${runtime.context?.userName}`);  
    return;
  },
  afterModel: (state: AgentState, runtime: Runtime<z.infer<typeof contextSchema>>) => {  
    console.log(`Completed request for user: ${runtime.context?.userName}`);  
    return;
  }
});

const agent = createAgent({
  model: "openai:gpt-4o",
  tools: [
    /* ... */
  ],
  middleware: [dynamicPromptMiddleware, loggingMiddleware],  
  contextSchema,
});

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

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