Strategy: Use doc_search to find patterns, implement TRUE one-liners, test everything Critical: DO NOT touch semantic_search.py until ALL other features work!
- Basic indexing and search (49 lines in semantic_search.py)
- doc_search.py with 25,929 vectors
- OpenAI embeddings + ElectronHub LLM (conflict resolved)
- Qdrant hybrid search
- IngestionPipeline - Prevents re-indexing
- refresh_ref_docs() - Updates only changed docs
- load_index_from_storage() - Load saved indexes
- persist with persist_dir - Save indexes properly
- RouterQueryEngine - Route between query types
- SubQuestionQueryEngine - Complex Q&A (needs fixing)
- CodeHierarchyNodeParser - Code structure analysis
- PropertyGraphIndex - Architecture visualization
- GraphRAGQueryEngine - Graph-based Q&A
- KnowledgeGraphIndex - Knowledge integration
These are foundational - implement first!
from llama_index.core.ingestion import IngestionPipeline, DocstoreStrategy
from llama_index.core.storage.docstore import SimpleDocumentStore
# Pattern from doc_search:
pipeline = IngestionPipeline(
transformations=[SentenceSplitter(), Settings.embed_model],
docstore=SimpleDocumentStore(),
docstore_strategy=DocstoreStrategy.UPSERTS
)
nodes = pipeline.run(documents=docs)Purpose: Prevents re-indexing same documents Lines: ~7-10
# Pattern from doc_search:
from llama_index.core import Document
# Documents must have IDs
docs = [Document(text="...", id_="doc_1")]
index.refresh_ref_docs(docs) # Only updates changed onesPurpose: Updates only changed documents Lines: ~3
from llama_index.core import StorageContext, load_index_from_storage
# Pattern from doc_search:
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)Purpose: Load saved indexes Lines: 2
# Pattern from doc_search:
index.storage_context.persist(persist_dir="./storage")Purpose: Save indexes to disk Lines: 1
from llama_index.core.query_engine import RouterQueryEngine
from llama_index.core.selectors import LLMSingleSelector
from llama_index.core.tools import QueryEngineTool
# Pattern from doc_search:
tools = [
QueryEngineTool.from_defaults(query_engine=code_engine, description="For code"),
QueryEngineTool.from_defaults(query_engine=doc_engine, description="For docs")
]
router = RouterQueryEngine(
selector=LLMSingleSelector.from_defaults(),
query_engine_tools=tools
)Purpose: Route queries to appropriate engine Lines: ~10
from llama_index.core.query_engine import SubQuestionQueryEngine
from llama_index.core.tools import QueryEngineTool
# Pattern from doc_search:
tools = [QueryEngineTool(...)]
engine = SubQuestionQueryEngine.from_defaults(
query_engine_tools=tools,
use_async=True # Fix timeout issues
)Purpose: Break complex questions into sub-questions Lines: ~8
from llama_index.core.node_parser import CodeHierarchyNodeParser
parser = CodeHierarchyNodeParser()
nodes = parser.get_nodes_from_documents(docs)Purpose: Parse code structure Lines: 3
from llama_index.core import PropertyGraphIndex
index = PropertyGraphIndex.from_documents(docs)Purpose: Create property graphs Lines: 1
- Create new test file to implement features
- Import all necessary modules
- Test each feature independently
- IngestionPipeline with UPSERTS
- refresh_ref_docs()
- load_index_from_storage
- persist with persist_dir
- Test prevent re-indexing works
- Test smart updates work
- Test save/load works
- RouterQueryEngine
- Fix SubQuestionQueryEngine
- Test routing works
- Test sub-questions work
- Add IngestionPipeline to index_project
- Add persist/load functions
- Add refresh function
- Keep under 100 lines total! (Achieved: ~80 lines)
- DO NOT touch semantic_search.py until Step 6
- Each feature must be TRUE one-liner/minimal
- Test in isolation first
- Use doc_search for patterns
- Total file must stay under 100 lines
- All features work in test file
- No re-indexing of same documents
- Smart updates only process changes
- Indexes persist and load correctly
- Query routing works
- semantic_search.py still under 100 lines (~80 lines)
- src/core/ingestion.py - IngestionPipeline with UPSERTS (21 lines)
- src/core/persistence.py - Save/load indexes (17 lines)
- src/core/updates.py - Smart document updates (9 lines)
- src/core/query_engines.py - Router & SubQuestion engines (28 lines)
index_project_smart()- Index with deduplicationsave_index()/load_saved_index()- Persistenceupdate_documents()- Smart updatescreate_multi_project_router()- Query routinganswer_complex()- Complex Q&A breakdown
- semantic_search.py: ~80 lines (was 55, now enhanced)
- DDD modules: ~75 lines total
- Total: ~155 lines for complete solution
If something doesn't work:
- Use doc_search to find correct pattern
- Check if imports are correct
- Verify Settings are configured
- Test with minimal example first
- DO NOT create custom implementations