kernel-memory

AI MemoryDevOpsC#

★ 2,233주당 +1

무엇인가

Kernel Memory(KM)는 문서 데이터셋을 하이브리드 파이프라인으로 인덱싱하고, 자연어 질의에 출처가 붙은 답을 돌려주는 멀티모달 AI 서비스다. 분류상 프레임워크에 가깝지만 실체는 검색 증강 생성(RAG) 파이프라인과 그 파이프라인을 감싼 웹 서비스의 묶음이다. 같은 저장소가 .NET 라이브러리, Docker 컨테이너, Web Service, ChatGPT·Copilot·Semantic Kernel용 플러그인이라는 네 가지 배포 형태를 함께 제공한다. 즉 애플리케이션 안에 라이브러리로 심을 수도 있고, 별도 프로세스로 띄워 HTTP로 호출할 수도 있다. 다루는 입력은 텍스트에 국한되지 않는다. 파일 포맷을 자동 인식해 텍스트를 뽑아내는 단계가 파이프라인 앞단에 들어 있어 PDF 같은 문서도 같은 흐름으로 처리된다. 결과물은 임베딩과 원문 청크이며, 질의 시점에는 LLM이 그 청크를 근거로 답을 생성한다. 저장소 설명이 강조하는 범위는 RAG, 합성 메모리, 프롬프트 엔지니어링, 사용자 정의 시맨틱 메모리 처리다.

어떻게 동작하나

RAG를 직접 구현하려면 문서 포맷 인식, 청킹, 임베딩 생성, 벡터 저장소 적재, 검색 결과 재조합, 프롬프트 구성, 출처 표시를 각각 따로 만들어야 한다. 이 조각들은 서로 다른 라이브러리와 서비스에 흩어져 있고, 모델이나 벡터 DB를 바꾸면 접착 코드를 다시 써야 한다. Kernel Memory는 이 접착 코드를 하나의 파이프라인 추상으로 고정한다. 임베딩 생성기와 벡터 인덱스를 교체 가능한 구성 요소로 두고, 그 사이의 흐름은 그대로 유지한다. 설계 동기는 특정 벡터 DB나 특정 LLM 제공자에 종속되지 않는 인덱싱 계층이다. 또한 인덱싱을 요청·응답 주기 밖으로 밀어낼 수 있게 했다. 큰 문서는 처리에 수 분이 걸릴 수 있으므로, 서비스 모드에서는 비동기로 적재하고 실패 시 재시도할 수 있는 구조를 택했다. 결과적으로 애플리케이션 코드는 무엇을 기억할지 정하고, 어떻게 저장하고 검색할지는 넘긴다. 이 분리는 언어 제약도 줄인다. 서비스로 띄우면 TypeScript, Java, Rust 같은 비 .NET 애플리케이션도 HTTP로 같은 메모리를 공유할 수 있다.

무엇과 다른가

적재 파이프라인은 네 단계로 정리된다. 첫째, 파일 포맷을 자동 인식해 텍스트를 추출한다. 둘째, 추출된 텍스트를 검색과 RAG 프롬프트에 넣기 좋은 작은 청크로 분할한다. 셋째, LLM 임베딩 생성기로 각 청크의 임베딩을 만든다. 넷째, 임베딩을 벡터 인덱스에 저장한다. 저장 위치는 고정되어 있지 않고 Azure AI Search, Qdrant를 비롯한 여러 DB 중에서 고른다. 검색 시점에는 질문을 같은 임베딩 공간으로 옮겨 가까운 청크를 찾고, 그 청크를 LLM 프롬프트에 넣어 답을 만든다. 이때 반환되는 답에는 인용과 원본 출처 링크가 함께 온다. 저장소가 하이브리드라고 부르는 부분은 추출·분할·임베딩·적재를 하나의 연속 파이프라인으로 묶고 사용자 정의 단계를 끼워 넣을 수 있다는 뜻이다. 청킹이 중요한 이유는 LLM 컨텍스트 한계와 검색 정확도가 동시에 걸려 있기 때문이다. 청크가 크면 프롬프트가 낭비되고, 작으면 문맥이 끊긴다. 파이프라인이 이 단계를 교체 가능하게 둔 것은 그래서다. 생성기를 바꾸면 벡터 공간이 달라지므로 인덱스를 다시 만들어야 한다.

어떻게 쓰나

배포 형태는 네 갈래다. 라이브러리로 쓸 때는 프로세스 내부에서 도는 MemoryServerless를 쓰고, 원격 호출이 필요하면 비동기·확장 가능한 Web Service로 띄운다. 서비스는 Docker 이미지 kernelmemory/service로도 배포된다. OpenAPI 스키마는 로컬 실행 시 http://127.0.0.1:9001/swagger/index.html 에서 확인한다. 설정은 appsettings.json을 기본값으로 두고 appsettings.Development.json으로 덮어쓰는 방식이다. cd service/Service 뒤에 dotnet run setup 을 실행하면 설정 마법사가 돈다. 데이터 조직화는 태그로 한다. 문서마다 소유자를 지정해 사설 정보를 보호하고, 검색 시 태그 필터로 부분집합만 대상으로 삼는다. 이 필터가 보안 경계 역할을 한다. 질의는 전체 메모리 집합을 대상으로 할 수도 있고, 필터로 좁힌 부분집합을 대상으로 할 수도 있다. 답변에는 토큰 사용량 보고서가 따라붙어, 어떤 질의가 컨텍스트를 얼마나 소모했는지 확인할 수 있다. .NET Aspire로 다른 프로젝트에 끼워 실행하는 경로도 README가 안내한다.

전제와 한계

같은 문제를 푸는 다른 방식과 비교하면 차이가 분명하다. 벡터 DB를 직접 쓰는 접근은 저장과 유사도 검색만 제공하므로, 포맷 인식·청킹·프롬프트 구성·출처 표시는 사용자가 만든다. 문서 로더와 벡터 스토어를 잇는 프레임워크들은 파이프라인을 코드로 조립하게 하지만, 서비스 엔드포인트와 플러그인 형태를 함께 주지는 않는다. Kernel Memory는 SDK와 서비스를 같은 저장소에서 제공해, 프로토타입은 라이브러리로 시작하고 운영은 컨테이너로 옮기는 경로를 만든다. Semantic Kernel·Copilot·ChatGPT 플러그인으로 동작한다는 점도 차이다. 다만 이 저장소는 아카이브된 연구 프로젝트이며, 코드는 학습 자료이지 프로덕션 소프트웨어가 아니라고 README가 명시한다. 지원이 제공되지 않으므로, 안정적 운영이 목적이면 같은 파이프라인을 직접 구현하거나 다른 기반을 검토해야 한다. 반대로 RAG 파이프라인의 구성 요소를 어떤 순서로 조립하고 어떤 인터페이스로 노출하는지 학습하려는 목적이라면, 이 저장소가 제공하는 참조 구현 자체가 결과물이다.

설정을 만들려면 `cd service/Service` 를 실행한 뒤 `dotnet run setup` 으로 설정 마법사를 돌린다. 그다음 Docker 이미지를 실행한다. Windows에서는 `docker run --volume .\appsettings.Development.json:/app/appsettings.Production.json -it --rm -p 9001:9001 kernelmemory/service` 이다. Linux / macOS에서는 `docker run --volume ./appsettings.Development.json:/app/appsettings.Production.json -it --rm -p 9001:9001 kernelmemory/service` 이다. 차이는 볼륨 경로 표기뿐이다. 호스트의 `appsettings.Development.json` 이 컨테이너 안 `appsettings.Production.json` 자리에 매핑되므로, 마운트 대상을 잘못 적으면 설정이 조용히 무시된다. Azure OpenAI, Azure Document Intelligence 같은 서비스를 쓰려면 기본값을 덮어쓸 `appsettings.Development.json` 을 직접 만들어야 한다. 기본값만 쓰면 OpenAI 구성으로 동작한다. 설정 항목이 맞지 않으면 서비스는 뜨지만 적재 단계에서 실패한다.

질의는 전체 메모리 집합을 대상으로 하거나 태그 필터로 좁힌 부분집합을 대상으로 한다. 문서마다 소유자를 지정하는 방식이므로 태그 설계가 곧 접근 제어 설계가 된다. 답변에는 인용과 원본 출처 링크가 붙고, LLM 생성 시 토큰 사용량 보고서가 함께 온다. README의 출력 예시는 Azure OpenAI gpt-4o(TextGeneration) 기준 입력 24356 토큰, 출력 103 토큰이다. 연동 경로는 배포 형태에 대응한다. .NET이면 MemoryServerless를 라이브러리로 심고, 다른 언어이거나 원격 호출이 필요하면 Web Service에 HTTP로 붙인다. ChatGPT·Copilot·Semantic Kernel에는 플러그인으로 붙는다. 서비스 모드는 비동기 적재를 전제로 하므로, 적재 요청과 결과 확인이 분리된 흐름을 애플리케이션이 감당해야 한다. 큰 문서는 처리에 수 분이 걸릴 수 있고 실패와 재시도가 전제로 깔린다.

README 첫머리는 이 저장소가 아카이브된 연구 프로젝트라고 선언한다. 코드는 학습 자료이고 프로덕션 소프트웨어가 아니며, 주의를 가지고 자기 책임 아래 사용하라고 적혀 있다. 지원은 제공되지 않는다. Microsoft의 공식 지원 제품이 아니라는 점도 명시된다. 따라서 여기서 얻는 것은 동작하는 서비스가 아니라 참조 구현이다. 기술적 전제도 따라온다. 임베딩과 LLM을 쓰므로 임베딩 생성기와 텍스트 생성 모델을 외부에서 공급해야 한다. 벡터 인덱스도 Azure AI Search, Qdrant 같은 외부 저장소 중에서 고르는 구조라 별도 인프라가 필요하다. 서비스 모드는 Docker 이미지를 실행하므로 컨테이너 런타임이 전제이고, 라이브러리 모드는 .NET 애플리케이션 안에서 돈다. 비 .NET 언어는 HTTP로 서비스에 붙는 경로만 열려 있다.

선택 기준은 목적에 따라 갈린다. RAG 파이프라인의 단계 구성과 인터페이스 설계를 학습하려는 목적이면 아카이브 상태가 걸림돌이 되지 않는다. 임베딩 생성기와 벡터 인덱스를 바꿔가며 실험하려는 목적도 맞는다. 언어가 .NET이 아니더라도 서비스로 띄워 HTTP로 호출할 수 있으므로, 여러 언어의 애플리케이션이 하나의 메모리를 공유하는 구성이 가능하다. 문서 적재가 오래 걸려 요청 주기 밖으로 빼야 하는 상황, 실패와 재시도가 필요한 상황도 서비스 모드를 쓸 이유가 된다. 반대로 안정적 운영과 지원이 필요한 상황이면 이 저장소는 답이 아니다. 같은 파이프라인을 직접 구현하거나 지원되는 다른 기반을 검토해야 한다. 벡터 저장과 유사도 검색만 필요하고 청킹·프롬프트 구성·출처 표시를 직접 만들 계획이라면 벡터 DB를 직접 쓰는 편이 계층이 적다. 라이브러리로 시작해 컨테이너로 옮기는 경로가 필요할 때 이 저장소의 구조가 참고가 된다.

관련 논문 5