
CTI를 위한 Python 기반 에이전틱 메모리 — STIX 지식 그래프, 위협 행위자 별칭 해결, 오프라인 우선 RAG, Claude Code 및 LangChain 에이전트를 위한 MCP 서버
사이버 위협 인텔리전스를 위해 구축된 유일한 에이전틱 메모리 시스템입니다.
시니어 분석가가 떠나면 2~3년치의 컨텍스트도 함께 사라집니다. 고객 환경, 이전 조사, 위협 행위자 TTP, 오탐 패턴, '아, 이거 전에 봤어' 같은 힘들게 얻은 모든 정보가요. ZettelForge는 이러한 컨텍스트가 팀에 남도록 설계된 에이전틱 메모리 시스템입니다.
분석가 노트와 위협 보고서에서 CVE, 위협 행위자, IOC, ATT&CK 기술을 추출하고, 별칭을 해결하며(APT28 = Fancy Bear = STRONTIUM = Sofacy), STIX 2.1 지식 그래프를 구축하고, 과거 모든 조사 내용을 자연어로 분석가와 Claude Code(MCP를 통해)에 제공합니다. 완전히 프로세스 내에서 실행됩니다. API 키 없음, 클라우드 없음, 데이터가 호스트를 떠나지 않습니다.
스타 · pip install zettelforge · 문서 · ThreatRecall (호스팅) · 변경 로그
v2.6.2 (2026-04-27): 구성 웹 편집기에 모든 열거형 필드(LLM/임베딩 제공자, 로그 수준, PII 조치, 합성 형식)에 대한 드롭다운이 작동하며, 적용 버튼도 작동합니다. 새로운
[crewai]추가 기능은 ZettelForge를 CrewAI 도구로 노출합니다 --pip install zettelforge[crewai]. 전체 변경 로그
ZettelForge가 귀하가 운영하는 CTI 워크플로에 적합하다면, 스타는 이 카테고리에 계속 투자할 가치가 있다는 가장 빠른 신호입니다.
모든 SOC는 분석가를 잃습니다. 그들이 떠나면 조사 컨텍스트, 위협 행위자 귀속, 환경별 오탐 패턴도 함께 사라집니다. 후임자들은 동일한 티켓을 다시 열고, 동일한 보고서를 다시 읽고, 처음부터 동일한 멘탈 모델을 다시 구축해야 합니다.
일반적인 AI 메모리 시스템은 보안 팀을 위해 이 문제를 해결하지 못합니다. APT28과 Fancy Bear를 구분하지 못하고, CVE-2024-3094가 XZ Utils 백도어인지 모르며, Sigma나 YARA를 파싱할 수 없고, MITRE ATT&CK 기술 ID에 대한 개념도 없습니다. CTI 분석가가 1년 치 인텔리전스 보고서를 주면, 채팅 기록에 대한 모호한 의미 검색 결과만 반환합니다.
ZettelForge는 위협 그래프를 생각하는 분석가를 위해 구축되었습니다. CVE, 위협 행위자, IOC, ATT&CK 기술을 자동으로 추출하고, 명명 규칙 간 별칭을 해결하며, 인과 관계가 포함된 지식 그래프를 구축하고, 의도 인식 혼합 검색을 사용하여 메모리를 검색합니다. 모두 프로세스 내에서, 외부 API 의존성 없이 작동합니다.
메모리 증강은 CTI 작업에서 소규모 모델과 대규모 모델 간의 격차 중 33%를 줄입니다 (CTI-REALM, Microsoft 2026, GPT-4를 대규모 모델 기준으로 사용). 전체 벤치마크 보고서에서 방법론과 비교를 확인하세요.
엔터티 추출 -- CVE, 위협 행위자, IOC(IP, 도메인, 해시, URL, 이메일), MITRE ATT&CK 기술, 캠페인, 침입 세트, 도구, 사람, 위치, 조직을 자동으로 식별합니다. 정규 표현식 + LLM NER을 사용하며, 모든 유형에 STIX 2.1이 적용됩니다.
지식 그래프 -- 엔터티는 노드가 되고, 동시 발생은 엣지가 됩니다. LLM이 인과 삼중항을 추론합니다("APT28 uses Cobalt Strike"). 시간적 엣지와 대체 관계는 인텔리전스의 진화를 추적합니다.
별칭 해결 -- APT28, Fancy Bear, Sofacy, STRONTIUM이 모두 동일한 위협 행위자 노드로 해결됩니다. 저장 및 검색 시 자동으로 작동합니다.
혼합 검색 -- 벡터 유사도(768차원 fastembed, ONNX) + 그래프 탐색(지식 그래프 엣지에 대한 BFS), 의도 분류에 따라 가중치 조정. 5가지 의도 유형: 사실적, 시간적, 관계적, 탐색적, 인과적.
메모리 진화 -- evolve=True로 설정하면 새로운 인텔리전스가 기존 메모리와 비교됩니다. LLM이 ADD, UPDATE, DELETE 또는 NOOP을 결정합니다. 오래된 인텔리전스는 대체됩니다. 모순은 해결됩니다. 중복은 건너뜁니다.
RAG 합성 -- direct_answer 형식으로 저장된 모든 메모리에서 답변을 합성합니다.
프로세스 내 아키텍처 -- 임베딩용 fastembed(ONNX), 로컬 LLM 추론용 llama-cpp-python(선택 사항), 저장용 SQLite + LanceDB, 기본적으로 localhost의 Ollama 사용. 외부 API 키가 필요하지 않습니다. 임베딩/LLM 모델이 다운로드될 때 첫 실행 시 아웃바운드 네트워크 액세스가 발생할 수 있습니다. 모델이 사전 로드된 후에는 완전히 오프라인(에어갭 호스트 포함)에서 실행할 수 있습니다.
OCSF 스키마의 감사 로깅 -- 모든 작업은 Open Cybersecurity Schema Framework 형식의 구조화된 이벤트를 생성합니다. 로그 스트림(SIEM, WORM 저장소 등)으로 무엇을 할지는 사용자에게 달려 있습니다.
pip install zettelforge
from zettelforge import MemoryManager
mm = MemoryManager()
# CTI 저장 -- 엔터티(CVE, 위협 행위자, ATT&CK ID, IOC)가 정규 표현식으로 추출
mm.remember("APT28 uses Cobalt Strike for lateral movement via T1021")
mm.remember("APT28 (Fancy Bear) targets NATO defense contractors with spear-phishing")
mm.remember("CVE-2024-3094 is the XZ Utils backdoor (CVSS 10.0) affecting sshd")
# 검색은 벡터 + 그래프 검색을 혼합하며, 별칭 해결이 적용됨 (Fancy Bear -> APT28)
for note in mm.recall("What tools does Fancy Bear use?", k=3):
print(f"[{note.metadata.tier}] {note.content.raw}")
위 코드는 외부 서비스 없이 pip install만으로 작동합니다. 임베딩은 fastembed를 통해 프로세스 내에서 실행됩니다(~80MB ONNX 모델이 첫 호출 시 다운로드됨). MemoryManager()는 기본적으로 ~/.amem/에 기록합니다. ZETTELFORGE_DATA_DIR 또는 구성을 통해 재정의 가능합니다. 실행 가능한 복사본은 examples/quickstart.py에 있습니다.
ollama pull qwen3.5:9b && ollama serve
# Ollama가 실행 중이면, synthesize()는 저장된 노트 전체에서 실제 요약을 반환
answer = mm.synthesize("Summarize known APT28 TTPs")
print(answer["synthesis"]["answer"])
# 백그라운드 LLM NER은 저장된 노트에 추가 엔터티를 더 풍부하게 함
ZettelForge는 Ollama를 자동 감지합니다. 다른 제공자(local llama-cpp, litellm 100개 이상 제공자, 테스트용 mock)를 사용하려면 구성을 참조하세요. LLM이 없으면 synthesize()는 여전히 구조화된 응답을 반환하지만 answer 필드는 대체 플레이스홀더입니다. pip 전용 모드에서는 remember와 recall만 유용한 결과를 생성합니다.
# 새로운 인텔리전스 도착 -- evolve=True는 메모리 진화 활성화:
# LLM이 사실을 추출하고, 기존 노트와 비교하여 ADD/UPDATE/DELETE/NOOP 결정
mm.remember(
"APT28 has shifted tactics. They dropped DROPBEAR and now exploit edge devices.",
domain="cti",
evolve=True, # 기존 APT28 노트는 대체되고, 중복되지 않음
)
모든 remember() 호출은 다음 파이프라인을 실행합니다:
모든 recall() 호출은 두 가지 검색 전략을 혼합합니다:
pip install zettelforge
프로젝트 루트에 .claude.json을 생성하거나 편집합니다(전역 접근을 위해서는 ~/.claude/.claude.json):
{
"mcpServers": {
"zettelforge": {
"command": "python3",
"args": ["-m", "zettelforge.mcp"]
}
}
}
ZettelForge가 가상 환경에 설치된 경우 해당 Python 인터프리터의 전체 경로를 사용하십시오:
{
"mcpServers": {
"zettelforge": {
"command": "/home/user/.venvs/zettelforge/bin/python",
"args": ["-m", "zettelforge.mcp"]
}
}
}
Claude Code를 시작하고 도구가 사용 가능한지 확인하십시오:
claude
# 세션 내에서 질문: "What tools do you have available from zettelforge?"
7가지 도구가 노출됩니다: zettelforge_remember, zettelforge_recall, zettelforge_synthesize, zettelforge_entity, zettelforge_graph, zettelforge_stats, zettelforge_sync(엔터프라이즈 패키지 필요). 전체 스키마, JSON-RPC 요청/응답 예제, 오류 코드, 지연 싱글톤 수명 주기는 MCP 프로토콜 참조를 참조하십시오. 문제 해결, 가상 환경 경로, 수동 도구 테스트는 MCP 서버 설정을 참조하십시오.
게재된 학술 벤치마크에 대해 평가됨:
점수 열은 Ollama 호스팅 모델로 실행된 ZettelForge 측정값을 보고합니다. 단, LOCOMO 행은 v2.1.1에서 평가 등급을 위해 Ollama 클라우드 판정기를 사용하여 재측정되었습니다(로컬 생성 아님). 벤치마크별 방법론, 버전 기록, 스위트별 판정기 구성은 전체 벤치마크 보고서를 참조하십시오.
Sigma 및 YARA 규칙은 일급 메모리 프리미티브입니다. 규칙을 파싱, 검증 및 수집하면 해당 태그가 그래프 엣지가 됩니다. MITRE ATT&CK 기술, CVE, 위협 행위자 별칭, 도구, 악성코드 패밀리는 다른 모든 노트와 동일한 온톨로지에 대해 해결됩니다. 공유된 DetectionRule 슈퍼타입은 SigmaRule과 YaraRule 하위 유형을 전달하므로, 단일 규칙 UUID가 두 형식 모두에서 주소 지정 가능합니다.
Sigma 규칙은 제공된 SigmaHQ JSON 스키마에 대해 검증됩니다. YARA 규칙은 plyara로 파싱되고 CCCS YARA 메타데이터 표준(계층: strict, warn, non_cccs)에 대해 확인됩니다. 수집은 멱등적입니다. 변경되지 않은 규칙을 다시 수집하면 콘텐츠 해시된 source_ref를 통해 원래 노트가 반환됩니다.
from zettelforge import MemoryManager
from zettelforge.sigma import ingest_rule as ingest_sigma
from zettelforge.yara import ingest_rule as ingest_yara
mm = MemoryManager()
ingest_sigma("rules/proc_creation_win_office_macro.yml", mm)
ingest_yara("rules/webshell_china_chopper.yar", mm, tier="warn")
# SigmaHQ 또는 개인 규칙 저장소에서 대량 수집
python -m zettelforge.sigma.ingest /path/to/sigma/rules/
python -m zettelforge.yara.ingest /path/to/yara/rules/ --tier warn
# CI 고정 장치 확인 -- 파싱 + 검증만 하며, 쓰지 않음
python -m zettelforge.sigma.ingest rules/ --dry-run
LLM 규칙 설명기(zettelforge.detection.explainer.explain)는 모든 DetectionRule에 대해 구조화된 JSON 요약(의도, 주요 필드, 회피 참고 사항, 오탐 가설)을 생성합니다. v1에서는 요청 시 동기적으로 실행됩니다. 비동기 보강 큐 연결은 v1.1에서 제공됩니다. ZETTELFORGE_EXPLAIN_RPM(기본값 60회 호출/분)을 통해 속도 제한.
참고 자료: Sigma 스펙, SigmaHQ 규칙, CCCS YARA, YARA 문서.
완료된 ATHF 헌트를 ZettelForge 메모리로 수집합니다. MITRE 기술과 IOC가 추출되어 지식 그래프에서 연결됩니다.
python examples/athf_bridge.py /path/to/hunts/
# 12개 헌트 파싱됨
# 12/12 헌트를 ZettelForge에 수집 완료
ThreatRecall은 엔터프라이즈 확장 기능이 활성화된 ZettelForge의 상용 배포판입니다. 기본적으로 관리형 SaaS로 제공되며, 분류 환경을 위한 선택적 자체 호스팅 온프레미스 및 에어갭 배포도 가능합니다. 엔터프라이즈 추가 기능:
SaaS는 유지 관리할 인프라 없이 몇 분 안에 배포됩니다. 자체 호스팅은 아웃바운드 네트워크 이그레스가 제한되거나 금지된 환경을 위한 배포 가능한 번들로 제공됩니다.
대기자 명단 참여 -- 현재 디자인 파트너 온보딩 중입니다.
모든 옵션은 config.default.yaml을 참조하십시오.
개발 설정은 CONTRIBUTING.md를 참조하십시오.
MIT -- LICENSE 참조.
Patrick Roland 제작 -- LinkedIn | Summit 7 Systems SOC 서비스 디렉터 | 해군 핵심 퇴역 군인 | CISSP, CCP(CMMC 2.0 Professional)
ZettelForge는 MIT 라이선스입니다. 저장소에 스타를 누르고, 이슈를 열고, PR을 제출해 주세요. 모든 기여를 환영합니다.
| 기능 | ZettelForge | Mem0 | Graphiti | Cognee |
|---|
| CTI 엔터티 추출 (CVE, 위협 행위자, IOC) | 예 | 아니요 | 아니요 | 아니요 |
| STIX 2.1 온톨로지 | 예 | 아니요 | 아니요 | 아니요 |
| 위협 행위자 별칭 해결 | 예 (APT28 = Fancy Bear) | 아니요 | 아니요 | 아니요 |
| 인과 삼중항이 포함된 지식 그래프 | 예 | 아니요 | 예 | 예 |
| 의도 분류 검색 (5가지 유형) | 예 | 아니요 | 아니요 | 아니요 |
| 프로세스 내 / 외부 API 불필요 | 예 | 아니요 | 아니요 | 아니요 |
| OCSF 스키마의 감사 로그 | 예 | 아니요 | 아니요 | 아니요 |
| MCP 서버 (Claude Code) | 예 | 아니요 | 아니요 | 아니요 |
| 벤치마크 | 측정 항목 | 점수 |
|---|
| CTI 검색 (CTIBench 하위 집합) | 귀속, CVE 연결, 다중 홉 | 75.0% |
| RAGAS | 검색 품질 (키워드 존재) | 78.1% |
| LOCOMO (ACL 2024) | 대화형 메모리 회상 | 22.0% |
| 변수 | 기본값 | 설명 |
|---|
AMEM_DATA_DIR | ~/.amem | 데이터 디렉터리 |
ZETTELFORGE_BACKEND | sqlite | SQLite 커뮤니티 백엔드. TypeDB는 확장을 통해 사용 가능. |
ZETTELFORGE_LLM_PROVIDER | local | local (llama-cpp) 또는 ollama |