From ac1d8edb9c28e1b70d18b1b36cc13dd7399290a2 Mon Sep 17 00:00:00 2001 From: ari-bmgf Date: Mon, 6 Apr 2026 00:09:58 -0700 Subject: [PATCH] Add Dewey integration --- integrations/dewey-haystack.md | 142 +++++++++++++++++++++++++++++++++ logos/dewey.png | Bin 0 -> 15288 bytes 2 files changed, 142 insertions(+) create mode 100644 integrations/dewey-haystack.md create mode 100644 logos/dewey.png diff --git a/integrations/dewey-haystack.md b/integrations/dewey-haystack.md new file mode 100644 index 0000000..1dc7f00 --- /dev/null +++ b/integrations/dewey-haystack.md @@ -0,0 +1,142 @@ +--- +layout: integration +name: Dewey +description: Connect Haystack pipelines to Dewey — a managed document intelligence backend that handles PDF conversion, chunking, embedding, and hybrid retrieval behind a single API. +authors: + - name: Dewey + socials: + github: meetdewey +pypi: https://pypi.org/project/dewey-haystack +repo: https://github.com/meetdewey/dewey-haystack +type: Document Store +report_issue: https://github.com/meetdewey/dewey-haystack/issues +logo: /logos/dewey.png +version: Haystack 2.0 +toc: true +--- + +### **Table of Contents** +- [Overview](#overview) +- [Installation](#installation) +- [Usage](#usage) +- [License](#license) + +## Overview + +[Dewey](https://meetdewey.com) is a managed document intelligence backend for AI applications. Upload PDFs, Word docs, and other files — Dewey handles conversion, section extraction, chunking, embedding, and hybrid semantic + BM25 retrieval automatically. + +This integration provides three Haystack 2.0 components: + +- **`DeweyDocumentStore`** — implements the Haystack `DocumentStore` protocol, backed by a Dewey collection +- **`DeweyRetriever`** — a `@component` that runs hybrid search against a collection and returns ranked `Document` objects +- **`DeweyResearchComponent`** — a `@component` that runs Dewey's full agentic research loop (multi-step search, synthesis, citations) and returns a grounded Markdown answer + +## Installation + +```bash +pip install dewey-haystack +``` + +Requires a free Dewey account at [meetdewey.com](https://meetdewey.com). Set your API key: + +```bash +export DEWEY_API_KEY="dwy_live_..." +``` + +## Usage + +### Components + +This integration introduces three components: + +- **`DeweyDocumentStore`** (`haystack_integrations.document_stores.dewey`) +- **`DeweyRetriever`** (`haystack_integrations.components.retrievers.dewey`) +- **`DeweyResearchComponent`** (`haystack_integrations.components.retrievers.dewey`) + +### RAG pipeline with DeweyRetriever + +```python +import os +from haystack import Pipeline +from haystack_integrations.document_stores.dewey import DeweyDocumentStore +from haystack_integrations.components.retrievers.dewey import DeweyRetriever +from haystack.components.builders import PromptBuilder +from haystack.components.generators import OpenAIGenerator +from haystack.utils import Secret + +store = DeweyDocumentStore( + api_key=Secret.from_env_var("DEWEY_API_KEY"), + collection_id="3f7a1b2c-...", # your collection ID +) + +prompt_template = """ +Answer the question using only the provided context. +Context: {% for doc in documents %}{{ doc.content }}{% endfor %} +Question: {{ query }} +""" + +pipeline = Pipeline() +pipeline.add_component("retriever", DeweyRetriever(document_store=store, top_k=5)) +pipeline.add_component("prompt", PromptBuilder(template=prompt_template)) +pipeline.add_component("llm", OpenAIGenerator(model="gpt-4o-mini")) + +pipeline.connect("retriever.documents", "prompt.documents") +pipeline.connect("prompt.prompt", "llm.prompt") + +result = pipeline.run({ + "retriever": {"query": "What are the key findings?"}, + "prompt": {"query": "What are the key findings?"}, +}) +print(result["llm"]["replies"][0]) +``` + +### Agentic research with DeweyResearchComponent + +`DeweyResearchComponent` is a drop-in replacement for an LLM generator when you want Dewey to handle both retrieval *and* generation. It runs a multi-step research loop internally and returns a grounded answer with cited sources. + +```python +import os +from haystack import Pipeline +from haystack_integrations.components.retrievers.dewey import DeweyResearchComponent +from haystack.utils import Secret + +pipeline = Pipeline() +pipeline.add_component( + "research", + DeweyResearchComponent( + api_key=Secret.from_env_var("DEWEY_API_KEY"), + collection_id="3f7a1b2c-...", + depth="balanced", # "quick" | "balanced" | "deep" | "exhaustive" + ), +) + +result = pipeline.run({"research": {"query": "What were the key findings across all studies?"}}) +print(result["research"]["answer"]) + +for source in result["research"]["sources"]: + print(f" [{source.meta['filename']}] {source.content[:80]}...") +``` + +### Writing documents + +Upload content to Dewey directly from a Haystack pipeline using `DeweyDocumentStore.write_documents`: + +```python +from haystack import Document +from haystack_integrations.document_stores.dewey import DeweyDocumentStore +from haystack.utils import Secret + +store = DeweyDocumentStore( + api_key=Secret.from_env_var("DEWEY_API_KEY"), + collection_id="3f7a1b2c-...", +) + +store.write_documents([ + Document(content="Neural networks learn via backpropagation.", meta={"source": "ml-intro.txt"}), + Document(content="Transformers use self-attention mechanisms.", meta={"source": "transformers.txt"}), +]) +``` + +## License + +`dewey-haystack` is released under the [MIT License](https://github.com/meetdewey/dewey-haystack/blob/main/LICENSE). diff --git a/logos/dewey.png b/logos/dewey.png new file mode 100644 index 0000000000000000000000000000000000000000..dd159c5c5887e01434ee48461f52bc5d1bf40b39 GIT binary patch literal 15288 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 literal 0 HcmV?d00001