아카이브된 그래프 데이터베이스를 포크하여 헬스케어 AI를 꿈꾸기 시작하다
요약
Kùzu 그래프 데이터베이스를 포크하여 헬스케어 AI 엔진으로 발전시키려는 소프트웨어 엔지니어의 프로젝트 과정을 다룹니다. C/C++ API 확장, 벡터 인덱스 통합, LLM 임베딩 지원 등을 통해 임상 분석을 위한 아키텍처를 구축하는 로드맵을 제시합니다.
핵심 포인트
- Kùzu DB를 기반으로 한 헬스케어 특화 그래프 엔진 'Gorgonzola' 개발
- uint128_t 지원 및 바이너리 데이터 처리를 위한 C/C++ API 확장
- HNSW 벡터 인덱스 및 다양한 LLM 임베딩 API 통합
- 그래프 알고리즘을 확장 기능 시스템으로 래핑하여 활용
저는 아카이브된 그래프 데이터베이스를 가져와 벡터 검색 (vector search), LLM 임베딩 (LLM embeddings), 그리고 전체 GDS 스위트 (GDS suite)를 추가했습니다. 이제 이를 헬스케어 AI를 위한 핵심 엔진으로 만드는 것을 목표로 하고 있습니다. 여기 그 아키텍처 (architecture)와 로드맵 (roadmap), 그리고 이것이 왜 임상 분석 (clinical analytics)을 위한 올바른 토대라고 믿는지에 대해 설명합니다.
한 달 전, 저는 아카이브된 임베디드 분석용 그래프 데이터베이스인 Kùzu를 발견했습니다. 호기심이 생겨 이를 포크 (fork)하고 이것저것 살펴보기 시작했습니다. 저는 이것을 처음부터 새로 만든 것이 아닙니다. 핵심 엔진의 힘든 작업을 수행한 원작자들의 어깨 위에 올라서 있는 것입니다. 지금까지 저의 기여는 미미합니다. 몇 가지 C++ API 확장 (extensions), 약간의 파서 (parser) 수정, 그리고 유용할 것 같다고 생각한 몇 가지 확장 기능들입니다.
이것은 매우 학습적인 프로젝트입니다. 저는 데이터베이스 전문가는 아닙니다. 저는 시스템 구축을 즐기고 그래프 (graphs), AI, 그리고 헬스케어 (healthcare)의 교차점에 매료된 소프트웨어 엔지니어입니다. 이 포스트는 제가 지금까지 이해한 내용, 잠재력을 보는 지점, 그리고 여전히 어려움을 겪고 있는 부분들을 기록하려는 시도입니다.
2. 제가 실제로 한 일 (솔직하게)
솔직히 말씀드리겠습니다: 저는 데이터베이스 엔진을 작성하지 않았습니다. Kùzu 팀은 컬럼형 저장소 (columnar storage), OpenCypher 쿼리 프로세서 (query processor), ACID 트랜잭션 관리자 (transaction manager), 그리고 벡터화된 실행 엔진 (vectorized execution engine)을 구축하는 데 수년을 보냈습니다. 그것은 박사급 수준의 작업이며, 저는 이를 깊이 존경합니다.
제가 Gorgonzola (저의 포크)에 실제로 기여한 내용은 다음과 같습니다:
C/C++ API 확장 (API Extensions) (제가 실제로 작성한 코드):
uint128_t지원 –int128_t및uuid와 함께 산술, 비교, 캐스트 (cast) 연산자를 포함한 완전한 128비트 부호 없는 정수 (unsigned integer) 타입을 추가했습니다.gorgonzola_value_get_blob_with_size– 기존의get_blob은 첫 번째\0에서 바이너리 데이터를 잘라냈습니다. 이 API는 전체 버퍼와 그 바이트 길이를 반환합니다. 작은 수정이지만, 바이너리 데이터에는 매우 중요합니다.- 파서 (Parser) 미세 조정 – 숫자 리터럴에서 앞자리에 오는 0을 허용하도록 Cypher 문법을 수정했습니다 (
00123이 이제 유효합니다). 벡터 함수 시그니처 (function signatures)를 전반적으로 표준화했습니다.
기존 알고리즘을 확장 기능으로 래핑 (Wrapped):
- PageRank, 매개 중심성 (Betweenness Centrality), WCC, SCC, Louvain, K-Core Decomposition, Spanning Forest.
- 이러한 알고리즘 구현의 대부분은 이미 코드베이스에 있었거나 표준 교과서적인 내용입니다. 저는 단지 그것들을 확장 기능 시스템에 통합했을 뿐입니다.
제3자 라이브러리 통합:
- HNSW 벡터 인덱스 (vector index) (기존 라이브러리 사용) – 근사 최근접 이웃 (approximate nearest-neighbor) 검색을 위함입니다.
- LLM 임베딩 생성 (embedding generation) – 외부 API (OpenAI, Google Gemini, Vertex AI, Amazon Bedrock, Voyage AI, Ollama)를 호출하고 결과를 부동 소수점 배열 (float arrays)로 저장합니다.
- DuckDB, Iceberg, Delta Lake, PostgreSQL 커넥터 – 기존 라이브러리 위에 얹은 얇은 계층 (thin layers)이며, 깊은 통합은 아닙니다.
제가 절대 작성하지 않은 것들:
- 핵심 그래프 엔진 (core graph engine), 컬럼형 저장소 (columnar storage), OpenCypher 쿼리 프로세서 (query processor), 트랜잭션 관리자 (transaction manager), 압축 서브시스템 (compression subsystem), 또는 확장 기능 로딩 프레임워크 (extension loading framework).
저는 잠자고 있던 프로젝트의 먼지를 털어내고, 약간의 접착제 (glue)를 더해 새로운 이름을 붙여준 사람입니다. 저는 그것으로 만족합니다.
3. 더 빠르게 움직이기 위해 AI를 사용하는 방법 (투명성)
저는 AI 어시스턴트를 광범위하게 사용합니다. 저는 C++ 전문가가 아니며, 코드베이스는 수십만 줄에 달할 정도로 방대합니다.
AI가 저를 위해 하는 일은 다음과 같습니다:
-
스캐폴딩 (Scaffolding) – 새로운 GDS 알고리즘을 등록하거나 확장을 추가해야 할 때, 산더미 같은 상용구 코드(Boilerplate, CMake 파일, 함수 등록, bind/exec 패턴 등)가 존재합니다. 저는 AI로 뼈대를 생성하고 로직은 직접 채워 넣습니다.
-
반복적인 코드 (Repetitive code) – 시리얼라이저 (Serializers), 복사 생성자 (Copy constructors), 테스트 스텁 (Test stubs), 설정 구조체 (Configuration structs) 등입니다. 지루하지만 필수적인 작업들입니다. AI는 이 작업을 잘 수행합니다.
-
리팩토링 제안 (Refactoring suggestions) – 코드베이스의 복잡한 부분을 이해하지 못할 때, AI에게 설명을 요구하고 개선 사항을 제안하도록 합니다. 때로는 정확하고 때로는 환각 (Hallucination)을 일으키기도 하지만, AI는 항상 저의 학습 속도를 높여줍니다.
-
문서화 및 예제 (Documentation and examples) – 예제 Cypher 쿼리와 사용법 문서를 작성하는 일은 AI를 통해 빠르게 처리하며, 이를 반복적으로 수정하며 완성합니다.
핵심 규칙: 저는 AI가 생성한 코드를 결코 맹목적으로 커밋하지 않습니다. 모든 코드는 반영되기 전에 검토, 테스트 및 이해 과정을 거칩니다. AI는 저의 주니어 페어 프로그래머 (Junior pair programmer)입니다. AI가 단순 반복 작업 (Grunt work)을 수행하면, 저는 아키텍처, 정확성, 그리고 "이것이 실제로 말이 되는가?"에 대한 결정을 내립니다.
이러한 접근 방식은 혁신적이었습니다. 헤더 파일을 읽는 데 몇 주가 걸렸을 작업을 이제는 며칠 만에 끝낼 수 있습니다. 역설적이게도, AI의 모든 제안을 검증해야 하기 때문에 코드베이스에 대해 더 많이 배우게 되었습니다.
4. 비전 – 왜 헬스케어인가?
어느 시점에 저는 더 큰 그림을 생각하기 시작했습니다. 헬스케어 데이터는 근본적으로 그래프입니다:
- 환자는 인카운터 (Encounters)를 가집니다.
- 인카운터는 진단 (Diagnoses), 약물 (Medications), 관찰 (Observations), 처치 (Procedures)를 포함합니다.
- 의료 제공자 (Providers)와 기관 (Organizations)은 리퍼럴 네트워크 (Referral networks)를 형성합니다.
- 약물-질병 상호작용, 동반 질환 패턴 (Comorbidity patterns), 질병 경로 (Disease pathways)는 모두 네트워크입니다.
모든 환자의 여정은 시계열 그래프 (Temporal graph)입니다. 그럼에도 불구하고, 대부분의 헬스케어 분석 파이프라인은 관계형 데이터베이스 (Relational databases)에서 데이터를 파이썬 (Python)으로 내보내고, 메모리 상에서 그래프를 재구성한 뒤, 분석을 실행하고 데이터를 버려버립니다.
만약 그래프 데이터베이스 자체가 분석 엔진이라면 어떨까요?
데이터를 내보내지 않고도 동일한 데이터베이스 내에서 의료진 추천 네트워크(provider referral network)에 대한 PageRank를 실행하고, 임상 노트(clinical notes)의 LLM 임베딩(embeddings)을 생성하며, 벡터 유사성(vector similarity)을 통해 유사한 환자를 검색하고, 치료 경로(treatment pathways)를 탐색할 수 있다면 어떨까요?
Gorgonzola는 이미 오늘날 이러한 기능의 일부를 수행할 수 있습니다. 하지만 저는 한 명의 개인이 프로덕션급(production-grade) 헬스케어 플랫폼을 구축할 수는 없다는 점을 충분히 인지하고 있습니다. 제가 스케치한 로드맵(FHIR 파서, 의료 용어, GNN 추론, 시계열 쿼리)은 열망적인 목표입니다. 이를 위해서는 팀과 수년간의 지속적인 노력이 필요할 것입니다.
그럼에도 불구하고, 이 아키텍처는 매우 매력적입니다. 수백만 명의 환자와 수십억 개의 이벤트를 다룰 때는 데이터-투-컴퓨트(data-to-compute) 방식보다 컴퓨트-투-데이터(compute-to-data) 방식이 훨씬 유리합니다. 따라서 저는 이 비전을 완성된 제품이 아니라, 하나의 시작점으로 공유하고자 합니다.
5. 현재 작동하는 것들 (솔직하게)
작동함 (어느 정도까지):
| 기능 | 상태 |
|---|---|
| 그래프 탐색을 포함한 OpenCypher 쿼리 | ✅ 안정적 – Kùzu로부터 상속됨 |
| ... |
**작동하지 않음 (아직):
| 격차(Gap) | 상태 |
|---|---|
| 네이티브 FHIR/HL7 파싱 | ❌ 실험 중 – C++ 생태계가 존재하지 않음 |
| ... |
이것은 개념 증명(proof of concept)이자 학습 프로젝트이며, Neo4j나 TigerGraph를 대체하기 위한 것이 아닙니다.
6. 로드맵 (현실 점검)
다음은 열망적인 로드맵입니다. 강조하고 싶은 점은, 이것은 **희망 목록(wishlist)**이지 확정된 약속이 아니라는 것입니다.
| 단계 | 중점 사항 | 가능해지는 것 |
|---|---|---|
| 1 (현재) | 그래프 분석 + 벡터 검색 + LLM 임베딩 | 기본적인 임상 그래프 분석, 구조화/비구조화 하이브리드 쿼리 |
| ... |
헬스케어 분야에서의 가장 큰 차별점은 단순히 GNN을 하나 더 추가하는 것이 아닐 것입니다. 그것은 Gorgonzola를 **그래프 네이티브 임상 분석 플랫폼(graph-native clinical analytics platform)**으로 만드는 것입니다. 즉, 데이터베이스를 떠나지 않고도 FHIR 번들(bundle)을 수집하고, 이를 환자 그래프에 매핑하며, 동반 질환(comorbidities)에 대한 커뮤니티 탐지(community detection)를 실행하고, 임상 노트의 임베딩을 생성하며, 재입원 위험을 예측할 수 있는 플랫폼 말입니다.
그러한 조합은 현재 어떤 그래프 데이터베이스에도 존재하지 않습니다.
7. 제가 도움을 받고 싶은 부분
여기까지 읽으셨고 다음 중 흥미로운 내용이 있다면—함께 이야기해 봅시다.
- 헬스케어 데이터 엔지니어 (Healthcare data engineers) – 실제 환경의 FHIR/OMOP 인제스션 (ingestion) 요구사항을 이해하는 데 도움이 필요합니다.
- 그래프 알고리즘 연구자 (Graph algorithm researchers) – 특히 C++로 Node2Vec 또는 시계열 그래프 알고리즘 (temporal graph algorithms)을 구현해 본 분이라면 더욱 좋습니다.
- GNN 실무자 (GNN practitioners) – 데이터베이스 내부 추론 (in-database inference)이 실제로 유용할까요, 아니면 PyG/DGL로 내보내는 것이 항상 더 나은 워크플로우 (workflow)가 될까요?
- FHIR 파서 빌더 (FHIR parser builders) – 이는 C++ 생태계에서 아직 채워지지 않은 공백처럼 보입니다. 직접 구축해야 할까요, 아니면 Java와 브릿지 (bridge)를 연결해야 할까요?
- ** tinkerer (Tinkerers, 실험가)** – 확장 시스템이 잘 설계되어 있습니다. 새로운 알고리즘을 추가하는 것은 약 200줄 정도의 작업입니다.
8. 참여하기
이 내용이 공감된다면—레포지토리 (repo)에 스타 (star)를 누르거나, 이슈 (issue)를 생성하거나, 그냥 메시지를 보내주세요. 모든 분께 답장합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기