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
| Source | source_type | Planned trigger | Phase in the design |
|---|---|---|---|
| Telegram bot conversation | tg_session | /note with a session ID | Phase one |
| AI assistant conversation | web_session | Capture button with a session ID | Phase one proposal; frontend remained pending |
| Git commit | git_commit | Webhook after push, using the commit diff | Phase two; pending |
| Manual text | manual | /note <text>, skipping step 1 | Phase 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.
Step 2: Find Related Documents
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;skipwhen 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
| Component | Role in capture |
|---|---|
memory.py | Provides session history for Telegram and web conversations |
retriever.search() | Supplies retrieval functionality for locating related material |
router.py | Holds model settings for each stage |
robot.ask() | Makes LLM calls |
pipeline.py | Orchestrates capture separately from the existing ask() path |
main.py | Exposes 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.