現(xiàn))
RedisES——Retriever的抽象實(shí)現(xiàn)Eino 的 Retriever 抽象就是為了屏蔽底層檢索實(shí)現(xiàn)Redis 和 ElasticsearchES都可以作為 Retriever 的實(shí)現(xiàn)只不過支持方式有所區(qū)別。Eino 中 Retriever 的定位Eino 將檢索能力統(tǒng)一抽象成了一個(gè)接口大致可以理解成typeRetrieverinterface{Retrieve(ctx context.Context,querystring,opts...Option)([]*schema.Document,error)}無論底層是向量數(shù)據(jù)庫Milvus、Qdrant、Chroma搜索引擎ElasticsearchRedis自定義數(shù)據(jù)庫最終都只需要實(shí)現(xiàn)這個(gè)接口即可。這樣在 Chain 或 Agent 中只需要依賴 Retriever而不用關(guān)心底層是什么。1. ElasticsearchES 非常適合作為 Retriever??梢杂袔追N方式① BM25 檢索User Query │ ▼ Elasticsearch (match / multi_match) │ ▼ Documents這種就是傳統(tǒng)全文檢索。例如如何部署docker ↓ match: content:如何部署docker② 向量檢索ES 8.x 已支持 Dense Vector。流程Embedding ↓ query_vector ↓ KNN Search ↓ TopK DocumentsRetriever 內(nèi)部Embedding(query) ↓ ES KNN ↓ 返回 Document[]③ Hybrid Search很多 RAG 都采用BM25 Vector Search RRFRetriever 完全可以封裝這套邏輯。2. RedisRedis 也完全可以做 Retriever。但這里要區(qū)分是哪種 Redis。普通 Redis例如GET HGET SCAN它本身沒有真正意義上的語義檢索。如果只是key - document那更像 KV Store不屬于典型 Retriever。Redis StackRediSearch如果安裝了Redis Stack或者RediSearch就支持全文檢索Vector SearchHybrid Search例如FT.SEARCH KNN VECTOR那么它完全可以作為 Retriever。流程Embedding ↓ Redis Vector Index ↓ TopK ↓ Document[]3. 在 Eino 中如何使用Eino 不要求 Retriever 一定來自官方。例如可以自己實(shí)現(xiàn)ESRetriever RedisRetriever MilvusRetriever PGVectorRetriever QdrantRetriever它們都滿足Retrieve() ↓ []DocumentChain 完全不用修改。例如KnowledgeRetriever │ ┌────────┴─────────┐ │ │ ESRetriever MilvusRetriever │ │ ES MilvusAgent 根本不知道底層是誰。4. 官方是否內(nèi)置了 Redis 和 ES截至目前Eino 官方生態(tài)主要內(nèi)置和維護(hù)的是對常見向量數(shù)據(jù)庫、Embedding、LLM 等組件的適配。Elasticsearch 和 Redis 并不是官方長期維護(hù)的核心 Retriever 實(shí)現(xiàn)更多時(shí)候需要你自行實(shí)現(xiàn)適配或者基于社區(qū)擴(kuò)展來接入。由于 Eino 的 Retriever 接口非常簡單實(shí)現(xiàn)一個(gè)ESRetriever或RedisRetriever的成本并不高只需要把底層查詢結(jié)果轉(zhuǎn)換成schema.Document即可??偨Y(jié)檢索后端能否作為 Retriever是否適合 RAGElasticsearchBM25√√ElasticsearchVector√√ElasticsearchHybrid√√Redis普通 KV注意可以封裝但不屬于真正語義檢索×Redis Stack / RediSearch√√Milvus√√Qdrant√√如果你是在做企業(yè)級 RAG 或智能體項(xiàng)目我更推薦采用“ES 向量庫”的雙檢索架構(gòu)Hybrid RetrievalES 負(fù)責(zé)關(guān)鍵詞/BM25 檢索Milvus 或 Qdrant 負(fù)責(zé)語義向量檢索再通過 RRF、加權(quán)融合或重排序Reranker合并結(jié)果。這也是目前許多生產(chǎn)系統(tǒng)采用的方案。也就是說要區(qū)分抽象Interface**和**具體實(shí)現(xiàn)Implementation。第一層Retriever 是抽象Eino 中真正依賴的是 Retriever 接口例如typeRetrieverinterface{Retrieve(ctx context.Context,querystring,opts...Option)([]*schema.Document,error)}對于 Chain、Agent 來說它們只認(rèn)識Retriever并不知道下面到底是誰。例如Retriever ▲ ┌──────────────┼──────────────┐ │ │ │ MilvusRetriever ESRetriever RedisRetriever │ │ │ Milvus ES Redis StackAgent 調(diào)用的永遠(yuǎn)都是Retrieve(...)所以Retriever 抽象可以對應(yīng)任意數(shù)據(jù)庫。第二層MilvusRetriever 是具體實(shí)現(xiàn)MilvusRetriever 的內(nèi)部代碼一般會(huì)直接調(diào)用 Milvus SDK例如client.Search(...)它知道collectionvector fieldmetric typetopK例如User Query │ Embedding │ MilvusRetriever │ Milvus SDK │ Milvus Server因此MilvusRetriever 不可能直接去查 ES。因?yàn)镋S 的 API 是POST /_searchMilvus 是Search()參數(shù)完全不同。第三層如果數(shù)據(jù)庫換了怎么辦假設(shè)今天不用 Milvus而換成QdrantWeaviatePGVectorChroma那么應(yīng)該Retriever ▲ ┌───────────┴───────────┐ │ │ MilvusRetriever QdrantRetriever │ │ Milvus Qdrant只需要typeQdrantRetrieverstruct{client*qdrant.Client}func(r*QdrantRetriever)Retrieve(...){...}即可。整個(gè) Agent 一行代碼都不用改。為什么要這樣設(shè)計(jì)這就是經(jīng)典的依賴倒置Dependency Inversion。例如以前Agent │ ▼ MilvusAgent 被綁死了?,F(xiàn)在Agent │ ▼ Retriever │ ├── Milvus ├── ES ├── Redis ├── PGVector └── QdrantAgent 根本不知道下面是誰。以后替換數(shù)據(jù)庫Milvus ↓ QdrantAgent 完全不用改。Eino 為什么要這樣抽象因?yàn)橐粋€(gè) Retriever 并不一定對應(yīng)一個(gè)數(shù)據(jù)庫它甚至可以組合多個(gè)數(shù)據(jù)源。例如HybridRetriever │ ┌────┴────┐ │ │ ES Milvus │ │ BM25 Vector Search └────┬────┘ ▼ Rank Fusion ▼ Documents對于 Agent 來說它依然只是docs,err:retriever.Retrieve(ctx,query)它不知道內(nèi)部實(shí)際上調(diào)用了ESMilvusReranker甚至可以再加Redis CacheKnowledge GraphMySQL都可以。一句話總結(jié)RetrieverEino 定義的抽象接口可以適配任意檢索后端Milvus、Qdrant、ES、Redis Stack、PGVector 等。MilvusRetrieverRetriever的一個(gè)具體實(shí)現(xiàn)只負(fù)責(zé)調(diào)用 Milvus因此不能直接用于其他向量數(shù)據(jù)庫。如果更換向量數(shù)據(jù)庫應(yīng)實(shí)現(xiàn)對應(yīng)的QdrantRetriever、PGVectorRetriever等只要都實(shí)現(xiàn)Retriever接口Agent 和 Chain 無需修改。這也是 Eino 將組件分為Loader → Transformer → Indexer → Retriever → Reranker的核心思想上層依賴統(tǒng)一抽象下層可以自由替換具體實(shí)現(xiàn)。