Skip to content

Conversation

@huanghuoguoguo
Copy link
Collaborator

@huanghuoguoguo huanghuoguoguo commented Feb 9, 2026

Overview

This PR implements the RAG Engine Plugin Architecture for LangBot, enabling third-party plugins to provide custom RAG (Retrieval-Augmented Generation) implementations. This is a major architectural refactor that unifies the previously separate "internal" and "external" knowledge base concepts.

Related

Supersedes #1960. Closed and reopened from main repository branch as maintainer.

Key Changes

1. Unified Knowledge Base Model

  • Removed the internal/external knowledge base distinction
  • All knowledge bases now use a single KnowledgeBase entity with rag_engine_plugin_id field
  • UI simplified to a single unified list (removed Internal/External tabs)

2. RAGEngine Plugin Component

  • New RAGEngine component type for plugins
  • Capability-based feature detection (doc_ingestion, chunking_config, rerank, hybrid_search)
  • Dynamic form schemas for creation and retrieval settings

3. RPC Action Protocol

New actions for plugin-host communication:

Action Direction Description
RAG_KB_CREATED Host → Plugin Notify when KB is created
RAG_KB_DELETED Host → Plugin Notify when KB is deleted
RAG_INGEST_DOCUMENT Host → Plugin Request document ingestion
RAG_RETRIEVE Host → Plugin Request document retrieval
RAG_DELETE_DOCUMENT Host → Plugin Request document deletion
RAG_EMBED_DOCUMENTS Plugin → Host Request batch text embedding
RAG_EMBED_QUERY Plugin → Host Request query text embedding
RAG_VECTOR_UPSERT Plugin → Host Upsert vectors to VDB
RAG_VECTOR_SEARCH Plugin → Host Search vectors in VDB
RAG_VECTOR_DELETE Plugin → Host Delete vectors from VDB
RAG_GET_FILE_STREAM Plugin → Host Get file content from storage

4. New API Endpoints

GET /api/v1/knowledge/engines - List available RAG engines
GET /api/v1/knowledge/engines//creation-schema - Get creation form schema
GET /api/v1/knowledge/engines//retrieval-schema - Get retrieval form schema

5. RAGRuntimeService

New service bridging plugin requests to LangBot infrastructure (embedding models, vector database, file storage).

Breaking Changes

  • API: Removed /api/v1/knowledge/external-bases endpoints
  • Database: ExternalKnowledgeBase table dropped; new columns added to KnowledgeBase
  • Frontend: Internal/External tabs removed; unified list view
  • Plugin SDK: KnowledgeRetriever component deprecated, use RAGEngine instead

File Changes Summary

Added

  • src/langbot/pkg/rag/service/runtime.py - RAGRuntimeService
  • src/langbot/pkg/api/http/controller/groups/knowledge/engines.py - Engine API
  • src/langbot/pkg/persistence/migrations/dbm019_rag_engine_plugin_architecture.py - DB migration

Modified

  • src/langbot/pkg/rag/knowledge/kbmgr.py - Plugin communication integration
  • src/langbot/pkg/plugin/handler.py - RAG action handlers
  • src/langbot/pkg/plugin/connector.py - RAG connector methods
  • src/langbot/pkg/api/http/service/knowledge.py - Capability-based checks
  • src/langbot/pkg/entity/persistence/rag.py - Updated KB entity
  • web/src/app/home/knowledge/ - Unified UI components

Deleted

  • src/langbot/pkg/rag/knowledge/external.py
  • src/langbot/pkg/api/http/controller/groups/knowledge/external.py
  • src/langbot/pkg/api/http/service/external_kb.py
  • src/langbot/pkg/rag/knowledge/services/ (old service implementations)
  • web/src/app/home/knowledge/components/external-kb-*/

Migration Notes

  1. Existing external knowledge bases need manual recreation using the new unified interface
  2. Install a RAG engine plugin (e.g., langbot-plugin-rag) to use built-in RAG features
  3. API consumers should migrate from /external-bases to /bases endpoints

Checklist

  • Unified knowledge base model
  • RAGEngine component support
  • RPC action protocol
  • RAGRuntimeService implementation
  • New API endpoints
  • Frontend UI unification
  • Database migration
  • Code review fixes

huanghuoguoguo and others added 26 commits January 26, 2026 07:18
…dgeBase

BREAKING CHANGE: RAGPluginAdapter has been removed. All plugin
communication is now handled directly by RuntimeKnowledgeBase.

Architecture change:
- Before: RuntimeKnowledgeBase → RAGPluginAdapter → plugin_connector
- After:  RuntimeKnowledgeBase → plugin_connector (direct)

Changes to kbmgr.py (RuntimeKnowledgeBase):
- Remove RAGPluginAdapter import and usage
- Inline plugin communication methods:
  - _on_kb_create(): Notify plugin when KB is created
  - _on_kb_delete(): Notify plugin when KB is deleted
  - _ingest_document(): Call plugin for document ingestion
  - _retrieve(): Call plugin for retrieval
  - _delete_document(): Call plugin to delete document
- Simplify dispose(): Only notify plugin, no built-in VDB assumption

Changes to base.py (KnowledgeBaseInterface):
- Remove get_type() abstract method (outdated internal/external concept)
- Add get_rag_engine_plugin_id() abstract method

Changes to localagent.py:
- Remove get_type() call
- Simplify top_k retrieval from KB entity

Deleted files:
- pkg/rag/knowledge/plugin_adapter.py

Benefits:
- Reduced abstraction layer, simpler code
- Plugin communication logic centralized in RuntimeKnowledgeBase
- Easier to understand and maintain

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BREAKING CHANGE: ExternalKnowledgeBase has been completely removed.
All knowledge bases are now unified under the single KnowledgeBase model,
differentiated by their rag_engine_plugin_id.

Deleted files:
- pkg/api/http/controller/groups/knowledge/external.py
  (ExternalKBController with /external-bases routes)
- pkg/api/http/service/external_kb.py
  (ExternalKnowledgeBaseService)
- pkg/rag/knowledge/external.py
  (ExternalKnowledgeBase implementation)

Modified files:
- pkg/entity/persistence/rag.py:
  Remove ExternalKnowledgeBase SQLAlchemy table definition
- pkg/core/app.py:
  Remove external_kb_service attribute from LangBotApplication
- pkg/core/stages/build_app.py:
  Remove external_kb_service initialization

Migration notes:
- Existing external knowledge base data should be migrated manually
- API consumers should use /api/v1/knowledge/bases for all KB operations
- Use /api/v1/knowledge/engines to discover available RAG engines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove deprecated list_knowledge_retrievers functionality from the
plugin communication layer. This aligns with the SDK change that
removed the LIST_KNOWLEDGE_RETRIEVERS action.

Changes:
- connector.py: Remove list_knowledge_retrievers() method
- handler.py: Remove list_knowledge_retrievers() handler

The functionality is replaced by the new /api/v1/knowledge/engines
endpoint which lists available RAGEngine components with their
capabilities and configuration schemas.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace type-based checks with capability-based checks for file
operations, aligning with the unified knowledge base architecture.

Changes to knowledge.py:
- store_file(): Replace get_type() check with doc_ingestion capability check
- delete_file(): Replace get_type() check with doc_ingestion capability check
- list_rag_engines(): Remove list_knowledge_retrievers call, simplify to
  only list RAGEngine components (KnowledgeRetriever type removed)

Changes to pipelines.py:
- Minor cleanup related to knowledge base references

The capability-based approach allows RAG engines to declare their
supported features (doc_ingestion, chunking_config, rerank, hybrid_search)
and the system responds accordingly, rather than hardcoding behavior
based on internal/external type distinction.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BREAKING CHANGE: The internal/external knowledge base distinction
has been removed from the frontend. All knowledge bases are now
displayed in a unified list, differentiated by their RAG engine.

Changes to page.tsx:
- Remove Tab component (内置/外置 tabs)
- Remove selectedKbType state
- Unified knowledge base list display
- Single "Create Knowledge Base" button for all types

Changes to KBDetailDialog.tsx:
- Remove kbType prop
- Simplify dialog logic for unified KB handling
- Documents menu item conditionally shown based on doc_ingestion capability

Changes to KBForm.tsx:
- Remove retriever type handling code
- Simplify form for unified KB creation
- Dynamic form rendering based on RAG engine's creation_schema

Changes to KBCardVO.ts:
- Remove 'type' field from KBCardVO interface

Changes to BackendClient.ts:
- Remove all external KB related methods:
  - getExternalKnowledgeBases()
  - getExternalKnowledgeBase()
  - createExternalKnowledgeBase()
  - updateExternalKnowledgeBase()
  - deleteExternalKnowledgeBase()
  - retrieveFromExternalKnowledgeBase()

Changes to api/index.ts:
- Remove ExternalKnowledgeBase interface definition

UI/UX improvements:
- Users no longer need to understand internal vs external distinction
- RAG engine selection is now the primary differentiator
- Documents panel visibility is capability-driven (doc_ingestion)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Unify embed_model field naming to embedding_model_uuid only
- Add structured error responses with error_type for RAG actions
- Fix file_size and mime_type detection in _store_file_task
- Improve error handling with detailed error context (error_type, original_error)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Frontend: Refactor Knowledge Base form using DynamicForm components.
- Frontend: Remove obsolete jsonSchemaConverter utility.
- Backend: Update VectorManager and PluginHandler to support new RAG architecture.
- Chore: Update dependencies in pyproject.toml.
- Remove DEBUG stderr outputs in handler.py
- Move repeated `import json` to file top
- Add warning log for unimplemented delete_by_filter

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Define MUTABLE_FIELDS, CREATE_FIELDS, ALL_DB_FIELDS as class
constants in KnowledgeBase entity to eliminate duplication.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create RAGRuntimeService to encapsulate RAG capability implementation (Embedding, VectorOps).
- Refactor PluginHandler to delegate RAG actions to RAGRuntimeService.
- Move KnowledgeService enrichment and creation logic to RAGManager.
- Register RAGRuntimeService in Application and BuildAppStage.
- Clean up legacy code in KnowledgeService.
- Use self.ap.logger consistently in kbmgr.py and runtime.py, removing module-level loggers.
- Fix type hints for retrieve_knowledge in handler.py and connector.py to match implementation returning dict.
- Fix missing key prop in PluginComponentList by using ternary instead of Fragment
- Fix RAGEngine.name type to I18nObject and use extractI18nObject() for rendering
- Preserves multi-language support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
P0 fixes:
- Fix ALL_DB_FIELDS missing collection_id and emoji fields
- Move rag_engine_plugin_id to CREATE_FIELDS (immutable after creation)
- Fix creation_settings mutable default value (dict -> None)
- Rename vector delete method to delete_by_file_id for correct semantics
- Fix delete_by_filter to raise NotImplementedError instead of silent no-op
- Add database migration script (dbm019) for new columns and table cleanup

P1 fixes:
- Clean up design-hesitation comments in connector.py
- Add _parse_plugin_id() with format validation for all RAG methods
- Make _retrieve() raise exceptions instead of silently returning empty results
- Extract _make_rag_error_response() helper for clean error formatting
- Remove unused imports from handler.py

P2 fixes:
- Fix runtime.py indentation inconsistencies
- Simplify get_file_stream to use storage abstraction uniformly
- Reduce redundant DB queries in knowledge service (extract _check_doc_capability)
- Fix engines.py URL encoding: use <path:plugin_id> instead of __ replacement
- Add read-only mode for engine settings in KBForm edit mode
- Simplify page.tsx handleKBCardClick to pass only kbId string

Co-authored-by: Cursor <cursoragent@cursor.com>
- Frontend: add retrieval_settings param to retrieveKnowledgeBase API call
- Backend: return {uuid} from PUT knowledge base to match frontend expectation
- Backend: validate query is non-empty in retrieve endpoint (400 on empty)
- Backend: rename vector_delete ids→file_ids for semantic clarity, keep
  backward compat by accepting both 'file_ids' and 'ids' in RPC handler
- Backend: ensure rag_engine.name fallback is always I18nObject-compatible
  dict, preventing frontend extractI18nObject from receiving plain strings
- Migration: fix misleading docstring about external_kb data migration

Co-authored-by: Cursor <cursoragent@cursor.com>
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. eh: Feature enhance: 新功能添加 / add new features External Plugin 插件问题或新增插件 / Issues on plugin itself m: Plugins 插件加载及管理模块 / Plugins loading and management labels Feb 9, 2026
@dosubot dosubot bot added the pd: Need testing pending: 待测试的PR / PR waiting to be tested label Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

eh: Feature enhance: 新功能添加 / add new features External Plugin 插件问题或新增插件 / Issues on plugin itself m: Plugins 插件加载及管理模块 / Plugins loading and management pd: Need testing pending: 待测试的PR / PR waiting to be tested size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: RAG engine plugin architecture

1 participant