Skip to content

Commit f2c65e0

Browse files
akotylamicpst
andauthored
docs: Update README (#704)
Co-authored-by: Michal Pstrag <[email protected]>
1 parent 511631c commit f2c65e0

File tree

2 files changed

+151
-59
lines changed

2 files changed

+151
-59
lines changed

README.md

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434
- **Connect to any data source** – Use prebuilt connectors for S3, GCS, Azure, or implement your own.
3535
- **Scale ingestion** – Process large datasets quickly with [Ray-based parallel processing](https://ragbits.deepsense.ai/how-to/document_search/distributed_ingestion/#how-to-ingest-documents-in-a-distributed-fashion).
3636

37+
### 🤖 Build Multi-Agent Workflows with Ease
38+
39+
- **Multi-agent coordination** – Create teams of specialized agents with role-based collaboration using [A2A protocol](https://ragbits.deepsense.ai/tutorials/agents) for interoperability.
40+
- **Real-time data integration** – Leverage [Model Context Protocol (MCP)](https://ragbits.deepsense.ai/how-to/agents/provide_mcp_tools) for live web access, database queries, and API integrations.
41+
- **Conversation state management** – Maintain context across interactions with [automatic history tracking](https://ragbits.deepsense.ai/how-to/agents/define_and_use_agents/#conversation-history).
42+
3743
### 🚀 Deploy & Monitor with Confidence
3844

3945
- **Real-time observability** – Track performance with [OpenTelemetry](https://ragbits.deepsense.ai/how-to/project/use_tracing/#opentelemetry-trace-handler) and [CLI insights](https://ragbits.deepsense.ai/how-to/project/use_tracing/#cli-trace-handler).
@@ -165,55 +171,95 @@ if __name__ == "__main__":
165171
asyncio.run(run())
166172
```
167173

174+
### Agentic RAG
175+
176+
To build an agentic RAG pipeline:
177+
178+
```python
179+
import asyncio
180+
from ragbits.agents import Agent
181+
from ragbits.core.embeddings import LiteLLMEmbedder
182+
from ragbits.core.llms import LiteLLM
183+
from ragbits.core.vector_stores import InMemoryVectorStore
184+
from ragbits.document_search import DocumentSearch
185+
186+
embedder = LiteLLMEmbedder(model_name="text-embedding-3-small")
187+
vector_store = InMemoryVectorStore(embedder=embedder)
188+
document_search = DocumentSearch(vector_store=vector_store)
189+
190+
llm = LiteLLM(model_name="gpt-4.1-nano")
191+
agent = Agent(llm=llm, tools=[document_search.search])
192+
193+
async def main() -> None:
194+
await document_search.ingest("web://https://arxiv.org/pdf/1706.03762")
195+
response = await agent.run("What are the key findings presented in this paper?")
196+
print(response.content)
197+
198+
if __name__ == "__main__":
199+
asyncio.run(main())
200+
```
201+
168202
### Chat UI
169203

170-
To expose your RAG application through Ragbits UI:
204+
To expose your GenAI application through Ragbits API:
171205

172206
```python
173-
from collections.abc import AsyncGenerator, Iterable
174-
from pydantic import BaseModel
207+
from collections.abc import AsyncGenerator
208+
from ragbits.agents import Agent, ToolCallResult
175209
from ragbits.chat.api import RagbitsAPI
176210
from ragbits.chat.interface import ChatInterface
177-
from ragbits.chat.interface.types import ChatContext, ChatResponse
211+
from ragbits.chat.interface.types import ChatContext, ChatResponse, LiveUpdateType
178212
from ragbits.core.embeddings import LiteLLMEmbedder
179-
from ragbits.core.llms import LiteLLM
180-
from ragbits.core.prompt import Prompt, ChatFormat
213+
from ragbits.core.llms import LiteLLM, ToolCall
214+
from ragbits.core.prompt import ChatFormat
181215
from ragbits.core.vector_stores import InMemoryVectorStore
182216
from ragbits.document_search import DocumentSearch
183-
from ragbits.document_search.documents.element import Element
184217

185-
class QuestionAnswerPromptInput(BaseModel):
186-
question: str
187-
context: Iterable[Element]
218+
embedder = LiteLLMEmbedder(model_name="text-embedding-3-small")
219+
vector_store = InMemoryVectorStore(embedder=embedder)
220+
document_search = DocumentSearch(vector_store=vector_store)
188221

189-
class QuestionAnswerPrompt(Prompt[QuestionAnswerPromptInput, str]):
190-
system_prompt = """
191-
You are a question answering agent. Answer the question that will be provided using context.
192-
If in the given context there is not enough information refuse to answer.
193-
"""
194-
user_prompt = """
195-
Question: {{ question }}
196-
Context: {% for chunk in context %}{{ chunk.text_representation }}{%- endfor %}
197-
"""
222+
llm = LiteLLM(model_name="gpt-4.1-nano")
223+
agent = Agent(llm=llm, tools=[document_search.search])
198224

199225
class MyChat(ChatInterface):
200226
async def setup(self) -> None:
201-
self.llm = LiteLLM(model_name="gpt-4.1-nano")
202-
self.embedder = LiteLLMEmbedder(model_name="text-embedding-3-small")
203-
self.vector_store = InMemoryVectorStore(embedder=self.embedder)
204-
self.document_search = DocumentSearch(vector_store=self.vector_store)
205-
await self.document_search.ingest("web://https://arxiv.org/pdf/1706.03762")
227+
await document_search.ingest("web://https://arxiv.org/pdf/1706.03762")
206228

207229
async def chat(
208230
self,
209231
message: str,
210232
history: ChatFormat | None = None,
211233
context: ChatContext | None = None,
212-
) -> AsyncGenerator[ChatResponse, None]:
213-
chunks = await self.document_search.search(message)
214-
prompt = QuestionAnswerPrompt(QuestionAnswerPromptInput(question=message, context=chunks))
215-
async for text in self.llm.generate_streaming(prompt):
216-
yield self.create_text_response(text)
234+
) -> AsyncGenerator[ChatResponse]:
235+
async for result in agent.run_streaming(message):
236+
match result:
237+
case str():
238+
yield self.create_live_update(
239+
update_id="1",
240+
type=LiveUpdateType.START,
241+
label="Answering...",
242+
)
243+
yield self.create_text_response(result)
244+
case ToolCall():
245+
yield self.create_live_update(
246+
update_id="2",
247+
type=LiveUpdateType.START,
248+
label="Searching...",
249+
)
250+
case ToolCallResult():
251+
yield self.create_live_update(
252+
update_id="2",
253+
type=LiveUpdateType.FINISH,
254+
label="Search",
255+
description=f"Found {len(result.result)} relevant chunks.",
256+
)
257+
258+
yield self.create_live_update(
259+
update_id="1",
260+
type=LiveUpdateType.FINISH,
261+
label="Answer",
262+
)
217263

218264
if __name__ == "__main__":
219265
api = RagbitsAPI(MyChat)
@@ -232,7 +278,7 @@ Explore `create-ragbits-app` repo [here](https://github.com/deepsense-ai/create-
232278

233279
## Documentation
234280

235-
- [Quickstart](https://ragbits.deepsense.ai/quickstart/quickstart1_prompts/) - Get started with Ragbits in a few minutes
281+
- [Tutorials](https://ragbits.deepsense.ai/tutorials/intro) - Get started with Ragbits in a few minutes
236282
- [How-to](https://ragbits.deepsense.ai/how-to/prompts/use_prompting) - Learn how to use Ragbits in your projects
237283
- [CLI](https://ragbits.deepsense.ai/cli/main) - Learn how to run Ragbits in your terminal
238284
- [API reference](https://ragbits.deepsense.ai/api_reference/core/prompt) - Explore the underlying Ragbits API

docs/index.md

Lines changed: 75 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ hide:
5454
- **Connect to any data source** – Use prebuilt connectors for S3, GCS, Azure, or implement your own.
5555
- **Scale ingestion** – Process large datasets quickly with [Ray-based parallel processing](https://ragbits.deepsense.ai/how-to/document_search/distributed_ingestion/#how-to-ingest-documents-in-a-distributed-fashion).
5656

57+
### 🤖 Build Multi-Agent Workflows with Ease
58+
59+
- **Multi-agent coordination** – Create teams of specialized agents with role-based collaboration using [A2A protocol](https://ragbits.deepsense.ai/tutorials/agents/) for interoperability.
60+
- **Real-time data integration** – Leverage [Model Context Protocol (MCP)](https://ragbits.deepsense.ai/how-to/provide_mcp_tools/) for live web access, database queries, and API integrations.
61+
- **Conversation state management** – Maintain context across interactions with [automatic history tracking](https://ragbits.deepsense.ai/how-to/agents/define_and_use_agents/#conversation-history/).
62+
5763
### 🚀 Deploy & Monitor with Confidence
5864

5965
- **Real-time observability** – Track performance with [OpenTelemetry](https://ragbits.deepsense.ai/how-to/project/use_tracing/#opentelemetry-trace-handler) and [CLI insights](https://ragbits.deepsense.ai/how-to/project/use_tracing/#cli-trace-handler).
@@ -194,55 +200,95 @@ if __name__ == "__main__":
194200
asyncio.run(run())
195201
```
196202

203+
### Agentic RAG
204+
205+
To build an agentic RAG pipeline:
206+
207+
```python
208+
import asyncio
209+
from ragbits.agents import Agent
210+
from ragbits.core.embeddings import LiteLLMEmbedder
211+
from ragbits.core.llms import LiteLLM
212+
from ragbits.core.vector_stores import InMemoryVectorStore
213+
from ragbits.document_search import DocumentSearch
214+
215+
embedder = LiteLLMEmbedder(model_name="text-embedding-3-small")
216+
vector_store = InMemoryVectorStore(embedder=embedder)
217+
document_search = DocumentSearch(vector_store=vector_store)
218+
219+
llm = LiteLLM(model_name="gpt-4.1-nano")
220+
agent = Agent(llm=llm, tools=[document_search.search])
221+
222+
async def main() -> None:
223+
await document_search.ingest("web://https://arxiv.org/pdf/1706.03762")
224+
response = await agent.run("What are the key findings presented in this paper?")
225+
print(response.content)
226+
227+
if __name__ == "__main__":
228+
asyncio.run(main())
229+
```
230+
197231
### Chat UI
198232

199-
To expose your RAG application through Ragbits UI:
233+
To expose your GenAI application through Ragbits API:
200234

201235
```python
202-
from collections.abc import AsyncGenerator, Iterable
203-
from pydantic import BaseModel
236+
from collections.abc import AsyncGenerator
237+
from ragbits.agents import Agent, ToolCallResult
204238
from ragbits.chat.api import RagbitsAPI
205239
from ragbits.chat.interface import ChatInterface
206-
from ragbits.chat.interface.types import ChatContext, ChatResponse
240+
from ragbits.chat.interface.types import ChatContext, ChatResponse, LiveUpdateType
207241
from ragbits.core.embeddings import LiteLLMEmbedder
208-
from ragbits.core.llms import LiteLLM
209-
from ragbits.core.prompt import Prompt, ChatFormat
242+
from ragbits.core.llms import LiteLLM, ToolCall
243+
from ragbits.core.prompt import ChatFormat
210244
from ragbits.core.vector_stores import InMemoryVectorStore
211245
from ragbits.document_search import DocumentSearch
212-
from ragbits.document_search.documents.element import Element
213246

214-
class QuestionAnswerPromptInput(BaseModel):
215-
question: str
216-
context: Iterable[Element]
247+
embedder = LiteLLMEmbedder(model_name="text-embedding-3-small")
248+
vector_store = InMemoryVectorStore(embedder=embedder)
249+
document_search = DocumentSearch(vector_store=vector_store)
217250

218-
class QuestionAnswerPrompt(Prompt[QuestionAnswerPromptInput, str]):
219-
system_prompt = """
220-
You are a question answering agent. Answer the question that will be provided using context.
221-
If in the given context there is not enough information refuse to answer.
222-
"""
223-
user_prompt = """
224-
Question: {{ question }}
225-
Context: {% for chunk in context %}{{ chunk.text_representation }}{%- endfor %}
226-
"""
251+
llm = LiteLLM(model_name="gpt-4.1-nano")
252+
agent = Agent(llm=llm, tools=[document_search.search])
227253

228254
class MyChat(ChatInterface):
229255
async def setup(self) -> None:
230-
self.llm = LiteLLM(model_name="gpt-4.1-nano")
231-
self.embedder = LiteLLMEmbedder(model_name="text-embedding-3-small")
232-
self.vector_store = InMemoryVectorStore(embedder=self.embedder)
233-
self.document_search = DocumentSearch(vector_store=self.vector_store)
234-
await self.document_search.ingest("web://https://arxiv.org/pdf/1706.03762")
256+
await document_search.ingest("web://https://arxiv.org/pdf/1706.03762")
235257

236258
async def chat(
237259
self,
238260
message: str,
239261
history: ChatFormat | None = None,
240262
context: ChatContext | None = None,
241-
) -> AsyncGenerator[ChatResponse, None]:
242-
chunks = await self.document_search.search(message)
243-
prompt = QuestionAnswerPrompt(QuestionAnswerPromptInput(question=message, context=chunks))
244-
async for text in self.llm.generate_streaming(prompt):
245-
yield self.create_text_response(text)
263+
) -> AsyncGenerator[ChatResponse]:
264+
async for result in agent.run_streaming(message):
265+
match result:
266+
case str():
267+
yield self.create_live_update(
268+
update_id="1",
269+
type=LiveUpdateType.START,
270+
label="Answering...",
271+
)
272+
yield self.create_text_response(result)
273+
case ToolCall():
274+
yield self.create_live_update(
275+
update_id="2",
276+
type=LiveUpdateType.START,
277+
label="Searching...",
278+
)
279+
case ToolCallResult():
280+
yield self.create_live_update(
281+
update_id="2",
282+
type=LiveUpdateType.FINISH,
283+
label="Search",
284+
description=f"Found {len(result.result)} relevant chunks.",
285+
)
286+
287+
yield self.create_live_update(
288+
update_id="1",
289+
type=LiveUpdateType.FINISH,
290+
label="Answer",
291+
)
246292

247293
if __name__ == "__main__":
248294
api = RagbitsAPI(MyChat)

0 commit comments

Comments
 (0)