Skip to main content

에이전트 메모리 관리

에이전트가 대화 맥락을 유지하고 과거 상호작용으로부터 학습하려면 메모리 관리 가 필수적입니다.

Short-term Memory (단기 메모리)

현재 대화 세션 내에서 맥락을 유지하는 메모리입니다.
전략설명장단점
전체 대화 이력 전달모든 메시지를 LLM에 전달합니다정확하지만 토큰 비용이 급증합니다. 긴 대화에 부적합합니다
슬라이딩 윈도우최근 N개 메시지만 전달합니다비용을 제어하지만 초기 맥락을 잃습니다
요약 기반오래된 대화를 LLM이 요약하여 압축합니다비용과 맥락의 균형이 좋지만 요약 시 정보 손실이 있습니다
토큰 예산 기반총 토큰 수를 제한하고 오래된 메시지를 제거합니다비용을 엄격히 제어합니다
# 슬라이딩 윈도우 + 요약 하이브리드 전략
def manage_memory(messages: list, max_recent: int = 10, max_tokens: int = 4000):
    if len(messages) <= max_recent:
        return messages

    # 오래된 메시지를 요약
    old_messages = messages[:-max_recent]
    summary = llm.summarize(old_messages)

    # 요약 + 최근 메시지를 결합
    return [{"role": "system", "content": f"이전 대화 요약: {summary}"}] + messages[-max_recent:]

Long-term Memory (장기 메모리)

세션을 넘어 지속되는 메모리로, 사용자 선호도, 과거 질문 패턴, 해결된 이슈 등을 저장합니다.
저장소적합한 데이터Databricks 도구
Vector Store과거 대화 중 유용한 Q&A 쌍, 해결 사례Databricks Vector Search
Key-Value Store사용자 선호도, 설정, 프로필Lakebase (PostgreSQL)
Delta Table구조화된 상호작용 로그, 피드백 이력Unity Catalog Delta 테이블
# Lakebase를 활용한 장기 메모리 저장 예시
import psycopg2

def save_user_preference(user_id: str, key: str, value: str):
    """사용자 선호도를 Lakebase에 저장"""
    conn = psycopg2.connect(host="lakebase-endpoint", dbname="agent_memory")
    with conn.cursor() as cur:
        cur.execute("""
            INSERT INTO user_preferences (user_id, pref_key, pref_value, updated_at)
            VALUES (%s, %s, %s, NOW())
            ON CONFLICT (user_id, pref_key) DO UPDATE SET pref_value = %s, updated_at = NOW()
        """, (user_id, key, value, value))
    conn.commit()
💡 메모리 비용 고려: 모든 대화를 저장하면 스토리지와 검색 비용이 증가합니다. 실무에서는 사용자 피드백이 긍정적인 대화, 해결된 이슈, 자주 묻는 질문 등 고품질 메모리만 선별 하여 저장하는 것이 효율적입니다.

에이전트 보안 설계

프로덕션 에이전트는 실제 시스템에 접근하므로, 보안이 매우 중요합니다. 잘못 설계하면 데이터 유출이나 의도치 않은 시스템 변경이 발생할 수 있습니다.

도구 접근 제어

보안 원칙설명구현 방법
최소 권한 원칙에이전트에 필요한 최소한의 도구만 부여합니다Unity Catalog Functions에서 GRANT로 도구별 권한 제어
읽기/쓰기 분리조회 도구와 변경 도구를 분리합니다읽기 전용 에이전트와 쓰기 가능 에이전트를 별도 엔드포인트로 분리
승인 기반 실행위험한 작업(삭제, 결제 등)은 인간 승인을 필수로 합니다Human-in-the-loop 패턴 적용
도구 호출 제한한 세션에서 도구를 호출할 수 있는 최대 횟수를 제한합니다무한 루프 방지를 위해 max_iterations 설정
# Human-in-the-loop 패턴: 위험한 도구 실행 전 승인 요청
DANGEROUS_TOOLS = {"delete_record", "process_payment", "update_user_data"}

def execute_tool(tool_name: str, params: dict, user_session):
    if tool_name in DANGEROUS_TOOLS:
        # 사용자에게 승인 요청
        approval = request_human_approval(
            user_session,
            action=f"{tool_name}({params})",
            message=f"다음 작업을 실행하시겠습니까?"
        )
        if not approval:
            return "사용자가 작업을 취소했습니다."

    return tools[tool_name].execute(**params)

데이터 유출 방지 (Data Exfiltration Prevention)

위험시나리오방어 방법
프롬프트 인젝션악의적 입력으로 시스템 프롬프트를 우회합니다입력 필터링, Guardrails, 시스템 프롬프트와 사용자 입력 분리
민감 데이터 노출에이전트가 답변에 PII(개인정보)를 포함합니다출력 필터링(정규식, NER 기반 마스킹)
도구 체인 공격에이전트가 여러 도구를 조합하여 의도하지 않은 데이터를 추출합니다도구 간 데이터 흐름 모니터링, 조합 제한
간접 프롬프트 인젝션검색된 문서에 악의적 명령이 포함되어 있습니다RAG 소스 데이터 검증, 검색 결과와 명령 분리
# Guardrails를 활용한 입출력 필터링
import re

PII_PATTERNS = {
    "주민등록번호": r"\d{6}-[1-4]\d{6}",
    "신용카드": r"\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}",
    "전화번호": r"01[0-9]-\d{3,4}-\d{4}",
}

def sanitize_output(response: str) -> str:
    """에이전트 응답에서 PII를 마스킹"""
    for pii_type, pattern in PII_PATTERNS.items():
        response = re.sub(pattern, f"[{pii_type} 마스킹됨]", response)
    return response

MLflow Tracing 기반 보안 감사

# 모든 도구 호출을 MLflow로 추적하여 보안 감사 로그 생성
import mlflow

@mlflow.trace
def agent_chat(user_input: str):
    with mlflow.start_span("input_validation"):
        validated_input = validate_and_sanitize(user_input)

    with mlflow.start_span("llm_reasoning"):
        response = llm.generate(validated_input)

    with mlflow.start_span("tool_execution"):
        result = execute_tools(response.tool_calls)

    with mlflow.start_span("output_sanitization"):
        safe_output = sanitize_output(result)

    return safe_output

프로덕션 SLA 설계

에이전트를 프로덕션에 배포할 때는 가용성, 지연시간, 비용을 명확히 정의하고 관리해야 합니다.

지연시간(Latency) 최적화

최적화 전략설명예상 효과
LLM 선택작업 복잡도에 맞는 모델 크기를 선택합니다소형 모델은 2~5x 빠름
스트리밍 응답토큰 단위로 실시간 스트리밍하여 체감 지연을 줄입니다첫 토큰까지 시간(TTFT) 단축
도구 병렬 호출독립적인 도구를 동시에 호출합니다도구가 3개면 지연이 1/3로 감소
검색 결과 캐싱자주 묻는 질문의 Vector Search 결과를 캐싱합니다검색 지연 제거
프롬프트 최적화시스템 프롬프트를 간결하게 유지합니다토큰 처리 시간 감소

가용성 및 확장성

설계 항목권장 설정이유
Model Serving 엔드포인트Provisioned Throughput 사용트래픽 급증 시에도 안정적인 지연시간 보장
자동 스케일링min_instances=2, max_instances=10고가용성 유지 + 트래픽 대응
헬스 체크30초 간격으로 엔드포인트 상태 확인장애 조기 발견
타임아웃 설정도구 호출 30초, 전체 응답 120초무한 대기 방지
재시도 전략최대 3회, 지수 백오프일시적 오류 복구

비용 예산 관리

에이전트 비용은 주로 LLM 토큰 소비와 Model Serving 인프라에서 발생합니다.
비용 요소산정 방법최적화 전략
LLM 토큰입력 토큰 + 출력 토큰 x 단가프롬프트 압축, 불필요한 컨텍스트 제거
Model Serving인스턴스 수 x 시간 x DBU 단가Provisioned Throughput 적정 사이징
Vector Search엔드포인트 + 쿼리 수캐싱, 배치 쿼리
도구 호출SQL Warehouse 쿼리 수, API 호출 수불필요한 도구 호출 최소화
# 월 비용 추정 예시 (일 1,000 대화, 평균 5턴/대화 기준)
- LLM 토큰: 1,000 x 5 x 4,000 토큰 = 20M 토큰/일 ≈ $300~600/월
- Model Serving: Provisioned Throughput 2 인스턴스 ≈ $2,000~4,000/월
- Vector Search: Endpoint 1개 ≈ $200~500/월
- 총 예상: $2,500~5,100/월
💡 비용 모니터링: Inference Tables에 기록되는 토큰 사용량을 SQL로 조회하여 일별/주별 비용 트렌드를 대시보드로 관리하세요. 예상치를 초과하면 즉시 알림을 받도록 설정합니다.

에이전트 디버깅 전략

에이전트는 비결정적(non-deterministic)이므로, 전통적인 소프트웨어 디버깅과 다른 접근이 필요합니다.

MLflow Tracing 활용

MLflow Tracing은 에이전트의 실행 흐름을 단계별로 추적할 수 있는 핵심 도구입니다.
추적 대상확인 가능한 정보
LLM 호출입력 프롬프트, 출력 텍스트, 토큰 수, 지연시간
도구 호출호출된 도구 이름, 파라미터, 반환값, 실행 시간
검색(Retrieval)검색 쿼리, 반환된 문서, 유사도 점수
전체 체인각 단계의 순서, 소요 시간, 오류 발생 지점

일반적인 실패 모드와 디버깅 방법

실패 모드증상디버깅 방법
도구 선택 오류잘못된 도구를 호출하거나 도구를 호출하지 않습니다Tracing에서 LLM의 reasoning 확인 → 도구 설명(description) 개선
파라미터 추출 오류올바른 도구를 선택하지만 잘못된 파라미터를 전달합니다도구의 파라미터 스키마를 더 명확하게 정의
무한 루프같은 도구를 반복 호출합니다max_iterations 설정, 루프 감지 로직 추가
환각 응답도구 결과를 무시하고 지어낸 답변을 반환합니다시스템 프롬프트에 “도구 결과만 사용하라”는 지시 강화
컨텍스트 유실긴 대화에서 초반 맥락을 잊습니다메모리 관리 전략 개선(요약 기반 압축)

체계적 평가 파이프라인

# MLflow Evaluate를 활용한 에이전트 품질 평가
import mlflow

eval_data = [
    {"input": "지난 달 매출 알려줘", "expected_tool": "get_sales_data", "expected_contains": "매출"},
    {"input": "서울 날씨 어때?", "expected_tool": "get_weather", "expected_contains": "온도"},
]

results = mlflow.evaluate(
    model=agent_model_uri,
    data=eval_data,
    model_type="databricks-agent",
    evaluator_config={
        "databricks-agent": {
            "metrics": ["toxicity", "groundedness", "relevance", "tool_accuracy"]
        }
    }
)

# 결과 확인
print(f"Tool 정확도: {results.metrics['tool_accuracy/mean']:.2%}")
print(f"Groundedness: {results.metrics['groundedness/mean']:.2%}")
print(f"Relevance: {results.metrics['relevance/mean']:.2%}")

프로덕션 모니터링 체크리스트

모니터링 항목임계값 예시알림 조건
P50 응답 지연시간< 5초P50 > 8초 시 경고
P99 응답 지연시간< 30초P99 > 60초 시 경고
도구 호출 실패율< 1%> 5% 시 긴급
사용자 피드백(👍비율)> 80%< 60% 시 경고
일일 토큰 소비량예산 이내예산 120% 초과 시 경고
환각 비율< 5%> 10% 시 긴급

정리

핵심 개념설명
AI 에이전트LLM을 두뇌로, 도구를 수족으로 사용하여 자율적으로 작업을 수행하는 시스템입니다
ReAct 패턴생각(Reasoning) → 행동(Acting) → 관찰(Observation)의 반복 루프입니다
RAG문서 검색 → LLM 답변 생성. 내부 데이터 기반 정확한 답변에 필수적입니다
Tool에이전트가 호출하는 외부 기능. DB 조회, API 호출, 코드 실행 등입니다
환각(Hallucination)LLM이 근거 없이 그럴듯한 답변을 생성하는 현상. RAG로 완화합니다
아키텍처 패턴Single Agent → Multi-Agent → Supervisor 순으로 복잡도가 증가합니다
메모리 관리단기(세션 내)와 장기(세션 간) 메모리를 적절히 조합해야 합니다
보안최소 권한, PII 마스킹, 프롬프트 인젝션 방어가 프로덕션 필수 요소입니다
SLA 설계지연시간, 가용성, 비용을 정량적으로 정의하고 모니터링해야 합니다

참고 링크