All articles

A Human-Reviewed Knowledge Ingestion Pipeline

AI practiceRead in Chinese

Closing the Knowledge-Capture Loop

Background

At the start of this work, the knowledge base could only be updated through a Git push. Daily activity did not flow back into it automatically. The goal was a common pipeline from source content to a knowledge-base document, regardless of what triggered the update. This is often called a knowledge ingestion pipeline and is an important part of a RAG feedback loop.

This article records both the design and the implementation status reported in the original project notes. It is not a claim that every proposed source or user interface is currently available.

Core Abstraction

The input is a piece of content worth retaining. Whether it comes from a conversation, a code commit, or another event, the processing stages are the same:

Content source
  -> pipeline.capture(content, source_type, hint=None)
  -> Step 1: extract a structured summary with an LLM
  -> Step 2: locate related documents with RAG
  -> Step 3: decide where to write and preview the change
  -> Step 3.5: request human confirmation
  -> Step 4: merge content into a document
  -> rebuild the RAG index

Content Sources

Sourcesource_typePlanned triggerPhase in the design
Telegram bot conversationtg_session/note with a session IDPhase one
AI assistant conversationweb_sessionCapture button with a session IDPhase one proposal; frontend remained pending
Git commitgit_commitWebhook after push, using the commit diffPhase two; pending
Manual textmanual/note <text>, skipping step 1Phase one

Adding a source should require only an extraction adapter that normalizes its content for pipeline.capture(). The internal pipeline should not change.

Step 1: Extract the Content

The inputs are raw conversation history, a commit diff, or manually supplied text, together with source_type. The output is a structured summary of the main ideas, conclusions, and reusable knowledge. The proposed model was minimax-m2.1 to control cost. Manual text skips extraction because the user already supplied a summary. For a Git commit, the prompt should focus on technical decisions, architectural changes, and lessons learned.

Pass the summary to retriever.search_with_sources(). The capture-specific top_k setting was five by default; question answering used a separate default of three. Retrieval returns text, file paths, and similarity scores so the next step can consider existing documents instead of writing blindly.

Step 3: Decide Where to Write

The LLM receives the summary and the retrieved candidates, then chooses one of three actions:

  • update: <path> to extend an existing document, with a summary of proposed changes;
  • create: <path> to add a new document at a suggested location;
  • skip when the content is duplicate or too fragmentary.

The design suggested updating when similarity was high (above 0.7) and the new content was complementary; creating when similarity was low or the topic was new; and skipping when the knowledge was already covered. The proposed model was Claude Haiku. These thresholds were decision rules in the design, not evidence of measured accuracy.

Step 3.5: Human Confirmation

The Telegram bot sends a preview containing the summary, decision, target path, and proposed edits. The user confirms or cancels with an inline button. On confirmation the pipeline continues; on cancellation it stops. The design specified automatic cancellation after ten minutes without a reply.

Telegram was intended to be the single real-time notification and approval channel, even for capture initiated from a web assistant.

Step 4: Merge and Write

For an update, the LLM merges the summary into the existing document while retaining its structure and avoiding duplication. For a new document, it generates Markdown in the knowledge base's established style. The design assigned Claude Haiku to updates and minimax-m2.1 to new documents.

After a write, the GitHub API pushes the file to the repository. The deployment workflow rebuilds the RAG index and restarts the service. The plan also called for backing up an original document as .bak before a write and restoring it on failure.

Relationship to Existing Components

ComponentRole in capture
memory.pyProvides session history for Telegram and web conversations
retriever.search()Supplies retrieval functionality for locating related material
router.pyHolds model settings for each stage
robot.ask()Makes LLM calls
pipeline.pyOrchestrates capture separately from the existing ask() path
main.pyExposes the /note command

Triggers and Implementation Sequence

In phase one, /note captures the current session, while /note <summary> starts from manually supplied text and skips extraction. A proposed assistant button would call pipeline.capture() from a web session. In phase two, a webhook would provide a Git commit diff. That source was deferred until the core pipeline could be evaluated.

The source document's implementation table marked the capture() skeleton, /note, extraction, retrieval, write-location decision, Telegram confirmation, and merge/write flow as completed. It marked the web assistant button and Git commit source as pending. Those were the statuses recorded when the notes were written.

Key Decisions

Why Not Append to a Scratchpad?

Appending content to a temporary note leaves knowledge unplaced and gradually weakens the structure of the knowledge base. Deciding the destination during capture avoids creating a separate manual cleanup task.

Why Several LLM Steps?

One prompt handling extraction, retrieval, decision-making, and merging would have a large context and several responsibilities. Smaller steps are easier to debug independently and allow each model to be replaced without changing the whole pipeline.

Why Confirm Through Telegram?

Telegram was the existing real-time notification channel, and inline buttons made confirmation simple. A capture request from the assistant could use the same confirmation path instead of requiring a separate web approval interface.

A Human-Reviewed Knowledge Ingestion Pipeline | Xuhuan / Gelatoni