서브에이전트 스트리밍

서브에이전트 스트리밍 (Subagent streaming)

일반 채팅 앱은 단순한 대화 기록만 보여주지만, LangChain 프론트엔드 SDK는 서브에이전트를 독립된 스트림 개체로 다뤄요. 서브에이전트마다 자기 상태, 메시지, 툴 호출 메타데이터, 결과가 따로 있어서, 사용자에게 각 워커의 토큰을 섞어서 보여주지 않아도 위임·진행·오류·최종 종합을 표시할 수 있어요.

출처: 공식문서

셀렉터 기반 서브에이전트 스트림이 좋은 이유

이렇게 오케스트레이터의 메시지는 한 곳에, 서브에이전트 카드는 사용자가 전문가 작업을 볼 필요가 있을 때만 마운트해서 분리해 렌더링할 수 있어요. 각각을 독립적으로 다루니까 UI가 훨씬 깔끔하죠.

useStream 설정하기

코드 예시는 타입 안전한 스트림 상태를 위해 useStream<typeof myAgent>를 사용해요. 타입 추론(Type inference)은 Python 또는 JavaScript 백엔드 문서를 참고하세요.

React:

import { useStream } from "@langchain/react";
import { AIMessage, HumanMessage } from "langchain";

const AGENT_URL = "http://localhost:2024";

export function DeepAgentChat() {
  const stream = useStream<typeof myAgent>({
    apiUrl: AGENT_URL,
    ...

Svelte는 @langchain/svelteuseStream을, Angular는 injectStream<typeof myAgent>을 써요. 각자 apiUrl: AGENT_URL, assistantId: "deep_agent_subagent_cards" 형태로 동일하게 설정해요.

메시지 제출

메시지는 루트 스트림을 통해 제출해요. 딥 에이전트 워크플로는 중첩된 서브그래프가 여러 층이 될 때가 많으니, 에이전트가 깊게 위임할 수 있다면 적절한 재귀 한도(recursion limit)를 설정해 주는 게 좋아요.

stream.submit(
  { messages: [{ type: "human", content: text }] },
  { config: { recursion_limit: 100 } }
);

Deep Agents는 기본 재귀 한도가 10,000이에요. 대부분의 멀티-전문가 구성에 충분하지만, 필요하면 config.recursion_limit으로 덮어쓸 수 있어요.

SubagentDiscoverySnapshot

SubagentDiscoverySnapshot은 스레드 안에서 실행 중인 서브에이전트에 대한 가벼운 디스커버리 레코드예요. 서브에이전트가 존재한다는 것, 서브에이전트 트리에서 어디에 있는지, 어떤 생명주기 상태인지를 UI에 알려줘요.

SubagentCard 만들기

서브에이전트 카드를 만들려면 @langchain/react에서 useMessages, useToolCalls, 그리고 AnyStream, SubagentDiscoverySnapshot 타입을 가져와요.

import { useState } from "react";
import { AIMessage } from "langchain";
import {
  useMessages,
  useToolCalls,
  type AnyStream,
  type SubagentDiscoverySnapshot,
} from "@langchain/react";

function SubagentCard({
  stream,
  ...

더 알아보기 (Learn more)