ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이코에코(Eco²) Agent Skills: Checkpointer Reference
    이코에코(Eco²) Context/Skills 2026. 1. 19. 06:47

    Chat Agent Persistence Skill.md 하위 Reference
    Cache Aside 패턴 및 LangGraph 멀티턴 대화 컨텍스트 영속화 명시

    Architecture

    ┌─────────────────────────────────────────────────────────────────┐
    │                    Cache-Aside Pattern                           │
    ├─────────────────────────────────────────────────────────────────┤
    │                                                                  │
    │  조회 (aget_tuple)                                               │
    │  ─────────────────                                               │
    │  LangGraph → Redis (L1, ~1ms)                                    │
    │                 │                                                │
    │                 ├── Hit → Return                                 │
    │                 │                                                │
    │                 └── Miss → PostgreSQL (L2)                       │
    │                               │                                  │
    │                               └── Redis 캐싱 (warm-up)           │
    │                                       │                          │
    │                                       └── Return                 │
    │                                                                  │
    │  저장 (aput)                                                     │
    │  ───────────                                                     │
    │  LangGraph → PostgreSQL (영구) + Redis (캐시)                     │
    │              Write-Through                                       │
    │                                                                  │
    └─────────────────────────────────────────────────────────────────┘

    Components

    Class Purpose Layer
    CachedPostgresSaver L1 Redis + L2 PostgreSQL Adapter
    AsyncPostgresSaver LangGraph PostgreSQL 체크포인터 External (langgraph)
    MemorySaver In-memory fallback External (langgraph)

    Current Issue

    Error

    [WARNING] CachedPostgresSaver failed, falling back to Redis only:
    object _AsyncGeneratorContextManager can't be used in 'await' expression

    Root Cause

    checkpointer.py:228:

    # BUG: from_conn_string()은 async context manager 반환
    postgres_saver = await AsyncPostgresSaver.from_conn_string(conn_string)  # WRONG!

    LangGraph API Signature

    # langgraph-checkpoint-postgres
    class AsyncPostgresSaver:
        @classmethod
        @asynccontextmanager
        async def from_conn_string(cls, conn_string: str) -> AsyncIterator["AsyncPostgresSaver"]:
            """Async context manager - await 아님!"""
            ...

    Fallback Chain

    CachedPostgresSaver (PostgreSQL + Redis)
           │
           │ Exception
           ▼
    create_redis_checkpointer()
           │
           │ (Redis checkpointer도 lifecycle 이슈)
           ▼
    MemorySaver (In-memory only)

    Fix Options

    Option A: Context Manager 수동 관리

    class CachedPostgresSaver(BaseCheckpointSaver):
        _postgres_cm: AsyncContextManager | None = None
    
        @classmethod
        async def create(cls, conn_string: str, redis: "Redis") -> "CachedPostgresSaver":
            from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
    
            cm = AsyncPostgresSaver.from_conn_string(conn_string)
            postgres_saver = await cm.__aenter__()
    
            instance = cls(postgres_saver=postgres_saver, redis=redis)
            instance._postgres_cm = cm
            return instance
    
        async def close(self) -> None:
            if self._postgres_cm:
                await self._postgres_cm.__aexit__(None, None, None)

    Option B: Connection Pool 직접 생성 (권장)

    from psycopg_pool import AsyncConnectionPool
    
    async def create_cached_postgres_checkpointer(
        conn_string: str,
        redis: "Redis",
    ) -> CachedPostgresSaver:
        from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
    
        # Pool 직접 생성
        pool = AsyncConnectionPool(conninfo=conn_string)
        await pool.open()
    
        postgres_saver = AsyncPostgresSaver(pool)
        await postgres_saver.setup()  # 테이블 생성
    
        return CachedPostgresSaver(
            postgres_saver=postgres_saver,
            redis=redis,
            pool=pool,  # cleanup 위해 보관
        )

    Verification

    # 1. Worker 로그에서 성공 메시지 확인
    kubectl logs -n chat deploy/chat-worker --tail=50 | grep -E "CachedPostgresSaver (created|initialized)"
    
    # 2. PostgreSQL 체크포인트 테이블 확인
    kubectl exec -n postgres deploy/postgresql -- psql -U sesacthon -d ecoeco -c \
      "SELECT COUNT(*) FROM checkpoints;"
    
    # 3. 멀티턴 대화 테스트
    # 첫 번째 메시지: "내 이름은 철수야"
    # 두 번째 메시지: "내 이름이 뭐라고 했지?" → 철수 기억하면 성공

    Configuration

    Variable Value Description
    POSTGRES_URL postgresql+asyncpg://... PostgreSQL 연결 문자열
    REDIS_URL redis://rfr-pubsub-redis-0... Redis 캐시 URL
    Cache TTL 86400 (24h) 체크포인트 캐시 TTL

    Related Files

    File Description
    checkpointer.py CachedPostgresSaver 구현
    dependencies.py:641-678 get_checkpointer() 함수
    factory.py Graph 생성 시 checkpointer 주입

    댓글

ABOUT ME

🎓 부산대학교 정보컴퓨터공학과 학사: 2017.03 - 2023.08
☁️ Rakuten Symphony Jr. Cloud Engineer, Full-time: 2024.12.09 - 2025.08.31
🏆 2025 AI 새싹톤 우수상 수상: 2025.10.30 - 2025.12.02
🌏 이코에코(Eco²) BE/AI(Harness)/Infra/FE 24-node E2E 고도화 및 운영, 2600만원 소모: 2025.12 - 2026.02
🪂 넥슨 AI 엔지니어(서류합 -> 과제합 -> 면접 탈락), 무신사 AI-Native(전환형 인턴, 진행 X) 채용 프로세스: 2026.01.31 - 2026.03.05
🪂 GEODE/REODE 개발, Agentic Loop-based 자율 수행 하네스 + 도메인 특화 DAG(Plug-In), AI R&D Freelance @Pinxlab : 2026.03 - 2026.05
🪂 FuriosaAI SWE, Agent System (서류합 -> 면접 탈락), 42dot AI Engineer, Gleo팀(서류합->코테합->면접 탈락): 2026.04 - 2026.07
🪂 LG AI Research AI Data Engineer Intern(서류합, 전형 참여중), FuriosaAI SWE, Compiler[AX](서류합, 전형 참여중): 2026.07

Designed by Mango