Company Knowledge Base — Privacy-Safe Compilation Pipeline
Bodit · 2026.07 – present · Designed, built & operated solo · Ingest & de-id running · weekly compile paused
- Python
- GPU NER
- Claude API
- cron
A knowledge base where an LLM compiles and maintains internal conversations. Answers come from compiled documents, not from retrieval over raw text.
- 12-channel ingestinternal messenger
- Two de-identification layersregex + GPU NER
Identification numbers never leave in plaintext; farm names become one-way hash codes. Over-masking of public institutions was loosened
- LLM compilationraw text → maintained documents
- Human review & mergeNER accuracy 90–95%
The point where I decided not to automate the final gate on personal data
- Wiki
- Agent queriesanswers only from compiled docs
Compilation is automated only up to a draft branch. A human merges, and success is announced too — a silent success is just another stall.
Problem
The answers were in accumulated internal conversations, but nobody could find them. The usual prescription is to embed the raw conversations and retrieve over them. The trouble is that raw conversation contradicts itself, gets reversed, and drops context. Answering from unverified raw text produces confident wrong answers.
And those conversations carry identifiers for people, farms and animals. They could not be sent to an external LLM as-is.
What I did
I went with compilation rather than retrieval. Answers do not come from the raw text; they come from documents an LLM reads the raw text to maintain.
Pipeline: channel ingest → two de-identification layers (regex + GPU NER) → LLM compilation → wiki → agent queries
- Tuned de-identification precision in both directions. Plaintext identification numbers went from 181 to 0, and farm names became one-way hash codes (135 unique) instead of collapsing into a single placeholder, so documents can still tell them apart. In the other direction, I loosened rules that masked things that should stay visible — a public livestock-grading agency was being masked as a farm because its name contains “livestock”. Over-masking makes the documents useless. Both directions were written down as rules and pinned with 20 regression asserts.
- Automated compilation as a weekly batch. Manual compilation had sat stalled for two weeks, and in the meantime answers had quietly degraded to unverified raw text. Automation stops at a draft branch, and success sends an alert too.
- Decided that final review and merge stay human. NER accuracy sits at 90–95%, so automating the last gate on personal data was not the right call.
Result
The line between what gets automated and what a human catches was drawn with an accuracy number, not a hunch.
The first backlog compile (12 min · $7.34) took the wiki from 5 to 13 pages, and review found 0/6 personal-data leaks. Questions are answered by citing compiled pages, not by searching raw text. Ingest and de-identification still run daily; only the paid weekly compile is paused for now. The most important decision in this project was drawing the line between what gets automated and what a human catches using an accuracy number, not a hunch.
홍길동, this is an alert for COW-000000 at 한빛농장. Contact 010-0000-0000 or farm@example.com.
Identifiers remain — transmission to external LLM blocked
Regex catches identifiers with fixed shapes — phone, email, animal ID. Names and farm names have no shape and are only knowable from context, which is why a separate NER layer exists. The sample is fabricated, shaped like the real thing; the person and farm names stay in Korean because the pipeline runs on Korean text.
Measurement
- Subject
- Conversations across 12 internal messenger channels
- Sample
- First backlog compile — 12 min · $7.34 · 5 → 13 pages
- Verification
- NER accuracy sits at 90–95%, so the final gate on personal data is not automated — human review is kept. Review found 0/6 personal-data leaks
Every de-identification rule change was judged on precision and over-masking together. Looking at only one side either makes the documents useless or lets identifiers leak.