
Synthadoc: 최신성 탐지, 전체 감사 추적(Audit Trails), 그리고 4가지 내보내기 형식 - 추가 LLM 호출 없음
요약
Synthadoc v0.6.0은 지식 베이스의 노후화 문제를 해결하기 위해 5단계 페이지 생명주기 관리와 감사 추적 기능을 도입했습니다. 추가 LLM 호출 없이도 콘텐츠의 출처, 이력, 비용을 4가지 형식으로 내보낼 수 있는 시스템을 제공합니다.
핵심 포인트
- 5단계 페이지 생명주기를 통한 콘텐츠 최신성 자동 추적
- 추가 LLM 비용 없는 4가지 기계 판독 가능 내보내기 형식 지원
- 영구적인 감사 추적(Audit Trail)을 통한 데이터 신뢰성 확보
- 시스템 트리거 및 CLI 명령을 통한 유연한 상태 전환
자동화된 지식 시스템을 한동안 운영하다 보면 나타나는 특정한 유형의 문제가 있습니다. 첫 한 달은 마법처럼 느껴집니다. 페이지들이 스스로 컴파일되고, 인용(Citations)이 나타나며, 모든 것이 신선합니다. 3개월 후, 소스가 마지막으로 수집(Ingest)된 이후 세 번의 파괴적 버전(Breaking versions)이 출시된 라이브러리에 관한 페이지를 열게 됩니다. 페이지는 완벽하게 건강해 보입니다. 신뢰도(Confidence)는 "높음"입니다. 린트(Lint)도 통과했습니다. 하지만 그 안의 모든 내용은 조용히 잘못되어 있습니다.
정적 지식 베이스(Static knowledge bases)에는 "이것이 과거에 사실이었다"라는 것을 표현할 어휘가 없습니다. Synthadoc v0.6.0은 여러분의 위키(Wiki)에 그 어휘를 제공합니다.
Synthadoc v0.6.0 릴리스는 위키가 노후화되는 방식을 바꾸는 두 가지 기능을 제공합니다. 영구적인 감사 추적(Audit trail)과 함께 콘텐츠의 최신성을 추적하는 5단계 페이지 생명주기 머신(Five-state page lifecycle machine), 그리고 추가적인 LLM 호출 없이 콘텐츠뿐만 아니라 출처(Provenance), 이력(History), 비용(Cost)을 4가지 기계 판독 가능(Machine-readable) 형식으로 직렬화하는 **위키 내보내기 시스템(Wiki export system)**입니다.
5단계 페이지 생명주기 (The 5-State Page Lifecycle)
핵심 아이디어는 간단합니다. 모든 페이지는 단순히 페이지가 "말하는" 내용뿐만 아니라, 시스템이 현재 그 페이지에 대해 "알고 있는" 것을 반영하는 상태(Status)를 가집니다. 이 상태는 수집(Ingest), 린트(Lint), 그리고 소스 파일 자체에서 오는 신호에 따라 다섯 가지 상태를 거치며 이동합니다.
자동 전환 (시스템 트리거):
| 전환 (Transition) | 트리거 (Trigger) | 주체 (Who) |
|---|---|---|
→ draft | 수집(Ingest)을 통해 새 페이지 생성 | IngestAgent |
| ... |
**수동 전환 (사용자 CLI 명령):
| 명령 (Command) | 전환 (Transition) | 설명 (Description) |
|---|---|---|
lifecycle activate <slug> | draft → active | 다음 린트(lint) 실행을 기다리지 않고 승격 |
| ... |
참고: active → stale 및 stale → draft는 사용자에게 노출되는 CLI 명령어가 없으며, 각각 린트(lint)와 재수집(re-ingest)에 의해 시스템에 의해서만 트리거됩니다. contradicted 상태에서 벗어나는 유일한 경로는 아카이빙(archiving)하는 것뿐입니다. contradicted 상태의 페이지를 active로 직접 승격할 수는 없습니다.
자동이든 수동이든 모든 전환(transition)은 타임스탬프, 트리거를 발생시킨 에이전트(agent) 또는 사용자, 그리고 사유 문자열(reason string)과 함께 감사 데이터베이스(audit database)에 영구적으로 기록됩니다. 이 부분이 실제로 중요한 부분입니다. 상태(state)는 페이지가 어디에 있는지를 알려줍니다. 로그(log)는 페이지가 어떻게 그곳에 도달했는지 그리고 _누가 마지막으로 확인했는지_를 알려줍니다.
# 페이지의 전체 이력 확인
synthadoc lifecycle log alan-turing
...
시각적인 뷰를 선호한다면, 동일한 전체 위키 간 감사 추적(cross-wiki audit trail)을 Obsidian의 Synthadoc: Manage Page Lifecycle → Audit Log에서 확인할 수 있습니다. 모든 전환은 색상으로 구분된 From/To 상태 배지, 트리거를 발생시킨 에이전트 또는 사용자, 타임스탬프, 사유 문자열을 보여주며, 슬러그(slug)로 검색, 상태별 필터링, 페이지 나누기가 가능합니다:
플릿(fleet) 수준의 뷰를 보려면, synthadoc status를 통해 후보(candidates) 상태에 있는 페이지를 포함하여 5가지 모든 상태에 대한 실시간 요약을 확인할 수 있으며, 주의가 필요한 항목에 대한 작업 힌트(action hint)도 함께 제공됩니다:
synthadoc status
Wiki: history-of-computing
...
이 수치들이 무엇을 의미하는지에 대해 알아두어야 할 두 가지 사항이 있습니다. 첫째, 상단의 Pages: 42는 wiki/에 수락된 페이지들만 집계하며, wiki/candidates/에 격리(quarantined)되어 있는 페이지들은 해당 총계에서 제외됩니다. 둘째, draft와 draft (staged)는 서로 다른 행입니다. draft는 이미 wiki/ 내부에 있으며 첫 번째 린트(lint) 패스를 기다리는 페이지들을 의미합니다. 반면 draft (staged)는 wiki/candidates/에 물리적으로 격리되어 있으며, 아직 승격(promoted)되지 않아 생명주기 상태(lifecycle state)가 없고, 사람이 명시적으로 승격시키기 전까지는 시스템의 모든 부분에서 보이지 않는 페이지들을 의미합니다. 생명주기(lifecycle) 섹션은 draft (staged)의 개수가 0보다 클 때만 해당 행을 표시하므로, 스테이징(staging) 기능이 꺼져 있는 위키에서는 이 행을 볼 수 없습니다. 액션 힌트(action hints)는 각 그룹에 대해 다음에 무엇을 해야 하는지 정확히 알려줍니다: 초안(drafts)은 린트(lint)를 실행하고, 오래된(stale) 페이지는 재수집(re-ingest)하며, 모순(contradictions)이 있는 경우에는 검토 및 아카이브(archive)를 수행합니다.
생명주기 상태를 시각적으로 관리하는 것을 선호한다면, Obsidian 플러그인의 Synthadoc: Manage Page Lifecycle → Current States에서 동일한 데이터를 확인할 수 있습니다. 이 테이블은 상태별로 정렬 및 필터링이 가능하며, 마지막 상태 전환 타임스탬프와 이를 트리거한 사용자를 보여주고, 페이지당 원클릭 아카이브 버튼을 제공합니다. contradicted 칩을 사용하면 우선적으로 주의가 필요한 페이지를 쉽게 찾을 수 있습니다:
Candidates Staging: 생명주기가 시작되기 전의 품질 게이트 (Quality Gate)
생명주기 머신(lifecycle machine)은 페이지가 위키에 진입한 이후에 일어나는 일을 처리합니다. Candidates staging은 페이지가 진입할지 여부를 처리합니다.
새 페이지가 어디에 배치될지는 해당 위키에 설정된 스테이징 정책(staging policy)에 전적으로 달려 있습니다. 세 가지 옵션이 있습니다:
off(기본값): 모든 새 페이지가draft(초안) 상태로wiki/에 즉시 들어갑니다. 스테이징 (Staging) 과정이 포함되지 않습니다.all: 신뢰도 (confidence)와 관계없이 모든 새 페이지가wiki/candidates/로 이동합니다. 자동으로 승인되는 것은 없으며, 사용자가 모든 내용을 검토하고 승인(promote)해야 합니다.threshold: IngestAgent가 페이지의 신뢰도 등급을 설정된 최소 기준값과 비교하여 확인합니다. 기준을 충족하거나 초과하는 페이지는wiki/로 직접 이동하며, 기준 미달 페이지는 검토를 위해wiki/candidates/로 이동합니다.
wiki/candidates/는 검색, 컨텍스트 팩 (context packs), 그리고 내보내기 (export)에서 제외되는 대기 영역입니다. 하위 소비자 (downstream consumer)는 후보(candidate) 페이지를 볼 수 없습니다. 페이지가 디스크에는 존재하지만, 아직 라이프사이클 (lifecycle)에 편입되지 않았으므로 감사 로그 (audit log) 항목이 생성되지 않으며 synthadoc status 카운트에도 나타나지 않습니다.
threshold 정책 하에서 세 가지 경로가 전체적으로 어떻게 진행되는지는 다음과 같습니다:
여기서 핵심적인 설계 결정 사항은 스테이징 (staging)과 라이프사이클 (lifecycle)이 깔끔하게 결합되는 직교 시스템 (orthogonal systems)이라는 점입니다. 스테이징은 _편입 (admission)_을 결정하고, 라이프사이클은 편입 이후의 _상태 (state)_를 결정합니다. wiki/candidates/에 있는 페이지는 아직 라이프사이클 상태가 없으며, 감사 로그에 기록되지 않고, synthadoc status에 집계되지 않으며, 어떤 내보내기에도 나타나지 않습니다. 사용자가 페이지를 승인(promote)하는 순간, 해당 페이지는 draft 상태로 라이프사이클에 진입하며 다음 실행 시 린트 큐 (lint queue)가 이를 처리합니다.
이는 자동화된 수집 (ingestion) 과정에 인간의 검토 단계 (human gate)가 필요한 팀에게 매우 중요합니다. 야간 수집 작업은 새벽 2시에 실행되어 새로운 소스를 가져오고 페이지를 컴파일합니다. 이 모든 것들은 후보(candidates) 영역에 쌓입니다. 담당자는 아침에 목록을 검토하여 적절해 보이는 것은 승인하고, 그렇지 않은 것은 폐기합니다. 위키는 오직 검토된 콘텐츠로만 성장하게 됩니다.
# 임계값(threshold) 스테이징 활성화: 신뢰도가 높은 것은 자동 승인하고, 나머지는 대기
synthadoc staging policy threshold --min-confidence high
...
위키 내보내기: 4가지 형식, LLM 호출 제로
내보내기(Export)는 단 하나의 제약 사항을 중심으로 설계되었습니다: 위키가 컴파일(compile)되고 나면, 이를 직렬화(serialize)하기 위해 추가적인 API 예산을 더 이상 소비할 필요가 없어야 한다는 것입니다. 네 가지 형식 모두 저장된 위키 상태로부터 완전히 계산되며, 프롬프트(prompt), 완성(completion), 대기 시간이 전혀 필요하지 않습니다.
--status 플래그는 내보내기를 실질적으로 유용하게 만드는 핵심 요소입니다. 다운스트림(downstream) LLM에 데이터를 공급할 때, 아마도 린트(lint)를 통과하고 최신 상태를 유지하고 있는 active 페이지들만 필요할 것입니다:
synthadoc export --format llms.txt --status active
synthadoc export --format json --status active --output exports/wiki.json
--status contradicted 플래그는 포렌식(forensics) 용도로 진정 유용합니다. 충돌(conflict)이 있는 페이지들만 내보내어 위키의 나머지 부분은 건드리지 않고 분석할 수 있습니다.
JSON 형식은 특히 주목할 만한 가치가 있습니다. 대부분의 위키 내보내기는 평면적인 문서 덤프(flat document dump)를 제공합니다. 반면 이 형식은 문장 수준의 출처(provenance)(claims[]는 각 단락을 생성한 정확한 소스 파일과 라인 범위에 매핑함), 전체 상태 전이 이력(lifecycle_history[]), 그리고 컴파일에 소요된 페이지별 API 비용을 제공합니다. 만약 다운스트림 도구를 구축하거나 지식 품질에 대한 보고를 수행한다면, 이 세 가지 필드는 직접 구축해야 했을 계측(instrumentation) 계층 전체를 제거해 줍니다.
{
"slug": "alan-turing",
"status": "active",
...
무엇이 다른가
대부분의 LLM 위키 도구는 지식을 추가 전용(append-only)으로 취급합니다. 데이터를 수집(ingest)하고, 쿼리(query)할 뿐입니다. 페이지가 오래되어 쓸모없어지는(stale) 개념도 없고, 누가 무엇을 언제 검토했는지에 대한 감사 추적(audit trail)도 없으며, 당신이 읽고 있는 페이지가 3개월 전에 변경된 소스로부터 컴파일되었다는 사실을 알 방법도 없습니다. 이들은 사실상 채팅 인터페이스가 상단에 얹혀 있는 '한 번 쓰기(write-once)' 데이터베이스에 불과합니다.
Synthadoc의 라이프사이클 머신(lifecycle machine)은 위키를 _시간적으로 인지(temporally aware)_하게 만듭니다. 데이터 수집(ingest) 시점에 모든 소스에 대해 SHA-256 해시가 저장됩니다. 린트(lint)가 실행될 때(보통 매일 밤), 현재의 해시를 저장된 해시와 비교합니다. 소스가 변경되면 타임스탬프와 함께 active → stale 상태 전환이 자동으로 트리거됩니다. 여러분은 어떤 페이지에 주의가 필요한지, 그리고 해당 페이지가 마지막으로 유효했던 시점이 언제인지 정확히 알 수 있습니다.
Synthadoc을 아키텍처 측면에서 차별화하는 또 다른 점은, 이것이 생성 단계가 포함된 검색 파이프라인(retrieval pipeline)이 아니라 컴파일 파이프라인(compilation pipeline)이라는 것입니다. 모든 페이지는 검색된 청크(chunk)가 아니라 합성된 아티팩트(synthesized artifact)입니다. 그렇기 때문에 JSON 내보내기(export) 시 페이지당 ingest_cost_usd를 포함할 수 있습니다. 각 페이지는 누군가 질문을 던질 때마다 변하는 쿼리 시점(query-time)의 비용이 아니라, 개별적인 컴파일 이력을 가지고 있기 때문입니다.
라이프사이클 추적과 내보내기의 결합은 팀을 위해 실용적인 기능을 제공합니다. synthadoc export --format llms.txt --status active 명령을 실행하여 하위 에이전트(downstream agent)의 입력값으로 사용할 수 있으며, 이때 여러분은 에이전트에게 무엇을 전달하고 있는지 정확히 알 수 있습니다. 오래된 콘텐츠도, 모순되는 페이지도 없습니다. 오직 시스템이 검토 완료 및 일관성이 있다고 표시한 위키의 부분 집합(subset)만 전달됩니다.
빠른 데모
라이프사이클 머신이 작동하는 모습을 확인하는 가장 빠른 방법은 퀵스타트 가이드의 8단계입니다: Step 8 — Manage Page Lifecycle.
내보내기는 21단계입니다: Step 21 — Export Your Wiki.
두 단계 모두 '컴퓨터의 역사(history-of-computing)' 데모 위키로 작동하므로, 선택한 LLM 제공업체를 대상으로 약 10분 안에 로컬에서 전체 과정을 실행해 볼 수 있습니다:
git clone https://github.com/axoviq-ai/synthadoc.git
pip3 install -e ".[dev]"
synthadoc install history-of-computing --target ~/wikis --demo
...
Synthadoc이 유용하다고 느끼신다면, GitHub에서 Star를 눌러주세요. 이 프로젝트의 인지도를 유지하는 데 큰 도움이 됩니다: https://github.com/axoviq-ai/synthadoc.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기


