본문으로 건너뛰기

프레임워크 비종속 프로액티브 에이전트 SDK 'proactivity' (LangGraph 래핑)

이 프로젝트는 LangGraph 에이전트를 래핑해 지속 목표 관리, 리플렉션 기반 스케줄링, 멱등성·감사 거버넌스를 제공하는 TypeScript SDK이다.

이 요약은 AI가 원문을 분석해 생성했습니다. 정확한 내용은 원문 기준으로 확인하세요.

TL;DR

이 글은 LangGraph 에이전트를 직접 고치지 않고 외부에서 래핑해 주기적·지속적 목표 관리를 수행하는 TypeScript SDK를 공개한 사례이다. 각 웨이크에서 스크래치패드를 유지하고 동일한 LLM 클라이언트로 리플렉션을 실행해 다음 웨이크 시간을 min/max 범위 내에서 결정하며, 멱등성 키와 감사행을 통한 거버넌스가 사이드 이펙트의 중복 실행을 방지한다. 운영 스토어는 기본 메모리에서 프로덕션용 Postgres와 BullMQ로 전환하도록 설계되어 있으며 handle.wake와 handle.resume 같은 API로 웹훅 트리거와 재시작 복구를 지원한다. 작성자는 이 접근법의 초기 구현과 한계를 인정하면서 메모리-런 사이의 상태 유지 문제를 어떻게 처리하는지 피드백을 구하고 있다.

실용적 조언

  • 그래프 자체를 변경하지 않고 외부에 래퍼를 두면 기존 에이전트 정의를 재사용하면서 주기적 실행과 상태 보존 기능을 추가할 수 있다. 래퍼는 각 웨이크에서 스크래치패드를 갱신하고 다음 웨이크 시간을 산정해 재실행 결정을 내린다. 이 방식은 그래프 재작성 비용을 줄이면서 프로액티브 동작을 부여하는 실무적 타협으로 작동한다.
  • 멱등성 키를 호출 전에 스토어에 예약하고 시도별로 감사행을 남기는 거버닝 레이어를 도입하면 모델 응답의 불확실성 때문에 발생하는 중복 사이드 이펙트를 방지할 수 있다. 거부된 시도는 도구 결과로 모델에 반환되어 재계획을 유도하도록 설계하면 무차별 재시도를 줄일 수 있다. 운영 스토어는 개발 단계에서는 메모리 기반으로 시작하되 프로덕션에서는 Postgres와 작업 큐(BullMQ)로 전환하는 것이 권장된다.
  • 리플렉션 단계는 동일한 LLM 클라이언트를 재사용해 스크래치패드를 업데이트하고 다음 웨이크 시간(min/max 범위)을 결정하는 데 활용하면 추가 키나 공급자 설정을 늘리지 않고 상태 관리를 통합할 수 있다. 바쁜 리포지토리에서는 짧은 간격으로, 조용한 저장소에서는 긴 간격으로 자동 조정되도록 min/max를 설정하면 불필요한 호출을 줄일 수 있다. 웹훅 트리거용 handle.wake()를 제공하면 스케줄을 기다릴 필요 없이 즉시 반응해야 하는 이벤트에 대응할 수 있다.

섹션별 상세

01
LangGraph가 추론과 그래프 실행을 담당하지만 그래프는 호출되어야만 동작한다는 문제의식에서 출발했다. 원글 작성자는 주기적 작업, 요약 생성, 오래된 PR 추적 같은 '프로액티브'한 행위를 위해 그래프 바깥에서 실행·상태를 관리해야 했고 이 과정에서 많은 공통 인프라를 반복해서 구현했다고 밝혔다. 문제 해결을 위해 그래프 코드를 바꾸지 않고 에이전트를 래핑하는 SDK를 제작해 반복된 수정 비용을 줄였다고 언급했다.
02
웨이크마다 에이전트가 상황보고(situation report)를 받고 스크래치패드에 이전 웨이크의 약속과 수행 결과를 유지하는 방식이 핵심 동작 방식이다. 입력은 저장된 목표와 이전 웨이크의 요약이며 처리 단계에서 동일 LLM 클라이언트를 사용한 리플렉션이 실행되어 스크래치패드를 갱신하고 다음 웨이크 시간을 결정한다. 출력은 갱신된 스크래치패드, 선택된 다음 웨이크 타이밍, 그리고 수행 여부를 기록하는 감사행(audit row)이다.
03
리플렉션은 추가 키나 별도 LLM 공급자를 요구하지 않고 현재 사용 중인 langchainModel(llm)을 호출해 내부 상태를 정리하고 동적 백오프를 산정하는 방식으로 구현되었다. 글에는 바쁜 저장소에서는 짧은 간격(예: 30분)으로 재검사하고 조용한 저장소에서는 최대 24시간으로 백오프하는 min/max 카덴스 정책이 적용되었다고 적혀 있다. 작성자는 고정 주기보다 이 동적 방식이 더 잘 작동한다고 경험적으로 보고했다.
04
거버넌스는 governed() 래퍼를 통해 멱등성 키 청구, per-wake 실행 캡 적용, 시도별 감사 행 기록을 수행하면서 모델의 부적절한 재시도를 방지하는 방식으로 작동한다. 도구 호출 전에 스토어에 멱등성 키를 예약하고 거부된 시도는 모델의 도구 결과로 반환되어 재계획이 일어나도록 설계되었다는 기술적 세부가 제공되었다. 이 접근은 '모델이 했다고 주장하는 것'이 아니라 감사 이력으로 행동 여부를 판정하도록 만든 점에서 운영 신뢰성을 높였다.
05
운영 환경을 위한 구현 세부로 기본 스토어는 메모리 기반이며 프로덕션에서는 Postgres와 BullMQ를 사용하고 handle.resume()으로 재시작 후 상태를 재무장한다고 명시되어 있다. 또한 fromLangGraph 콜백은 트랜스크립트를 기록하고 서브그래프도 포함하여 웨이크 기록을 보관하며 handle.wake() API를 웹훅용으로 제공해 스케줄을 기다리지 않고 즉시 트리거할 수 있게 했다. 마지막으로 작성자는 깃허브 링크와 함께 이 SDK가 초기 단계이며 메모리-런 사이 상태 유지 문제에 대한 다른 사람들의 접근 방식을 묻는 형태로 토론을 요청했다.

용어 해설

LangGraph
LangGraph는 에이전트 흐름과 그래프 기반 작업 조합을 다루는 프레임워크로서 이 글에서는 추론과 플로우 정의를 담당하는 정적 그래프 역할을 한다. 원문 맥락에서는 그래프가 자체적으로 실행되지만 사전 호출이 있어야 동작하기 때문에 별도 래퍼로 주기적·상태ful 실행을 보완한다는 전제가 있다. 이 라이브러리는 에이전트 로직을 변경하지 않고 외부에서 작동 시간을 관리하는 구조적 기반으로 사용된다.
리플렉션(반성 단계)(Reflection)
리플렉션은 각 주기(wake) 후에 LLM으로 현재 상황과 이전 행동을 요약·갱신해 에이전트의 내부 스크래치패드를 업데이트하고 다음 실행 시점을 결정하는 과정이다. 이 글에서는 동일한 LLM 클라이언트를 호출해 별도 공급자나 키를 추가하지 않고 상태를 정리하고 재계획을 유도하는 역할을 한다. 리플렉션은 고정 간격 대신 동적 백오프와 조기 재시작을 가능하게 해 캔디스 기반 주기를 조절한다.
스크래치패드(Scratchpad)
스크래치패드는 에이전트가 각 웨이크 사이에 유지하는 임시 상태·메모 영역으로서 이전 웨이크의 약속, 수행 내역, 보류된 작업을 저장한다. 글에서는 이 공간 덕분에 웨이크 간 전사(transcript)를 재생하지 않고도 상태를 인지할 수 있다고 설명되어 있다. 스크래치패드는 중복 실행 방지와 의사결정의 연속성을 제공한다.
멱등성 키(Idempotency Key)
멱등성 키는 외부 사이드 이펙트 호출 전에 저장소에 선언되는 고유 식별자로서 동일한 효과를 중복 적용하지 않도록 보장한다. 글에서는 거버닝 래퍼(governed)가 호출 전에 키를 청구하고 실행 캡을 적용해 시도 내역을 감사행으로 남긴다고 적시되어 있다. 멱등성 키와 감사행 결합은 모델의 응답에 의한 무분별한 재시도를 방지하는 핵심 수단이다.
주기(카덴스)(Cadence)
카덴스는 에이전트가 깨어나서 점검·행동을 수행하는 최소·최대 간격을 뜻하며 이 글에서는 min/max 범위로 동적 재시작 간격을 선택하는 메커니즘을 의미한다. 구현은 각 웨이크 후 리플렉션이 다음 웨이크 시간을 min과 max 사이에서 결정하도록 하여 바쁜 리포지토리에서는 짧게, 조용한 곳에서는 길게 백오프하도록 동작한다. 고정 간격보다 더 효율적인 자원 사용과 적시 알림을 제공하는 설계 요소이다.

코드 예제

typescript
import { proactive } from "@refix/proactivity";
import { fromLangGraph, governed, langchainModel } from "@refix/proactivity/langgraph";

const agent = createReactAgent({ llm, tools: [listIssues, listPullRequests, governed(postToSlack)], prompt: "You watch a GitHub repo and keep #eng informed.", });

const handle = proactive(fromLangGraph(agent), { reflection: { model: langchainModel(llm) }, goals: [{ title: "Keep #eng on top of acme/api", objective: "Post when something needs a human. Stay silent otherwise.", doneCondition: "Standing goal, never done.", pinned: true, }], cadence: { min: "15m", max: "24h" }, });

await handle.start("acme/api");

LangGraph 에이전트를 래핑해 반영(reflection), 목표(goals), 동적 카덴스(cadence)를 설정하고 시작하는 TypeScript 사용 예시 코드이다.

언급된 도구

LangGraph중립

에이전트 플로우와 그래프 기반 실행을 담당하는 프레임워크

LangChain중립

LLM 호출을 위한 모델 래퍼로 글에서는 langchainModel(llm)을 리플렉션에 사용

Postgres + BullMQ추천

프로덕션용 상태 저장과 작업 큐로서 재시작 복구와 작업 재시도를 담당

언급된 리소스

AI 분석 전체 내용 보기

AI 요약 · 북마크 · 개인 피드 설정 — 무료

출처 · 인용 안내

원문 발행 2026. 07. 07.수집 2026. 07. 07.출처 타입 REDDIT

인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.