TL;DR
Arkency는 회의·Slack·이메일·GitHub 같은 비정형 기록을 단일 ingestion endpoint로 모은 뒤 LLM Extraction으로 엔티티와 typed relation을 PostgreSQL 그래프에 축적하는 Planet Arkency를 구축했습니다. 폐쇄형 ontology가 허용된 노드와 관계를 제한하고, search_nodes·alias·trigram·bge-m3 embedding을 결합한 hybrid search가 같은 사람이나 프로젝트의 표기 변형을 하나로 연결합니다. 모든 변경은 before·after diff와 원문·도구 호출 read set을 함께 기록하며, 사람 검토와 충돌 감지를 거쳐 이벤트 소싱 파이프라인에서 적용됩니다. 거의 2000개 노드와 5200개가 넘는 엣지, 약 300회의 Extraction, 3600개가 넘는 이벤트가 쌓였고 MCP를 통해 외부 AI assistant에도 출처 기반 질의를 제공합니다.
섹션별 상세
# from config/ontology.yml
node_kinds:
- kind: person
description: "team member, candidate, client contact, external person"
- kind: decision
description: "formal decision requiring group verdict — for casual suggestions use idea"
edge_relations:
- relation: works_on
signature: "person --works_on--> project"YAML 온톨로지에서 허용된 노드 종류와 관계의 방향을 정의하는 부분입니다.

node = Node.find_or_initialize_by(name: data[:name])
enforce_status!(data[:name], data[:status], node) # raises when the model's new/existing claim disagrees with the DB
was_new = node.new_record?
node.assign_attributes(short_description: ..., description: ..., attrs: node.attrs.merge(attrs))
changes = node.changes.except("updated_at", "created_at", "kind", "slug")
{
op: was_new ? "create" : "update",
node_id: node.persisted? ? node.id : nil,
changes: changes
}LLM이 반환한 노드의 신규·기존 상태를 데이터베이스와 대조하고 dirty tracking으로 필드별 변경 내역을 만드는 코드입니다.

def self.hybrid_search(query, limit: 10)
# fuzzy match on canonical names and aliases, powered by pg_trgm
by_name = where("similarity(nodes.name, ?) > 0.3", query)
by_alias = joins(:aliases).where("similarity(node_aliases.name, ?) > 0.3", query)
trigram_results = union_by_best_similarity(by_name, by_alias)
response = RubyLLM.embed(query, model: "bge-m3", provider: :ollama)
semantic_results = nearest_neighbors(:embedding, response.vectors, distance: "cosine")
.select { |n| n.neighbor_distance < SEMANTIC_THRESHOLD }
merge_and_rank(trigram_results, semantic_results, limit)
end정확한 문자열 유사도와 의미적 embedding 검색 결과를 합치고 순위를 매기는 노드 검색 함수입니다.


chat = RubyLLM
.chat(model: MODEL)
.with_params(tools: [
{ type: "web_search_20250305", name: "web_search", max_uses: 10 },
{ type: "web_fetch_20250910", name: "web_fetch", max_uses: 10 }
])
.with_schema(ResearchBriefSchema.build)그래프의 특정 노드를 대상으로 Anthropic의 server-side web_search와 web_fetch를 사용하는 Research 작업을 구성합니다.
용어 해설
- 지식 그래프(Knowledge Graph)
- — 지식 그래프는 사람·프로젝트·결정 같은 엔티티를 노드로 저장하고, 엔티티 사이의 의미 있는 관계를 타입이 지정된 엣지로 연결하는 구조입니다. 문장 속 사실을 데이터로 바꾸므로 관계를 검색·순회·집계할 수 있으며, 이 글에서는 조직의 기록을 지속적으로 축적하고 출처까지 추적하는 기반으로 사용됩니다.
- 온톨로지(Ontology)
- — 온톨로지는 그래프에 허용할 노드 종류와 관계 종류를 정의한 어휘 체계입니다. Planet Arkency는 YAML 파일에 정의된 폐쇄형 온톨로지를 Extraction 프롬프트와 스키마의 enum으로 주입해 LLM이 임의의 타입을 만들지 못하게 합니다. 덕분에 그래프의 분류 체계가 빠르게 무너지는 문제를 줄입니다.
- 식별자 해소(Identity Resolution)
- — 식별자 해소는 서로 다른 표기나 오탈자가 같은 엔티티를 가리키는지 판별하고 하나의 노드로 통합하는 과정입니다. 시스템은 검색 도구, canonical name과 alias, trigram·embedding을 결합한 hybrid search로 이 작업을 수행합니다. 이 과정이 실패하면 한 사람이 여러 노드로 쪼개져 그래프의 신뢰도가 떨어집니다.
- 이벤트 소싱(Event Sourcing)
- — 이벤트 소싱은 상태 자체보다 상태 변화를 나타내는 불변 이벤트를 기록하고, 그 이벤트에서 현재 상태와 화면용 read model을 재구성하는 방식입니다. 이 시스템은 수집·Extraction·변경 제안·적용·충돌을 이벤트 흐름으로 연결합니다. 각 사실의 생성·수정 경로와 적용 당시 상태를 되짚을 수 있다는 점이 핵심입니다.
- 데이터 계보(Provenance)
- — 데이터 계보는 그래프의 각 사실이 어떤 입력과 처리 과정에서 만들어졌는지 추적하는 정보입니다. 노드·엣지와 Extraction 사이의 조인 테이블에 작업 유형, 상태, 필드별 변경 내역을 저장하고, 도구 호출 결과도 read set으로 남깁니다. 따라서 특정 병합이나 수정의 근거를 원문과 모델의 조회 결과까지 거슬러 올라갈 수 있습니다.
- 프롬프트 캐싱(Prompt Caching)
- — Prompt Caching은 여러 차례의 LLM 호출에서 반복되는 시스템 프롬프트와 입력 콘텐츠를 캐시해 후속 라운드의 토큰 처리 비용을 낮추는 기능입니다. 이 글의 Extraction은 도구 호출이 끼어든 여러 라운드에서도 같은 프롬프트와 콘텐츠를 재사용합니다. 그 결과 대부분의 입력 토큰이 cache-read 요율로 청구되고, 작성자의 Extraction 대부분이 1달러보다 낮은 비용으로 처리됩니다.
기술
- Planet Arkency
- Rails Event Store
- PostgreSQL
- RubyLLM
- Ruby
- Rails
- Zapier
- n8n
- pg_trgm
- GIN indexes
- bge-m3
- Ollama
- pgvector
- Anthropic
- MCP
활용 사례
- 회의·Slack·이메일·GitHub 기록을 조직 지식 그래프로 축적
- 사람·프로젝트·결정·도구 사이의 관계 검색과 탐색
- LLM이 제안한 그래프 변경을 사람 검토 후 적용
- 엔티티별 웹 Research와 출처 기반 지식 갱신
- MCP를 통한 외부 AI assistant의 조직 지식 질의
AI 요약 · 북마크 · 개인 피드 설정 — 무료
출처 · 인용 안내
인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.

