본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 05. 22. 10:44

LangGraph 에이전트에 3가지 종류의 기억을 TiDB로 구현하기──위협 인텔리전스로 배우는 SQL × 벡터 검색 × 전문 검색

요약

LangGraph 에이전트의 기억력 문제를 해결하기 위해 TiDB를 활용하여 SQL, 벡터 검색, 전문 검색을 통합 구현하는 방법을 소개합니다. 위협 인텔리전스 사례를 통해 단일 데이터베이스로 세 가지 유형의 기억을 관리하는 효율적인 아키텍처를 제시합니다.

핵심 포인트

  • LangGraph 에이전트의 세션 간 기억 유지를 위한 영구 데이터 기반 구축
  • TiDB를 활용해 SQL, 벡터 검색, 전문 검색을 하나의 DB로 통합 관리
  • 위협 인텔리전스(IOC, TTP, 위협 액터)를 통한 실전 구현 예시 제공
  • 다중 DB 운영(pgvector, Elasticsearch, Redis) 대비 관리 비용 절감

서론 ── AI 에이전트는 왜 "잊어버리는"가

LangGraph로 AI 에이전트를 만들었을 때, 많은 사람이 처음에 직면하는 문제가 있습니다.

세션을 넘어가면 에이전트가 기억을 잃는 문제입니다.

어제 조사한 IP 주소의 위협 정보, 지난주에 분석한 공격 기법, 과거의 인시던트 대응 기록. 이것들을 에이전트에게 "기억시키기" 위해서는 영구적인 데이터 기반이 필요합니다.

이 기사에서는 TiDB의 SQL · 벡터 검색 (Vector Search) · 전문 검색 (Full-text Search)을 하나의 데이터베이스에서 구분하여 사용함으로써, AI 에이전트에게 3가지 종류의 기억을 갖게 하는 구현 방법을 소개합니다.

구현 예시로는 제 본업인 위협 인텔리전스 (Threat Intelligence) 영역을 다룹니다. IOC 대조 · TTP 유사 검색 · 위협 액터 조사의 세 가지 검색 니즈가 TiDB의 세 가지 기능과 잘 대응하기 때문입니다.

エージェントが脅威レポートを自動生成している画面

LangGraph 에이전트가 IOC 대조 · TTP 특정 · 위협 액터 조사를 자율적으로 실행하여 위협 보고서를 생성한다

잠시 자기소개를 하자면, 저는 솔루션 엔지니어로서 위협 인텔리전스를 전문으로 하고 있습니다. 경영 · 사업 · 업무 레벨에서 위협 인텔리전스를 활용하여 가치 향상을 지원하는 업무를 하기 때문에 평소에는 코드를 거의 쓰지 않습니다. 이번에는 TiDB 콘테스트를 계기로 LLM이나 벡터 검색을 공부하며 처음으로 AI 에이전트 구축에 도전했습니다. 막혔던 부분이나 깨달은 점도 포함하여 그대로 작성했으므로, 마찬가지로 "코드에 익숙하지 않지만 시도해보고 싶다"는 분들에게도 참고가 된다면 좋겠습니다.

왜 TiDB 하나인가 ── 3개 DB 구성의 고충

AI 애플리케이션의 검색 기반을 그대로 구축하면 다음과 같이 되기 쉽습니다.

pgvector ── 벡터 검색 (Vector Search)
Elasticsearch ── 전문 검색 (Full-text Search)
Redis ── 캐시 · 고속 참조

3개의 DB를 관리하는 비용, 각각의 연결 관리, 스키마의 정합성 유지. 운영 단계로 갈수록 부담이 늘어납니다.

TiDB는 이것을 하나로 집약할 수 있습니다.

검색 종류용도TiDB 기능
완전 일치 · 고속 참조IOC (IP · 해시 · 도메인)SQL
...

이 세 가지가 갖춰짐으로써, 위협 인텔리전스의 3가지 종류의 기억을 TiDB 하나로 실현할 수 있습니다.

시스템 구성

アーキテクチャ図

사용 기술 스택:

DB: TiDB Cloud Starter (Frankfurt / eu-central-1) -
Embedding: paraphrase-multilingual-MiniLM-L12-v2 (로컬 동작) -
에이전트: LangGraph + LangChain -
데이터: MITRE ATT&CK (공식 JSON)

TiDB Cloud Starter 설정

클러스터 생성

TiDB Cloud에 접속하여 Create Resource에서 클러스터를 생성합니다.

クラスター作成画面でFrankfurtを選択している

리전 선택 화면. AWS – Frankfurt (eu-central-1)을 반드시 선택할 것

연결 정보 설정

TiDB CloudのConnect画面

Connect 화면에 표시되는 Host · Port · User를 .env에 기재한다

클러스터 생성 후, Connect 버튼을 통해 연결 정보를 가져와 .env 파일에 기재합니다.

DB_HOST=gateway01.eu-central-1.prod.aws.tidbcloud.com
DB_PORT=4000
DB_USERNAME=your_prefix.root
...

필요한 라이브러리 설치

# Python 가상 환경 생성
python3 -m venv tidb
source tidb/bin/activate
pip install pymysql python-dotenv sentence-transformers \ 
mitreattack-python langgraph langchain-openai pytidb

Week1: 에피소드 기억 ── IOC를 SQL로 검색하기

왜 IOC에 SQL (완전 일치)이 최적인가

IOC 대조에서 가장 먼저 필요한 것은 속도입니다. 185.220.101.1

라는 IP 주소가 알려진 위협인지 판정할 때, 의미적 유사성은 필요하지 않으며, 해당 여부를 순식간에 반환해주기를 원합니다. SQL의 완전 일치 (Exact Match) 검색은 이러한 니즈에 그대로 대응합니다.

테이블 설계

CREATE TABLE IF NOT EXISTS ioc (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(20) NOT NULL, -- ip / domain / hash
...

셋업 및 검색 함수

Week1/setup_ioc.py (테이블 생성 및 샘플 데이터 투입)

import pymysql
from dotenv import load_dotenv
import os
...

에이전트의 도구 (tool)가 될 검색 함수는 간단하며, SQL을 한 줄 실행할 뿐입니다.

def search_ioc(indicator: str) -> dict | None:
"""IOC를 완전 일치로 검색한다. 나중에 LangGraph의 tool이 될 함수."""
conn = pymysql.connect(...)
...

동작 확인

🚨 [MEDIUM] 185.220.101.1
위협명: TorExitNode 정보원: abuse.ch
🚨 [HIGH] malware-c2.example.com
...

Week2: 세만틱 기억 (Semantic Memory) ── TTP를 벡터 검색하기

왜 TTP에 벡터 검색이 필요한가

TTP는 완전 일치로는 대응할 수 없습니다. "PowerShell을 사용한 외부 연결"이라는 알람으로부터 T1059.001 PowerShell을 찾아내려면, 문자의 일치가 아니라 의미의 유사성으로 검색해야 합니다. 이것이 벡터 검색 (Vector Search)을 사용하는 이유입니다.

MITRE ATT&CK 데이터 취득

# enterprise-attack.json을 다운로드 (약 80MB)
curl -L -o enterprise-attack.json \

테이블 설계 (384차원 벡터)

Week2/setup_ttp.py에서 테이블을 생성합니다.

CREATE TABLE ttp (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
technique_id VARCHAR(20) NOT NULL,
...

임베딩 (Embedding) 모델 선정

처음에는 OpenAI API를 사용하려 했으나, 쿼터 (Quota) 초과가 발생했습니다.

그다음 영어 전용 모델 (all-MiniLM-L6-v2)을 시도했으나, 일본어 쿼리의 정밀도가 낮은 문제가 발생했습니다.

TTP 데이터 투입

Week2/embed_ttp.py (MITRE ATT&CK 697건을 임베딩하여 TiDB에 투입)

import pymysql
from sentence_transformers import SentenceTransformer
from mitreattack.stix20 import MitreAttackData
...

LangGraph의 tool이 될 검색 함수

model = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")
def search_ttp(description: str, top_k: int = 3) -> list[dict]:
"""TTP를 벡터 검색한다. 나중에 LangGraph의 tool이 될 함수."""
...

동작 확인

search_ttp.pyの実行結果

일본어 쿼리가 영어 MITRE ATT&CK 데이터에 정확히 히트. PowerShell 쿼리로 스코어 0.812를 기록

일본어로 던진 쿼리가 영어로 작성된 ATT&CK 데이터에 정확히 히트하고 있습니다.

Week3: 절차적 기억 (Procedural Memory) ── 위협 액터를 전문 검색하기

왜 전문 검색 (Full-text Search, BM25)이 필요한가

위협 액터 검색에서 곤란한 점은 "관련 그룹을 놓치고 싶지 않다"는 점입니다. "Lazarus"로 검색했을 때, Lazarus Group뿐만 아니라 배후에 있는 Kimsuky나 Andariel도 함께 찾아내고 싶습니다. 게다가 관련도가 높은 순서대로 나열해주기를 원합니다. BM25 전문 검색은 이러한 니즈에 그대로 응답합니다.

테이블 설계

CREATE TABLE threat_actor (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
...
-- 인덱스는 별도로 추가 (ADD_COLUMNAR_REPLICA_ON_DEMAND 필요)
ALTER TABLE threat_actor
ADD FULLTEXT INDEX ft_actor (search_text)
...

MITRE ATT&CK에서 위협 액터(Threat Actor) 데이터 가져오기

샘플 데이터를 직접 만들 필요는 없습니다. Week 2에서 다운로드한 enterprise-attack.json에는 174건의 위협 액터 데이터가 들어 있습니다.

Week3/seed_actor_fulltext.py (174건의 위협 액터 투입)

import pymysql
from mitreattack.stix20 import MitreAttackData
from dotenv import load_dotenv
...

LangGraph의 도구(Tool)가 될 검색 함수

def search_actor_fulltext(keyword: str, top_k: int = 3) -> list[dict]:
    """위협 액터를 BM25 전문 검색(Full-text Search)한다. 나중에 LangGraph의 도구(Tool)가 될 함수."""
    conn = pymysql.connect(...)
    ...

동작 확인

🔍 쿼리: APT29
APT29 BM25 스코어: 7.152
🔍 쿼리: Lazarus
...

BM25 스코어에 따라 관련도 순으로 정렬되는 것이 LIKE 검색과의 결정적인 차이점입니다.

LangGraph 에이전트에 3가지 도구 통합하기

3가지 검색 함수를 LangGraph에 전달하기만 하면, 에이전트가 알람 내용을 읽고 적절한 도구를 자율적으로 선택하여 동작합니다.

Week3/agent.py (3가지 도구를 통합한 LangGraph 에이전트)

import os, sys
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
...

데모: 위협 보고서 자동 생성

agent.pyの実行結果

에이전트가 3가지 도구를 자율적으로 호출하여 위협 보고서를 생성함

알람을 던지면 IOC 대조 → TTP 특정 → 위협 액터 조사를 순차적으로 자율 실행하여 보고서를 반환해 줍니다. 보안 분석가가 수작업으로 30분 걸릴 조사가 단 몇 초 만에 끝나는 것을 보고, 처음 동작했을 때 솔직히 놀랐습니다. TiDB 하나로 통합함으로써 에이전트가 3가지 종류의 기억에 망설임 없이 접근할 수 있는 구성이 효과를 발휘하고 있다고 생각합니다.

퀵 스타트 ── 실행 순서 정리

처음 시도하는 분들을 위해 실행 순서를 정리합니다.

# 1. MITRE 데이터 다운로드 (약 80MB · 최초 1회)
curl -L -o enterprise-attack.json \

...

요약

TiDB의 3가지 기능을 구분하여 사용함으로써 AI 에이전트에게 3가지 종류의 기억을 부여할 수 있었습니다.

기억의 종류보안 용도TiDB 기능특징
에피소드 기억IOC 대조SQL완전 일치 · 고속
...

이 아키텍처는 위협 인텔리전스(Threat Intelligence) 외에도 사용할 수 있습니다.

고객 지원: FAQ 검색 (SQL) + 유사 사례 (벡터) + 제품 매뉴얼 (전문 검색) -
사내 지식: 직원 검색 (SQL) + 관련 문서 (벡터) + 회의록 (전문 검색)

여러 개의 DB를 관리하는 번거로움을 줄이면서, AI 에이전트의 데이터 기반을 하나로 구축할 수 있습니다. 그것이 TiDB를 선택한 가장 큰 이유입니다.

참고 링크

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn ML의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0