V1: RAG pipeline with hybrid search, reranker and Telegram bot - #1
Merged
Merged
Conversation
…Input/Output, agent_utils) - Add PromptTemplate class to domain/prompts/__init__.py (str.format, no Jinja2) - Add AgentInput and AgentOutput models to domain/models.py - Add load_history_and_append() and wrap_output() to agent_utils.py
…extraction, chunking and chroma
…s/ . And update repo structure to v2 clean agents template
added 26 commits
May 21, 2026 09:12
…rchitecture in Drawio format is added
Scaffolding for the concepts-tutor system was incomplete — bank generation and essay proposal modes need these dirs to exist before writing drafts.
Corrects three conceptual errors written in today's learnings.md entry (infrastructure/application dependency direction, business logic location, agent composition wording) and tracks them in "¿Qué no entendí bien?" for follow-up in future sessions. Reconciles the work_log.md draft with the day's actual commits.
Portable end-of-day skill: reviews the latest learnings.md entry and synthesizes work_log.md from actual git history, so day closeouts stay disciplined and traceable across projects.
TelegramBot depends only on AnswerFn (Callable[[str], Awaitable[str]]), never on LLMProvider/VectorStore/AnthropicLLM/ChromaVectorStore. Wiring of concrete infrastructure lives in the composition root (scripts/run_telegram_bot.py) via a closure, keeping the adapter testable and channel-agnostic.
Adds today's learnings entry on AnswerFn as a lightweight function-type contract for the Telegram adapter, and reconciles work_log.md with the actual bot implementation committed today.
johnma96
added a commit
that referenced
this pull request
Aug 13, 2026
V1: RAG pipeline with hybrid search, reranker and Telegram bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope
Closes V1 of the ResearchOS roadmap: a complete RAG pipeline over open-access
papers, exposed through a Telegram bot, built on Clean Architecture with
Protocol-based abstractions.
What was built
Domain layer
Document,Chunk,Message,Paperdomain/interfaces.py:LLMProvider,VectorStore,Retriever,MemoryStore.txtfiles withstr.format(), loaded viaPromptTemplateIngestion pipeline (offline)
chunking_service.pyingestion_service.py, run viascripts/ingest_documents.pyRetrieval
ChromaVectorStorewith local embeddings (sentence-transformers,all-MiniLM-L6-v2)
BM25Retrieverusingrank_bm25hybrid_search: Reciprocal Rank Fusion over an arbitrary list ofRetrieverimplementationshybrid_rerank_search: Claude as a relevance reranker over hybrid candidatesscripts/eval_retrieval.pycompares four strategies (vector, BM25, hybrid,hybrid+rerank) with P@k and MRR
Delivery channel
TelegramBotadapter ininfrastructure/bot/telegram_bot.pyscripts/run_telegram_bot.py, injecting anAnswerFn = Callable[[str], Awaitable[str]]Tests
@pytest.mark.unit/@pytest.mark.integrationseparation, mocking Protocols rather than concrete implementations
Key architectural decisions
application/decoupledfrom inheritance hierarchies and lets test mocks satisfy contracts without
importing infrastructure.
hybrid_searchacceptslist[Retriever], not concrete classes. Adding athird retriever requires no signature change and no edits to
application/.AnswerFnand never instantiatesAnthropicLLMorChromaVectorStore.Dependency wiring lives in the composition root (
scripts/). The samecontract will serve Slack, FastAPI or a CLI.
agent_utils.py; agents import what they need instead of inheriting from abase class.
asyncsearchdespite being in-memory, for uniformitywith
ChromaVectorStoreunderasyncio.gatherinhybrid_search. Documentedas a conscious trade-off; revisit if corpus size makes the blocking cost
material.
Known debt
test_extract_text_pdfdepends on a sample PDF that is not versioned, so itfails on a clean clone. Should be mocked (V3).
corpus (data leakage), so all four strategies score near 1.000 and the
comparison is non-discriminative. Rebuilt in V3 with real bot queries.
answer_querytakes no history, so follow-upquestions lose their referent (V2).
poorly even with memory (V2).
hybrid_rerank_search.Out of scope for V1
LangGraph orchestration, agent tools, morning briefing, observability,
guardrails, deployment. All planned in V2–V4.