Compare commits
116 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ad4af250f | |||
| 9fa368b114 | |||
| 4afef04f26 | |||
| 8fe2c3effc | |||
| fa78c972be | |||
| 0e66261644 | |||
| 819650a254 | |||
| 34c41c87dc | |||
| 2985b667b0 | |||
| 31bb0e7f0f | |||
| 8f28264aec | |||
| ec4fb11aa5 | |||
| b210723de1 | |||
| 433f99dd78 | |||
| e75c05112e | |||
| d2a5b50ff8 | |||
| 120690afd4 | |||
| 344dbeee42 | |||
| 3fe3b0320a | |||
| 75896b647f | |||
| 446d0975aa | |||
| b7d365119c | |||
| 2d9fbd4e49 | |||
| 22e14b5e65 | |||
| 1a654beea4 | |||
| f50f8a444a | |||
| 3cc3a0058d | |||
| ae473b5e3c | |||
| efb7e31565 | |||
| 069d265338 | |||
| 751a3a4bd1 | |||
| cb0499407e | |||
| 9afc6878c8 | |||
| 0b5b12575a | |||
| d79d30bf0c | |||
| 59600e2a5b | |||
| e572b5a3dc | |||
| 5b46daaee4 | |||
| 2784bae772 | |||
| 325e11f0de | |||
| 7444f59e3c | |||
| affe319460 | |||
| 862ff6cca6 | |||
| c020e65a50 | |||
| f582c1fe25 | |||
| 785929c502 | |||
| 68ec6615b1 | |||
| e2cca61cd3 | |||
| 69e83adae0 | |||
| 9e24aee40d | |||
| 3cff5e9898 | |||
| f3553040bc | |||
| 2b13984e11 | |||
| 0de9491c61 | |||
| c9df7a2020 | |||
| a7222e8c50 | |||
| 0373fa231c | |||
| 5f653e69ae | |||
| 2496ed133e | |||
| 62c0c52e31 | |||
| e36198dcc2 | |||
| 5fa6221f91 | |||
| f7696d1dc1 | |||
| 1878f8d4fc | |||
| 6c69ddef9b | |||
| 0c45020d81 | |||
| 4dfce44c1a | |||
| 1b661bb2fd | |||
| 73e726f6e3 | |||
| f58bbeffce | |||
| 99261e5fb5 | |||
| b4a59d1bd5 | |||
| 5c1f78879f | |||
| 94ba82f2a2 | |||
| b4ec14382b | |||
| 38ad57a22c | |||
| 60bbc180ba | |||
| a67d902b85 | |||
| ae2e9cb890 | |||
| 1976d38b25 | |||
| f5e3410e9a | |||
| 2f6ba642c7 | |||
| dd9b72dc62 | |||
| dd258c14b5 | |||
| 295cd3fac6 | |||
| c62663f2e4 | |||
| 367d6b70e2 | |||
| 27236bd1b2 | |||
| 6a82eb4287 | |||
| bd88fe3980 | |||
| 4f70fea6df | |||
| aee5bbb44b | |||
| a304ded500 | |||
| a54dde0509 | |||
| 52b4577d3b | |||
| e199f57279 | |||
| dec12b33a6 | |||
| 04daa1b206 | |||
| a7e1520d08 | |||
| 9e2b232c13 | |||
| 404e73af77 | |||
| a544b4d3ff | |||
| 6df63d9ca7 | |||
| 904baac153 | |||
| a926bcc640 | |||
| c0aafd38c9 | |||
| 19d80914df | |||
| d9d529987e | |||
| 12e6eaf802 | |||
| 7a026ea282 | |||
| 97dc90169b | |||
| 64c02f374a | |||
| 6c1ea7799e | |||
| 6be29f5bed | |||
| 68737da7a2 | |||
| da388b679f |
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
#### Before submitting a bug, please make sure the issue hasn't been already addressed by searching through [the existing and past issues](https://github.com/gventuri/pandas-ai/issues?q=is%3Aissue+sort%3Acreated-desc+).
|
||||
#### Before submitting a bug, please make sure the issue hasn't been already addressed by searching through [the existing and past issues](https://github.com/embedchain/embedchain/issues?q=is%3Aissue+sort%3Acreated-desc+).
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 🐛 Describe the bug
|
||||
|
||||
@@ -175,3 +175,6 @@ notebooks/*.yaml
|
||||
.ipynb_checkpoints/
|
||||
|
||||
!configs/*.yaml
|
||||
|
||||
# cache db
|
||||
*.db
|
||||
|
||||
@@ -13,17 +13,17 @@
|
||||
<a href="https://pepy.tech/project/embedchain">
|
||||
<img src="https://static.pepy.tech/badge/embedchain" alt="Downloads">
|
||||
</a>
|
||||
<a href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw">
|
||||
<a href="https://embedchain.ai/slack">
|
||||
<img src="https://img.shields.io/badge/slack-embedchain-brightgreen.svg?logo=slack" alt="Slack">
|
||||
</a>
|
||||
<a href="https://discord.gg/CUU9FPhRNt">
|
||||
<a href="https://embedchain.ai/discord">
|
||||
<img src="https://dcbadge.vercel.app/api/server/6PzXDgEjG5?style=flat" alt="Discord">
|
||||
</a>
|
||||
<a href="https://twitter.com/embedchain">
|
||||
<img src="https://img.shields.io/twitter/follow/embedchain" alt="Twitter">
|
||||
</a>
|
||||
<a href="https://colab.research.google.com/drive/138lMWhENGeEu7Q1-6lNbNTHGLZXBBz_B?usp=sharing">
|
||||
<img src="https://camo.githubusercontent.com/84f0493939e0c4de4e6dbe113251b4bfb5353e57134ffd9fcab6b8714514d4d1/68747470733a2f2f636f6c61622e72657365617263682e676f6f676c652e636f6d2f6173736574732f636f6c61622d62616467652e737667" alt="Open in Colab">
|
||||
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open in Colab">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/embedchain/embedchain">
|
||||
<img src="https://codecov.io/gh/embedchain/embedchain/graph/badge.svg?token=EMRRHZXW1Q" alt="codecov">
|
||||
@@ -32,23 +32,25 @@
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
> ### Checkout our latest [Sadhguru AI app](https://sadhguru-ai.streamlit.app/) built using Embedchain.
|
||||
|
||||
## What is Embedchain?
|
||||
|
||||
Embedchain is an Open Source RAG Framework that makes it easy to create and deploy AI apps. At its core, Embedchain follows the design principle of being *"Conventional but Configurable"* to serve both software engineers and machine learning engineers.
|
||||
|
||||
Embedchain streamlines the creation of RAG applications, offering a seamless process for managing various types of unstructured data. It efficiently segments data into manageable chunks, generates relevant embeddings, and stores them in a vector database for optimized retrieval. With a suite of diverse APIs, it enables users to extract contextual information, find precise answers, or engage in interactive chat conversations, all tailored to their own data.
|
||||
Embedchain streamlines the creation of Retrieval-Augmented Generation (RAG) applications, offering a seamless process for managing various types of unstructured data. It efficiently segments data into manageable chunks, generates relevant embeddings, and stores them in a vector database for optimized retrieval. With a suite of diverse APIs, it enables users to extract contextual information, find precise answers, or engage in interactive chat conversations, all tailored to their own data.
|
||||
|
||||
## 🔧 Quick install
|
||||
|
||||
### Python API
|
||||
|
||||
```bash
|
||||
pip install embedchain
|
||||
```
|
||||
|
||||
## 🔍 Usage and Demo
|
||||
## ✨ Live demo
|
||||
|
||||
Checkout the [Chat with PDF](https://embedchain.ai/demo/chat-pdf) live demo we created using Embedchain. You can find the source code [here](https://github.com/embedchain/embedchain/tree/main/examples/chat-pdf).
|
||||
|
||||
## 🔍 Usage
|
||||
|
||||
<!-- Demo GIF or Image -->
|
||||
<p align="center">
|
||||
@@ -59,7 +61,7 @@ For example, you can create an Elon Musk bot using the following code:
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# Create a bot instance
|
||||
os.environ["OPENAI_API_KEY"] = "YOUR API KEY"
|
||||
@@ -76,7 +78,7 @@ elon_bot.query("How many companies does Elon Musk run and name those?")
|
||||
|
||||
You can also try it in your browser with Google Colab:
|
||||
|
||||
[](https://colab.research.google.com/drive/17ON1LPonnXAtLaZEebnOktstB_1cJJmh?usp=sharing)
|
||||
[](https://colab.research.google.com/drive/17ON1LPonnXAtLaZEebnOktstB_1cJJmh?usp=sharing)
|
||||
|
||||
## 📖 Documentation
|
||||
Comprehensive guides and API documentation are available to help you get the most out of Embedchain:
|
||||
@@ -88,7 +90,9 @@ Comprehensive guides and API documentation are available to help you get the mos
|
||||
|
||||
## 🔗 Join the Community
|
||||
|
||||
Connect with fellow developers and users by joining our [Slack Workspace](https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw) or [Discord Community](https://discord.gg/CUU9FPhRNt). Dive into discussions, ask questions, and share your experiences.
|
||||
* Connect with fellow developers by joining our [Slack Community](https://embedchain.ai/slack) or [Discord Community](https://embedchain.ai/discord).
|
||||
|
||||
* Dive into [GitHub Discussions](https://github.com/embedchain/embedchain/discussions), ask questions, or share your experiences.
|
||||
|
||||
## 🤝 Schedule a 1-on-1 Session
|
||||
|
||||
@@ -116,7 +120,7 @@ If you utilize this repository, please consider citing it with:
|
||||
```
|
||||
@misc{embedchain,
|
||||
author = {Taranjeet Singh, Deshraj Yadav},
|
||||
title = {Embedchain: Data platform for LLMs - load, index, retrieve, and sync any unstructured data},
|
||||
title = {Embedchain: The Open Source RAG Framework},
|
||||
year = {2023},
|
||||
publisher = {GitHub},
|
||||
journal = {GitHub repository},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
app:
|
||||
config:
|
||||
id: 'my-app'
|
||||
collection_name: 'my-app'
|
||||
|
||||
llm:
|
||||
provider: openai
|
||||
|
||||
@@ -15,7 +15,7 @@ llm:
|
||||
max_tokens: 1000
|
||||
top_p: 1
|
||||
stream: false
|
||||
template: |
|
||||
prompt: |
|
||||
Use the following pieces of context to answer the query at the end.
|
||||
If you don't know the answer, just say that you don't know, don't try to make up an answer.
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
app:
|
||||
config:
|
||||
id: 'open-source-app'
|
||||
collection_name: 'open-source-app'
|
||||
collect_metrics: false
|
||||
|
||||
llm:
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
llm:
|
||||
provider: together
|
||||
config:
|
||||
model: mistralai/Mixtral-8x7B-Instruct-v0.1
|
||||
temperature: 0.5
|
||||
max_tokens: 1000
|
||||
@@ -0,0 +1,14 @@
|
||||
llm:
|
||||
provider: vllm
|
||||
config:
|
||||
model: 'meta-llama/Llama-2-70b-hf'
|
||||
temperature: 0.5
|
||||
top_p: 1
|
||||
top_k: 10
|
||||
stream: true
|
||||
trust_remote_code: true
|
||||
|
||||
embedder:
|
||||
provider: huggingface
|
||||
config:
|
||||
model: 'BAAI/bge-small-en-v1.5'
|
||||
@@ -2,7 +2,7 @@
|
||||
<Card title="Talk to founders" icon="calendar" href="https://cal.com/taranjeetio/ec">
|
||||
Schedule a call
|
||||
</Card>
|
||||
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
|
||||
<Card title="Slack" icon="slack" href="https://embedchain.ai/slack" color="#4A154B">
|
||||
Join our slack community
|
||||
</Card>
|
||||
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<Card title="Google Form" icon="file" href="https://forms.gle/NDRCKsRpUHsz2Wcm8" color="#7387d0">
|
||||
Fill out this form
|
||||
</Card>
|
||||
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
|
||||
<Card title="Slack" icon="slack" href="https://embedchain.ai/slack" color="#4A154B">
|
||||
Let us know on our slack community
|
||||
</Card>
|
||||
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<p>If you can't find the specific LLM you need, no need to fret. We're continuously expanding our support for additional LLMs, and you can help us prioritize by opening an issue on our GitHub or simply reaching out to us on our Slack or Discord community.</p>
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
|
||||
<Card title="Slack" icon="slack" href="https://embedchain.ai/slack" color="#4A154B">
|
||||
Let us know on our slack community
|
||||
</Card>
|
||||
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<p>If you can't find the specific vector database, please feel free to request through one of the following channels and help us prioritize.</p>
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
|
||||
<Card title="Slack" icon="slack" href="https://embedchain.ai/slack" color="#4A154B">
|
||||
Let us know on our slack community
|
||||
</Card>
|
||||
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
|
||||
|
||||
@@ -8,7 +8,7 @@ You can configure different components of your app (`llm`, `embedding model`, or
|
||||
|
||||
|
||||
<Tip>
|
||||
Embedchain applications are configurable using YAML file, JSON file or by directly passing the config dictionary. Checkout the [docs here](/api-reference/pipeline/overview#usage) on how to use other formats.
|
||||
Embedchain applications are configurable using YAML file, JSON file or by directly passing the config dictionary. Checkout the [docs here](/api-reference/app/overview#usage) on how to use other formats.
|
||||
</Tip>
|
||||
|
||||
<CodeGroup>
|
||||
@@ -26,7 +26,7 @@ llm:
|
||||
top_p: 1
|
||||
stream: false
|
||||
api_key: sk-xxx
|
||||
template: |
|
||||
prompt: |
|
||||
Use the following pieces of context to answer the query at the end.
|
||||
If you don't know the answer, just say that you don't know, don't try to make up an answer.
|
||||
|
||||
@@ -56,6 +56,14 @@ chunker:
|
||||
chunk_overlap: 100
|
||||
length_function: 'len'
|
||||
min_chunk_size: 0
|
||||
|
||||
cache:
|
||||
similarity_evaluation:
|
||||
strategy: distance
|
||||
max_distance: 1.0
|
||||
config:
|
||||
similarity_threshold: 0.8
|
||||
auto_flush: 50
|
||||
```
|
||||
|
||||
```json config.json
|
||||
@@ -73,7 +81,7 @@ chunker:
|
||||
"max_tokens": 1000,
|
||||
"top_p": 1,
|
||||
"stream": false,
|
||||
"template": "Use the following pieces of context to answer the query at the end.\nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n$context\n\nQuery: $query\n\nHelpful Answer:",
|
||||
"prompt": "Use the following pieces of context to answer the query at the end.\nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n$context\n\nQuery: $query\n\nHelpful Answer:",
|
||||
"system_prompt": "Act as William Shakespeare. Answer the following questions in the style of William Shakespeare.",
|
||||
"api_key": "sk-xxx"
|
||||
}
|
||||
@@ -98,7 +106,17 @@ chunker:
|
||||
"chunk_overlap": 100,
|
||||
"length_function": "len",
|
||||
"min_chunk_size": 0
|
||||
}
|
||||
},
|
||||
"cache": {
|
||||
"similarity_evaluation": {
|
||||
"strategy": "distance",
|
||||
"max_distance": 1.0,
|
||||
},
|
||||
"config": {
|
||||
"similarity_threshold": 0.8,
|
||||
"auto_flush": 50,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -117,7 +135,7 @@ config = {
|
||||
'max_tokens': 1000,
|
||||
'top_p': 1,
|
||||
'stream': False,
|
||||
'template': (
|
||||
'prompt': (
|
||||
"Use the following pieces of context to answer the query at the end.\n"
|
||||
"If you don't know the answer, just say that you don't know, don't try to make up an answer.\n"
|
||||
"$context\n\nQuery: $query\n\nHelpful Answer:"
|
||||
@@ -148,7 +166,17 @@ config = {
|
||||
'chunk_overlap': 100,
|
||||
'length_function': 'len',
|
||||
'min_chunk_size': 0
|
||||
}
|
||||
},
|
||||
'cache': {
|
||||
'similarity_evaluation': {
|
||||
'strategy': 'distance',
|
||||
'max_distance': 1.0,
|
||||
},
|
||||
'config': {
|
||||
'similarity_threshold': 0.8,
|
||||
'auto_flush': 50,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -170,11 +198,12 @@ Alright, let's dive into what each key means in the yaml config above:
|
||||
- `max_tokens` (Integer): Controls how many tokens are used in the response.
|
||||
- `top_p` (Float): Controls the diversity of word selection. A higher value (closer to 1) makes word selection more diverse.
|
||||
- `stream` (Boolean): Controls if the response is streamed back to the user (set to false).
|
||||
- `template` (String): A custom template for the prompt that the model uses to generate responses.
|
||||
- `prompt` (String): A prompt for the model to follow when generating responses, requires `$context` and `$query` variables.
|
||||
- `system_prompt` (String): A system prompt for the model to follow when generating responses, in this case, it's set to the style of William Shakespeare.
|
||||
- `stream` (Boolean): Controls if the response is streamed back to the user (set to false).
|
||||
- `stream` (Boolean): Controls if the response is streamed back to the user (set to false).
|
||||
- `number_documents` (Integer): Number of documents to pull from the vectordb as context, defaults to 1
|
||||
- `api_key` (String): The API key for the language model.
|
||||
- `model_kwargs` (Dict): Keyword arguments to pass to the language model. Used for `aws_bedrock` provider, since it requires different arguments for each model.
|
||||
3. `vectordb` Section:
|
||||
- `provider` (String): The provider for the vector database, set to 'chroma'. You can find the full list of vector database providers in [our docs](/components/vector-databases).
|
||||
- `config`:
|
||||
@@ -186,13 +215,27 @@ Alright, let's dive into what each key means in the yaml config above:
|
||||
- `provider` (String): The provider for the embedder, set to 'openai'. You can find the full list of embedding model providers in [our docs](/components/embedding-models).
|
||||
- `config`:
|
||||
- `model` (String): The specific model used for text embedding, 'text-embedding-ada-002'.
|
||||
- `vector_dimension` (Integer): The vector dimension of the embedding model. [Defaults](https://github.com/embedchain/embedchain/blob/e572b5a3dc1b66f1e9b3357d11a88c63b5ce06e3/embedchain/models/vector_dimensions.py)
|
||||
- `api_key` (String): The API key for the embedding model.
|
||||
- `deployment_name` (String): The deployment name for the embedding model.
|
||||
- `title` (String): The title for the embedding model for Google Embedder.
|
||||
- `task_type` (String): The task type for the embedding model for Google Embedder.
|
||||
5. `chunker` Section:
|
||||
- `chunk_size` (Integer): The size of each chunk of text that is sent to the language model.
|
||||
- `chunk_overlap` (Integer): The amount of overlap between each chunk of text.
|
||||
- `length_function` (String): The function used to calculate the length of each chunk of text. In this case, it's set to 'len'. You can also use any function import directly as a string here.
|
||||
- `min_chunk_size` (Integer): The minimum size of each chunk of text that is sent to the language model. Must be less than `chunk_size`, and greater than `chunk_overlap`.
|
||||
|
||||
6. `cache` Section: (Optional)
|
||||
- `similarity_evaluation` (Optional): The config for similarity evaluation strategy. If not provided, the default `distance` based similarity evaluation strategy is used.
|
||||
- `strategy` (String): The strategy to use for similarity evaluation. Currently, only `distance` and `exact` based similarity evaluation is supported. Defaults to `distance`.
|
||||
- `max_distance` (Float): The bound of maximum distance. Defaults to `1.0`.
|
||||
- `positive` (Boolean): If the larger distance indicates more similar of two entities, set it `True`, otherwise `False`. Defaults to `False`.
|
||||
- `config` (Optional): The config for initializing the cache. If not provided, sensible default values are used as mentioned below.
|
||||
- `similarity_threshold` (Float): The threshold for similarity evaluation. Defaults to `0.8`.
|
||||
- `auto_flush` (Integer): The number of queries after which the cache is flushed. Defaults to `20`.
|
||||
<Note>
|
||||
If you provide a cache section, the app will automatically configure and use a cache to store the results of the language model. This is useful if you want to speed up the response time and save inference cost of your app.
|
||||
</Note>
|
||||
If you have questions about the configuration above, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -21,7 +21,7 @@ title: '📊 add'
|
||||
### Load data from webpage
|
||||
|
||||
```python Code example
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
@@ -32,7 +32,7 @@ app.add("https://www.forbes.com/profile/elon-musk")
|
||||
### Load data from sitemap
|
||||
|
||||
```python Code example
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://python.langchain.com/sitemap.xml", data_type="sitemap")
|
||||
@@ -18,6 +18,9 @@ title: '💬 chat'
|
||||
<ParamField path="where" type="dict" optional>
|
||||
A dictionary of key-value pairs to filter the chunks from the vector database. Defaults to `None`
|
||||
</ParamField>
|
||||
<ParamField path="session_id" type="str" optional>
|
||||
Session ID of the chat. This can be used to maintain chat history of different user sessions. Default value: `default`
|
||||
</ParamField>
|
||||
<ParamField path="citations" type="bool" optional>
|
||||
Return citations along with the LLM answer. Defaults to `False`
|
||||
</ParamField>
|
||||
@@ -36,7 +39,7 @@ title: '💬 chat'
|
||||
If you want to get the answer to question and return both answer and citations, use the following code snippet:
|
||||
|
||||
```python With Citations
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# Initialize app
|
||||
app = App()
|
||||
@@ -53,27 +56,39 @@ print(sources)
|
||||
# [
|
||||
# (
|
||||
# 'Elon Musk PROFILEElon MuskCEO, Tesla$247.1B$2.3B (0.96%)Real Time Net Worthas of 12/7/23 ...',
|
||||
# 'https://www.forbes.com/profile/elon-musk',
|
||||
# '4651b266--4aa78839fe97'
|
||||
# {
|
||||
# 'url': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'score': 0.89,
|
||||
# ...
|
||||
# }
|
||||
# ),
|
||||
# (
|
||||
# '74% of the company, which is now called X.Wealth HistoryHOVER TO REVEAL NET WORTH BY YEARForbes ...',
|
||||
# 'https://www.forbes.com/profile/elon-musk',
|
||||
# '4651b266--4aa78839fe97'
|
||||
# {
|
||||
# 'url': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'score': 0.81,
|
||||
# ...
|
||||
# }
|
||||
# ),
|
||||
# (
|
||||
# 'founded in 2002, is worth nearly $150 billion after a $750 million tender offer in June 2023 ...',
|
||||
# 'https://www.forbes.com/profile/elon-musk',
|
||||
# '4651b266--4aa78839fe97'
|
||||
# {
|
||||
# 'url': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'score': 0.73,
|
||||
# ...
|
||||
# }
|
||||
# )
|
||||
# ]
|
||||
```
|
||||
|
||||
<Note>
|
||||
When `citations=True`, note that the returned `sources` are a list of tuples where each tuple has three elements (in the following order):
|
||||
When `citations=True`, note that the returned `sources` are a list of tuples where each tuple has two elements (in the following order):
|
||||
1. source chunk
|
||||
2. link of the source document
|
||||
3. document id (used for book keeping purposes)
|
||||
2. dictionary with metadata about the source chunk
|
||||
- `url`: url of the source
|
||||
- `doc_id`: document id (used for book keeping purposes)
|
||||
- `score`: score of the source chunk with respect to the question
|
||||
- other metadata you might have added at the time of adding the source
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -82,7 +97,7 @@ When `citations=True`, note that the returned `sources` are a list of tuples whe
|
||||
If you just want to return answers and don't want to return citations, you can use the following example:
|
||||
|
||||
```python Without Citations
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# Initialize app
|
||||
app = App()
|
||||
@@ -95,3 +110,37 @@ answer = app.chat("What is the net worth of Elon?")
|
||||
print(answer)
|
||||
# Answer: The net worth of Elon Musk is $221.9 billion.
|
||||
```
|
||||
|
||||
### With session id
|
||||
|
||||
If you want to maintain chat sessions for different users, you can simply pass the `session_id` keyword argument. See the example below:
|
||||
|
||||
```python With session id
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
# Chat on your data using `.chat()`
|
||||
app.chat("What is the net worth of Elon Musk?", session_id="user1")
|
||||
# 'The net worth of Elon Musk is $250.8 billion.'
|
||||
app.chat("What is the net worth of Bill Gates?", session_id="user2")
|
||||
# "I don't know the current net worth of Bill Gates."
|
||||
app.chat("What was my last question", session_id="user1")
|
||||
# 'Your last question was "What is the net worth of Elon Musk?"'
|
||||
```
|
||||
|
||||
### With custom context window
|
||||
|
||||
If you want to customize the context window that you want to use during chat (default context window is 3 document chunks), you can do using the following code snippet:
|
||||
|
||||
```python with custom chunks size
|
||||
from embedchain import App
|
||||
from embedchain.config import BaseLlmConfig
|
||||
|
||||
app = App()
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
query_config = BaseLlmConfig(number_documents=5)
|
||||
app.chat("What is the net worth of Elon Musk?", config=query_config)
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: 🗑 delete
|
||||
---
|
||||
|
||||
## Delete Document
|
||||
|
||||
`delete()` method allows you to delete a document previously added to the app.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
forbes_doc_id = app.add("https://www.forbes.com/profile/elon-musk")
|
||||
wiki_doc_id = app.add("https://en.wikipedia.org/wiki/Elon_Musk")
|
||||
|
||||
app.delete(forbes_doc_id) # deletes the forbes document
|
||||
```
|
||||
|
||||
<Note>
|
||||
If you do not have the document id, you can use `app.db.get()` method to get the document and extract the `hash` key from `metadatas` dictionary object, which serves as the document id.
|
||||
</Note>
|
||||
|
||||
|
||||
## Delete Chat Session History
|
||||
|
||||
`delete_session_chat_history()` method allows you to delete all previous messages in a chat history.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
app.chat("What is the net worth of Elon Musk?")
|
||||
|
||||
app.delete_session_chat_history()
|
||||
```
|
||||
|
||||
<Note>
|
||||
`delete_session_chat_history(session_id="session_1")` method also accepts `session_id` optional param for deleting chat history of a specific session.
|
||||
It assumes the default session if no `session_id` is provided.
|
||||
</Note>
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: 🚀 deploy
|
||||
---
|
||||
|
||||
The `deploy()` method is currently available on an invitation-only basis. To request access, please submit your information via the provided [Google Form](https://forms.gle/vigN11h7b4Ywat668). We will review your request and respond promptly.
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: '📝 evaluate'
|
||||
---
|
||||
|
||||
`evaluate()` method is used to evaluate the performance of a RAG app. You can find the signature below:
|
||||
|
||||
### Parameters
|
||||
|
||||
<ParamField path="question" type="Union[str, list[str]]">
|
||||
A question or a list of questions to evaluate your app on.
|
||||
</ParamField>
|
||||
<ParamField path="metrics" type="Optional[list[Union[BaseMetric, str]]]" optional>
|
||||
The metrics to evaluate your app on. Defaults to all metrics: `["context_relevancy", "answer_relevancy", "groundedness"]`
|
||||
</ParamField>
|
||||
<ParamField path="num_workers" type="int" optional>
|
||||
Specify the number of threads to use for parallel processing.
|
||||
</ParamField>
|
||||
|
||||
### Returns
|
||||
|
||||
<ResponseField name="metrics" type="dict">
|
||||
Returns the metrics you have chosen to evaluate your app on as a dictionary.
|
||||
</ResponseField>
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
# add data source
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
# run evaluation
|
||||
app.evaluate("what is the net worth of Elon Musk?")
|
||||
# {'answer_relevancy': 0.958019958036268, 'context_relevancy': 0.12903225806451613}
|
||||
|
||||
# or
|
||||
# app.evaluate(["what is the net worth of Elon Musk?", "which companies does Elon Musk own?"])
|
||||
```
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: 📄 get
|
||||
---
|
||||
|
||||
## Get data sources
|
||||
|
||||
`get_data_sources()` returns a list of all the data sources added in the app.
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
|
||||
|
||||
data_sources = app.get_data_sources()
|
||||
# [
|
||||
# {
|
||||
# 'data_type': 'web_page',
|
||||
# 'data_value': 'https://en.wikipedia.org/wiki/Elon_Musk',
|
||||
# 'metadata': 'null'
|
||||
# },
|
||||
# {
|
||||
# 'data_type': 'web_page',
|
||||
# 'data_value': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'metadata': 'null'
|
||||
# }
|
||||
# ]
|
||||
```
|
||||
@@ -1,34 +1,34 @@
|
||||
---
|
||||
title: "Pipeline"
|
||||
title: "App"
|
||||
---
|
||||
|
||||
Create a RAG pipeline object on Embedchain. This is the main entrypoint for a developer to interact with Embedchain APIs. A pipeline configures the llm, vector database, embedding model, and retrieval strategy of your choice.
|
||||
Create a RAG app object on Embedchain. This is the main entrypoint for a developer to interact with Embedchain APIs. An app configures the llm, vector database, embedding model, and retrieval strategy of your choice.
|
||||
|
||||
### Attributes
|
||||
|
||||
<ParamField path="local_id" type="str">
|
||||
Pipeline ID
|
||||
App ID
|
||||
</ParamField>
|
||||
<ParamField path="name" type="str" optional>
|
||||
Name of the pipeline
|
||||
Name of the app
|
||||
</ParamField>
|
||||
<ParamField path="config" type="BaseConfig">
|
||||
Configuration of the pipeline
|
||||
Configuration of the app
|
||||
</ParamField>
|
||||
<ParamField path="llm" type="BaseLlm">
|
||||
Configured LLM for the RAG pipeline
|
||||
Configured LLM for the RAG app
|
||||
</ParamField>
|
||||
<ParamField path="db" type="BaseVectorDB">
|
||||
Configured vector database for the RAG pipeline
|
||||
Configured vector database for the RAG app
|
||||
</ParamField>
|
||||
<ParamField path="embedding_model" type="BaseEmbedder">
|
||||
Configured embedding model for the RAG pipeline
|
||||
Configured embedding model for the RAG app
|
||||
</ParamField>
|
||||
<ParamField path="chunker" type="ChunkerConfig">
|
||||
Chunker configuration
|
||||
</ParamField>
|
||||
<ParamField path="client" type="Client" optional>
|
||||
Client object (used to deploy a pipeline to Embedchain platform)
|
||||
Client object (used to deploy an app to Embedchain platform)
|
||||
</ParamField>
|
||||
<ParamField path="logger" type="logging.Logger">
|
||||
Logger object
|
||||
@@ -36,12 +36,12 @@ Create a RAG pipeline object on Embedchain. This is the main entrypoint for a de
|
||||
|
||||
## Usage
|
||||
|
||||
You can create an embedchain pipeline instance using the following methods:
|
||||
You can create an app instance using the following methods:
|
||||
|
||||
### Default setting
|
||||
|
||||
```python Code Example
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
app = App()
|
||||
```
|
||||
|
||||
@@ -49,7 +49,7 @@ app = App()
|
||||
### Python Dict
|
||||
|
||||
```python Code Example
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
config_dict = {
|
||||
'llm': {
|
||||
@@ -76,7 +76,7 @@ app = App.from_config(config=config_dict)
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load llm configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -103,7 +103,7 @@ embedder:
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load llm configuration from config.json file
|
||||
app = App.from_config(config_path="config.json")
|
||||
@@ -127,4 +127,4 @@ app = App.from_config(config_path="config.json")
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
</CodeGroup>
|
||||
@@ -36,7 +36,7 @@ title: '❓ query'
|
||||
If you want to get the answer to question and return both answer and citations, use the following code snippet:
|
||||
|
||||
```python With Citations
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# Initialize app
|
||||
app = App()
|
||||
@@ -53,27 +53,39 @@ print(sources)
|
||||
# [
|
||||
# (
|
||||
# 'Elon Musk PROFILEElon MuskCEO, Tesla$247.1B$2.3B (0.96%)Real Time Net Worthas of 12/7/23 ...',
|
||||
# 'https://www.forbes.com/profile/elon-musk',
|
||||
# '4651b266--4aa78839fe97'
|
||||
# {
|
||||
# 'url': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'score': 0.89,
|
||||
# ...
|
||||
# }
|
||||
# ),
|
||||
# (
|
||||
# '74% of the company, which is now called X.Wealth HistoryHOVER TO REVEAL NET WORTH BY YEARForbes ...',
|
||||
# 'https://www.forbes.com/profile/elon-musk',
|
||||
# '4651b266--4aa78839fe97'
|
||||
# {
|
||||
# 'url': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'score': 0.81,
|
||||
# ...
|
||||
# }
|
||||
# ),
|
||||
# (
|
||||
# 'founded in 2002, is worth nearly $150 billion after a $750 million tender offer in June 2023 ...',
|
||||
# 'https://www.forbes.com/profile/elon-musk',
|
||||
# '4651b266--4aa78839fe97'
|
||||
# {
|
||||
# 'url': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'score': 0.73,
|
||||
# ...
|
||||
# }
|
||||
# )
|
||||
# ]
|
||||
```
|
||||
|
||||
<Note>
|
||||
When `citations=True`, note that the returned `sources` are a list of tuples where each tuple has three elements (in the following order):
|
||||
When `citations=True`, note that the returned `sources` are a list of tuples where each tuple has two elements (in the following order):
|
||||
1. source chunk
|
||||
2. link of the source document
|
||||
3. document id (used for book keeping purposes)
|
||||
2. dictionary with metadata about the source chunk
|
||||
- `url`: url of the source
|
||||
- `doc_id`: document id (used for book keeping purposes)
|
||||
- `score`: score of the source chunk with respect to the question
|
||||
- other metadata you might have added at the time of adding the source
|
||||
</Note>
|
||||
|
||||
### Without citations
|
||||
@@ -81,7 +93,7 @@ When `citations=True`, note that the returned `sources` are a list of tuples whe
|
||||
If you just want to return answers and don't want to return citations, you can use the following example:
|
||||
|
||||
```python Without Citations
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# Initialize app
|
||||
app = App()
|
||||
@@ -7,7 +7,7 @@ title: 🔄 reset
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
title: '🔍 search'
|
||||
---
|
||||
|
||||
`.search()` enables you to uncover the most pertinent context by performing a semantic search across your data sources based on a given query. Refer to the function signature below:
|
||||
|
||||
### Parameters
|
||||
|
||||
<ParamField path="query" type="str">
|
||||
Question
|
||||
</ParamField>
|
||||
<ParamField path="num_documents" type="int" optional>
|
||||
Number of relevant documents to fetch. Defaults to `3`
|
||||
</ParamField>
|
||||
<ParamField path="where" type="dict" optional>
|
||||
Key value pair for metadata filtering.
|
||||
</ParamField>
|
||||
<ParamField path="raw_filter" type="dict" optional>
|
||||
Pass raw filter query based on your vector database.
|
||||
Currently, `raw_filter` param is only supported for Pinecone vector database.
|
||||
</ParamField>
|
||||
|
||||
### Returns
|
||||
|
||||
<ResponseField name="answer" type="dict">
|
||||
Return list of dictionaries that contain the relevant chunk and their source information.
|
||||
</ResponseField>
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic
|
||||
|
||||
Refer to the following example on how to use the search api:
|
||||
|
||||
```python Code example
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
context = app.search("What is the net worth of Elon?", num_documents=2)
|
||||
print(context)
|
||||
```
|
||||
|
||||
### Advanced
|
||||
|
||||
#### Metadata filtering using `where` params
|
||||
|
||||
Here is an advanced example of `search()` API with metadata filtering on pinecone database:
|
||||
|
||||
```python
|
||||
import os
|
||||
|
||||
from embedchain import App
|
||||
|
||||
os.environ["PINECONE_API_KEY"] = "xxx"
|
||||
|
||||
config = {
|
||||
"vectordb": {
|
||||
"provider": "pinecone",
|
||||
"config": {
|
||||
"metric": "dotproduct",
|
||||
"vector_dimension": 1536,
|
||||
"index_name": "ec-test",
|
||||
"serverless_config": {"cloud": "aws", "region": "us-west-2"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
app = App.from_config(config=config)
|
||||
|
||||
app.add("https://www.forbes.com/profile/bill-gates", metadata={"type": "forbes", "person": "gates"})
|
||||
app.add("https://en.wikipedia.org/wiki/Bill_Gates", metadata={"type": "wiki", "person": "gates"})
|
||||
|
||||
results = app.search("What is the net worth of Bill Gates?", where={"person": "gates"})
|
||||
print("Num of search results: ", len(results))
|
||||
```
|
||||
|
||||
#### Metadata filtering using `raw_filter` params
|
||||
|
||||
Following is an example of metadata filtering by passing the raw filter query that pinecone vector database follows:
|
||||
|
||||
```python
|
||||
import os
|
||||
|
||||
from embedchain import App
|
||||
|
||||
os.environ["PINECONE_API_KEY"] = "xxx"
|
||||
|
||||
config = {
|
||||
"vectordb": {
|
||||
"provider": "pinecone",
|
||||
"config": {
|
||||
"metric": "dotproduct",
|
||||
"vector_dimension": 1536,
|
||||
"index_name": "ec-test",
|
||||
"serverless_config": {"cloud": "aws", "region": "us-west-2"},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
app = App.from_config(config=config)
|
||||
|
||||
app.add("https://www.forbes.com/profile/bill-gates", metadata={"year": 2022, "person": "gates"})
|
||||
app.add("https://en.wikipedia.org/wiki/Bill_Gates", metadata={"year": 2024, "person": "gates"})
|
||||
|
||||
print("Filter with person: gates and year > 2023")
|
||||
raw_filter = {"$and": [{"person": "gates"}, {"year": {"$gt": 2023}}]}
|
||||
results = app.search("What is the net worth of Bill Gates?", raw_filter=raw_filter)
|
||||
print("Num of search results: ", len(results))
|
||||
```
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
title: 🗑 delete
|
||||
---
|
||||
|
||||
`delete_chat_history()` method allows you to delete all previous messages in a chat history.
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
|
||||
app = App()
|
||||
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
app.chat("What is the net worth of Elon Musk?")
|
||||
|
||||
app.delete_chat_history()
|
||||
```
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
title: 🚀 deploy
|
||||
---
|
||||
|
||||
Using the `deploy()` method, Embedchain allows developers to easily launch their LLM-powered applications on the [Embedchain Platform](https://app.embedchain.ai). This platform facilitates seamless access to your data's context via a free and user-friendly REST API. Once your pipeline is deployed, you can update your data sources at any time.
|
||||
|
||||
The `deploy()` method not only deploys your pipeline but also efficiently manages LLMs, vector databases, embedding models, and data syncing, enabling you to focus on querying, chatting, or searching without the hassle of infrastructure management.
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
|
||||
# Initialize app
|
||||
app = App()
|
||||
|
||||
# Add data source
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
# Deploy your pipeline to Embedchain Platform
|
||||
app.deploy()
|
||||
|
||||
# 🔑 Enter your Embedchain API key. You can find the API key at https://app.embedchain.ai/settings/keys/
|
||||
# ec-xxxxxx
|
||||
|
||||
# 🛠️ Creating pipeline on the platform...
|
||||
# 🎉🎉🎉 Pipeline created successfully! View your pipeline: https://app.embedchain.ai/pipelines/xxxxx
|
||||
|
||||
# 🛠️ Adding data to your pipeline...
|
||||
# ✅ Data of type: web_page, value: https://www.forbes.com/profile/elon-musk added successfully.
|
||||
```
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
title: '🔍 search'
|
||||
---
|
||||
|
||||
`.search()` enables you to uncover the most pertinent context by performing a semantic search across your data sources based on a given query. Refer to the function signature below:
|
||||
|
||||
### Parameters
|
||||
|
||||
<ParamField path="query" type="str">
|
||||
Question
|
||||
</ParamField>
|
||||
<ParamField path="num_documents" type="int" optional>
|
||||
Number of relevant documents to fetch. Defaults to `3`
|
||||
</ParamField>
|
||||
|
||||
### Returns
|
||||
|
||||
<ResponseField name="answer" type="dict">
|
||||
Return list of dictionaries that contain the relevant chunk and their source information.
|
||||
</ResponseField>
|
||||
|
||||
## Usage
|
||||
|
||||
Refer to the following example on how to use the search api:
|
||||
|
||||
```python Code example
|
||||
from embedchain import Pipeline as App
|
||||
|
||||
# Initialize app
|
||||
app = App()
|
||||
|
||||
# Add data source
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
# Get relevant context using semantic search
|
||||
context = app.search("What is the net worth of Elon?", num_documents=2)
|
||||
print(context)
|
||||
# Context:
|
||||
# [
|
||||
# {
|
||||
# 'context': 'Elon Musk PROFILEElon MuskCEO, Tesla$221.9BReal Time Net Worthas of 10/29/23Reflects change since 5 pm ET of prior trading day. 1 in the world todayPhoto by Martin Schoeller for ForbesAbout Elon MuskElon Musk cofounded six companies, including electric car maker Tesla, rocket producer SpaceX and tunneling startup Boring Company.He owns about 21% of Tesla between stock and options, but has pledged more than half his shares as collateral for personal loans of up to $3.5 billion.SpaceX, founded in',
|
||||
# 'source': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'document_id': 'some_document_id'
|
||||
# },
|
||||
# {
|
||||
# 'context': 'company, which is now called X.Wealth HistoryHOVER TO REVEAL NET WORTH BY YEARForbes Lists 1Forbes 400 (2023)The Richest Person In Every State (2023) 2Billionaires (2023) 1Innovative Leaders (2019) 25Powerful People (2018) 12Richest In Tech (2017)Global Game Changers (2016)More ListsPersonal StatsAge52Source of WealthTesla, SpaceX, Self MadeSelf-Made Score8Philanthropy Score1ResidenceAustin, TexasCitizenshipUnited StatesMarital StatusSingleChildren11EducationBachelor of Arts/Science, University',
|
||||
# 'source': 'https://www.forbes.com/profile/elon-musk',
|
||||
# 'document_id': 'some_document_id'
|
||||
# }
|
||||
# ]
|
||||
```
|
||||
@@ -8,7 +8,7 @@ We believe in building a vibrant and supportive community around embedchain. The
|
||||
<Card title="Twitter" icon="twitter" href="https://twitter.com/embedchain">
|
||||
Follow us on Twitter
|
||||
</Card>
|
||||
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
|
||||
<Card title="Slack" icon="slack" href="https://embedchain.ai/slack" color="#4A154B">
|
||||
Join our slack community
|
||||
</Card>
|
||||
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
|
||||
|
||||
@@ -5,7 +5,7 @@ title: "🐝 Beehiiv"
|
||||
To add any Beehiiv data sources to your app, just add the base url as the source and set the data_type to `beehiiv`.
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -2,18 +2,27 @@
|
||||
title: '📊 CSV'
|
||||
---
|
||||
|
||||
To add any csv file, use the data_type as `csv`. `csv` allows remote urls and conventional file paths. Headers are included for each line, so if you have an `age` column, `18` will be added as `age: 18`. Eg:
|
||||
You can load any csv file from your local file system or through a URL. Headers are included for each line, so if you have an `age` column, `18` will be added as `age: 18`.
|
||||
|
||||
## Usage
|
||||
|
||||
### Load from a local file
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
|
||||
from embedchain import App
|
||||
app = App()
|
||||
app.add('https://people.sc.fsu.edu/~jburkardt/data/csv/airtravel.csv', data_type="csv")
|
||||
# Or add using the local file path
|
||||
# app.add('/path/to/file.csv', data_type="csv")
|
||||
|
||||
app.query("Summarize the air travel data")
|
||||
# Answer: The air travel data shows the number of flights for the months of July in the years 1958, 1959, and 1960. In July 1958, there were 491 flights, in July 1959 there were 548 flights, and in July 1960 there were 622 flights.
|
||||
app.add('/path/to/file.csv', data_type='csv')
|
||||
```
|
||||
|
||||
Note: There is a size limit allowed for csv file beyond which it can throw error. This limit is set by the LLMs. Please consider chunking large csv files into smaller csv files.
|
||||
### Load from URL
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
app = App()
|
||||
app.add('https://people.sc.fsu.edu/~jburkardt/data/csv/airtravel.csv', data_type="csv")
|
||||
```
|
||||
|
||||
<Note>
|
||||
There is a size limit allowed for csv file beyond which it can throw error. This limit is set by the LLMs. Please consider chunking large csv files into smaller csv files.
|
||||
</Note>
|
||||
|
||||
|
||||
@@ -5,13 +5,14 @@ title: '⚙️ Custom'
|
||||
When we say "custom", we mean that you can customize the loader and chunker to your needs. This is done by passing a custom loader and chunker to the `add` method.
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
import your_loader
|
||||
import your_chunker
|
||||
from my_module import CustomLoader
|
||||
from my_module import CustomChunker
|
||||
|
||||
app = App()
|
||||
loader = your_loader()
|
||||
chunker = your_chunker()
|
||||
loader = CustomLoader()
|
||||
chunker = CustomChunker()
|
||||
|
||||
app.add("source", data_type="custom", loader=loader, chunker=chunker)
|
||||
```
|
||||
@@ -27,7 +28,7 @@ app.add("source", data_type="custom", loader=loader, chunker=chunker)
|
||||
Example:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
from embedchain.loaders.github import GithubLoader
|
||||
|
||||
app = App()
|
||||
|
||||
@@ -35,7 +35,7 @@ Default behavior is to create a persistent vector db in the directory **./db**.
|
||||
Create a local index:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
naval_chat_bot = App()
|
||||
naval_chat_bot.add("https://www.youtube.com/watch?v=3qHkcs3kG44")
|
||||
@@ -45,7 +45,7 @@ naval_chat_bot.add("https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Alma
|
||||
You can reuse the local index with the same code, but without adding new documents:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
naval_chat_bot = App()
|
||||
print(naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?"))
|
||||
@@ -56,7 +56,7 @@ print(naval_chat_bot.query("What unique capacity does Naval argue humans possess
|
||||
You can reset the app by simply calling the `reset` method. This will delete the vector database and all other app related files.
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://www.youtube.com/watch?v=3qHkcs3kG44")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: '📁 Directory'
|
||||
title: '📁 Directory/Folder'
|
||||
---
|
||||
|
||||
To use an entire directory as data source, just add `data_type` as `directory` and pass in the path of the local directory.
|
||||
@@ -8,7 +8,7 @@ To use an entire directory as data source, just add `data_type` as `directory` a
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xxx"
|
||||
|
||||
@@ -23,7 +23,7 @@ print(response)
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
from embedchain.loaders.directory_loader import DirectoryLoader
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xxx"
|
||||
|
||||
@@ -12,7 +12,7 @@ To add any Discord channel messages to your app, just add the `channel_id` as th
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# add your discord "BOT" token
|
||||
os.environ["DISCORD_TOKEN"] = "xxx"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: '📚 Code documentation'
|
||||
title: '📚 Code Docs website'
|
||||
---
|
||||
|
||||
To add any code documentation website as a loader, use the data_type as `docs_site`. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://docs.embedchain.ai/", data_type="docs_site")
|
||||
app.query("What is Embedchain?")
|
||||
# Answer: Embedchain is a platform that utilizes various components, including paid/proprietary ones, to provide what is believed to be the best configuration available. It uses LLM (Language Model) providers such as OpenAI, Anthpropic, Vertex_AI, GPT4ALL, Azure_OpenAI, LLAMA2, JINA, Ollama and COHERE. Embedchain allows users to import and utilize these LLM providers for their applications.'
|
||||
# Answer: Embedchain is a platform that utilizes various components, including paid/proprietary ones, to provide what is believed to be the best configuration available. It uses LLM (Language Model) providers such as OpenAI, Anthpropic, Vertex_AI, GPT4ALL, Azure_OpenAI, LLAMA2, JINA, Ollama, Together and COHERE. Embedchain allows users to import and utilize these LLM providers for their applications.'
|
||||
```
|
||||
|
||||
@@ -7,7 +7,7 @@ title: '📄 Docx file'
|
||||
To add any doc/docx file, use the data_type as `docx`. `docx` allows remote urls and conventional file paths. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add('https://example.com/content/intro.docx', data_type="docx")
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: '💾 Dropbox'
|
||||
---
|
||||
|
||||
To load folders or files from your Dropbox account, configure the `data_type` parameter as `dropbox` and specify the path to the desired file or folder, starting from the root directory of your Dropbox account.
|
||||
|
||||
For Dropbox access, an **access token** is required. Obtain this token by visiting [Dropbox Developer Apps](https://www.dropbox.com/developers/apps). There, create a new app and generate an access token for it.
|
||||
|
||||
Ensure your app has the following settings activated:
|
||||
|
||||
- In the Permissions section, enable `files.content.read` and `files.metadata.read`.
|
||||
|
||||
## Usage
|
||||
|
||||
Install the `dropbox` pypi package:
|
||||
|
||||
```bash
|
||||
pip install dropbox
|
||||
```
|
||||
|
||||
Following is an example of how to use the dropbox loader:
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import App
|
||||
|
||||
os.environ["DROPBOX_ACCESS_TOKEN"] = "sl.xxx"
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xxx"
|
||||
|
||||
app = App()
|
||||
|
||||
# any path from the root of your dropbox account, you can leave it "" for the root folder
|
||||
app.add("/test", data_type="dropbox")
|
||||
|
||||
print(app.query("Which two celebrities are mentioned here?"))
|
||||
# The two celebrities mentioned in the given context are Elon Musk and Jeff Bezos.
|
||||
```
|
||||
@@ -24,7 +24,7 @@ To use this you need to save `credentials.json` in the directory from where you
|
||||
12. Put the `.json` file in your current directory and rename it to `credentials.json`
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: 'Google Drive'
|
||||
---
|
||||
|
||||
To use GoogleDriveLoader you must install the extra dependencies with `pip install --upgrade embedchain[googledrive]`.
|
||||
|
||||
The data_type must be `google_drive`. Otherwise, it will be considered a regular web page.
|
||||
|
||||
Google Drive requires the setup of credentials. This can be done by following the steps below:
|
||||
|
||||
1. Go to the [Google Cloud Console](https://console.cloud.google.com/apis/credentials).
|
||||
2. Create a project if you don't have one already.
|
||||
3. Enable the [Google Drive API](https://console.cloud.google.com/flows/enableapi?apiid=drive.googleapis.com)
|
||||
4. [Authorize credentials for desktop app](https://developers.google.com/drive/api/quickstart/python#authorize_credentials_for_a_desktop_application)
|
||||
5. When done, you will be able to download the credentials in `json` format. Rename the downloaded file to `credentials.json` and save it in `~/.credentials/credentials.json`
|
||||
6. Set the environment variable `GOOGLE_APPLICATION_CREDENTIALS=~/.credentials/credentials.json`
|
||||
|
||||
The first time you use the loader, you will be prompted to enter your Google account credentials.
|
||||
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
url = "https://drive.google.com/drive/u/0/folders/xxx-xxx"
|
||||
app.add(url, data_type="google_drive")
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: "🖼️ Image"
|
||||
---
|
||||
|
||||
|
||||
To use an image as data source, just add `data_type` as `image` and pass in the path of the image (local or hosted).
|
||||
|
||||
We use [GPT4 Vision](https://platform.openai.com/docs/guides/vision) to generate meaning of the image using a custom prompt, and then use the generated text as the data source.
|
||||
|
||||
You would require an OpenAI API key with access to `gpt-4-vision-preview` model to use this feature.
|
||||
|
||||
### Without customization
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import App
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xxx"
|
||||
|
||||
app = App()
|
||||
app.add("./Elon-Musk.webp", data_type="image")
|
||||
response = app.query("Describe the man in the image.")
|
||||
print(response)
|
||||
# Answer: The man in the image is dressed in formal attire, wearing a dark suit jacket and a white collared shirt. He has short hair and is standing. He appears to be gazing off to the side with a reflective expression. The background is dark with faint, warm-toned vertical lines, possibly from a lit environment behind the individual or reflections. The overall atmosphere is somewhat moody and introspective.
|
||||
```
|
||||
|
||||
### Customization
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import App
|
||||
from embedchain.loaders.image import ImageLoader
|
||||
|
||||
image_loader = ImageLoader(
|
||||
max_tokens=100,
|
||||
api_key="sk-xxx",
|
||||
prompt="Is the person looking wealthy? Structure your thoughts around what you see in the image.",
|
||||
)
|
||||
|
||||
app = App()
|
||||
app.add("./Elon-Musk.webp", data_type="image", loader=image_loader)
|
||||
response = app.query("Describe the man in the image.")
|
||||
print(response)
|
||||
# Answer: The man in the image appears to be well-dressed in a suit and shirt, suggesting that he may be in a professional or formal setting. His composed demeanor and confident posture further indicate a sense of self-assurance. Based on these visual cues, one could infer that the man may have a certain level of economic or social status, possibly indicating wealth or professional success.
|
||||
```
|
||||
@@ -21,7 +21,7 @@ If you would like to add other data structures (e.g. list, dict etc.), convert i
|
||||
<CodeGroup>
|
||||
|
||||
```python python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ title: '📝 Mdx file'
|
||||
To add any `.mdx` file to your app, use the data_type (first argument to `.add()` method) as `mdx`. Note that this supports support mdx file present on machine, so this should be a file path. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add('path/to/file.mdx', data_type='mdx')
|
||||
|
||||
@@ -8,7 +8,7 @@ To load a notion page, use the data_type as `notion`. Since it is hard to automa
|
||||
The next argument must **end** with the `notion page id`. The id is a 32-character string. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ title: 🙌 OpenAPI
|
||||
To add any OpenAPI spec yaml file (currently the json file will be detected as JSON data type), use the data_type as 'openapi'. 'openapi' allows remote urls and conventional file paths.
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -8,28 +8,31 @@ Embedchain comes with built-in support for various data sources. We handle the c
|
||||
<Card title="📰 PDF file" href="/components/data-sources/pdf-file"></Card>
|
||||
<Card title="📊 CSV file" href="/components/data-sources/csv"></Card>
|
||||
<Card title="📃 JSON file" href="/components/data-sources/json"></Card>
|
||||
<Card title="📺 Youtube" href="/components/data-sources/youtube-video"></Card>
|
||||
<Card title="📝 Text" href="/components/data-sources/text"></Card>
|
||||
<Card title="📚 Documentation website" href="/components/data-sources/docs-site"></Card>
|
||||
<Card title="📄 DOCX file" href="/components/data-sources/docx"></Card>
|
||||
<Card title="📁 Directory/ Folder" href="/components/data-sources/directory"></Card>
|
||||
<Card title="🌐 HTML Web page" href="/components/data-sources/web-page"></Card>
|
||||
<Card title="📽️ Youtube Channel" href="/components/data-sources/youtube-channel"></Card>
|
||||
<Card title="📺 Youtube Video" href="/components/data-sources/youtube-video"></Card>
|
||||
<Card title="📚 Docs website" href="/components/data-sources/docs-site"></Card>
|
||||
<Card title="📝 MDX file" href="/components/data-sources/mdx"></Card>
|
||||
<Card title="📄 DOCX file" href="/components/data-sources/docx"></Card>
|
||||
<Card title="📓 Notion" href="/components/data-sources/notion"></Card>
|
||||
<Card title="❓💬 Q&A pair" href="/components/data-sources/qna"></Card>
|
||||
<Card title="🗺️ Sitemap" href="/components/data-sources/sitemap"></Card>
|
||||
<Card title="🌐 Web page" href="/components/data-sources/web-page"></Card>
|
||||
<Card title="🧾 XML file" href="/components/data-sources/xml"></Card>
|
||||
<Card title="❓💬 Q&A pair" href="/components/data-sources/qna"></Card>
|
||||
<Card title="🙌 OpenAPI" href="/components/data-sources/openapi"></Card>
|
||||
<Card title="📬 Gmail" href="/components/data-sources/gmail"></Card>
|
||||
<Card title="📝 Github" href="/components/data-sources/github"></Card>
|
||||
<Card title="🐘 Postgres" href="/components/data-sources/postgres"></Card>
|
||||
<Card title="🐬 MySQL" href="/components/data-sources/mysql"></Card>
|
||||
<Card title="🤖 Slack" href="/components/data-sources/slack"></Card>
|
||||
<Card title="🗨️ Discourse" href="/components/data-sources/discourse"></Card>
|
||||
<Card title="💬 Discord" href="/components/data-sources/discord"></Card>
|
||||
<Card title="📝 Github" href="/components/data-sources/github"></Card>
|
||||
<Card title="⚙️ Custom" href="/components/data-sources/custom"></Card>
|
||||
<Card title="🗨️ Discourse" href="/components/data-sources/discourse"></Card>
|
||||
<Card title="📝 Substack" href="/components/data-sources/substack"></Card>
|
||||
<Card title="🐝 Beehiiv" href="/components/data-sources/beehiiv"></Card>
|
||||
<Card title="📁 Directory" href="/components/data-sources/directory"></Card>
|
||||
<Card title="💾 Dropbox" href="/components/data-sources/dropbox"></Card>
|
||||
<Card title="🖼️ Image" href="/components/data-sources/image"></Card>
|
||||
<Card title="⚙️ Custom" href="/components/data-sources/custom"></Card>
|
||||
</CardGroup>
|
||||
|
||||
<br/ >
|
||||
|
||||
@@ -1,17 +1,43 @@
|
||||
---
|
||||
title: '📰 PDF file'
|
||||
title: '📰 PDF'
|
||||
---
|
||||
|
||||
To add any pdf file, use the data_type as `pdf_file`. Eg:
|
||||
You can load any pdf file from your local file system or through a URL.
|
||||
|
||||
## Usage
|
||||
|
||||
### Load from a local file
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
|
||||
from embedchain import App
|
||||
app = App()
|
||||
|
||||
app.add('https://arxiv.org/pdf/1706.03762.pdf', data_type='pdf_file')
|
||||
app.query("What is the paper 'attention is all you need' about?")
|
||||
# Answer: The paper "Attention Is All You Need" proposes a new network architecture called the Transformer, which is based solely on attention mechanisms. It suggests moving away from complex recurrent or convolutional neural networks and instead using attention mechanisms to connect the encoder and decoder in sequence transduction models.
|
||||
app.add('/path/to/file.pdf', data_type='pdf_file')
|
||||
```
|
||||
|
||||
Note that we do not support password protected pdfs.
|
||||
### Load from URL
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
app = App()
|
||||
app.add('https://arxiv.org/pdf/1706.03762.pdf', data_type='pdf_file')
|
||||
app.query("What is the paper 'attention is all you need' about?", citations=True)
|
||||
# Answer: The paper "Attention Is All You Need" proposes a new network architecture called the Transformer, which is based solely on attention mechanisms. It suggests that complex recurrent or convolutional neural networks can be replaced with a simpler architecture that connects the encoder and decoder through attention. The paper discusses how this approach can improve sequence transduction models, such as neural machine translation.
|
||||
# Contexts:
|
||||
# [
|
||||
# (
|
||||
# 'Provided proper attribution is ...',
|
||||
# {
|
||||
# 'page': 0,
|
||||
# 'url': 'https://arxiv.org/pdf/1706.03762.pdf',
|
||||
# 'score': 0.3676220203221626,
|
||||
# ...
|
||||
# }
|
||||
# ),
|
||||
# ]
|
||||
```
|
||||
|
||||
We also store the page number under the key `page` with each chunk that helps understand where the answer is coming from. You can fetch the `page` key while during retrieval (refer to the example given above).
|
||||
|
||||
<Note>
|
||||
Note that we do not support password protected pdf files.
|
||||
</Note>
|
||||
|
||||
@@ -5,7 +5,7 @@ title: '❓💬 Queston and answer pair'
|
||||
QnA pair is a local data type. To supply your own QnA pair, use the data_type as `qna_pair` and enter a tuple. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ title: '🗺️ Sitemap'
|
||||
Add all web pages from an xml-sitemap. Filters non-text files. Use the data_type as `sitemap`. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ This will automatically retrieve data from the workspace associated with the use
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["SLACK_USER_TOKEN"] = "xoxp-xxx"
|
||||
app = App()
|
||||
|
||||
@@ -5,7 +5,7 @@ title: "📝 Substack"
|
||||
To add any Substack data sources to your app, just add the main base url as the source and set the data_type to `substack`.
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ title: '📝 Text'
|
||||
Text is a local data type. To supply your own text, use the data_type as `text` and enter a string. The text is not processed, this can be very versatile. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
---
|
||||
title: '🌐 Web page'
|
||||
title: '🌐 HTML Web page'
|
||||
---
|
||||
|
||||
To add any web page, use the data_type as `web_page`. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ title: '🧾 XML file'
|
||||
To add any xml file, use the data_type as `xml`. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: '📽️ Youtube Channel'
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
Make sure you have all the required packages installed before using this data type. You can install them by running the following command in your terminal.
|
||||
|
||||
```bash
|
||||
pip install -u "embedchain[youtube]"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To add all the videos from a youtube channel to your app, use the data_type as `youtube_channel`.
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("@channel_name", data_type="youtube_channel")
|
||||
```
|
||||
@@ -1,12 +1,21 @@
|
||||
---
|
||||
title: '📺 Youtube'
|
||||
title: '📺 Youtube Video'
|
||||
---
|
||||
|
||||
## Setup
|
||||
|
||||
To add any youtube video to your app, use the data_type (first argument to `.add()` method) as `youtube_video`. Eg:
|
||||
Make sure you have all the required packages installed before using this data type. You can install them by running the following command in your terminal.
|
||||
|
||||
```bash
|
||||
pip install -u "embedchain[youtube]"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To add any youtube video to your app, use the data_type as `youtube_video`. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add('a_valid_youtube_url_here', data_type='youtube_video')
|
||||
|
||||
@@ -25,7 +25,7 @@ Once you have obtained the key, you can use it like this:
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'xxx'
|
||||
|
||||
@@ -40,7 +40,27 @@ app.query("What is OpenAI?")
|
||||
embedder:
|
||||
provider: openai
|
||||
config:
|
||||
model: 'text-embedding-ada-002'
|
||||
model: 'text-embedding-3-small'
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
* OpenAI announced two new embedding models: `text-embedding-3-small` and `text-embedding-3-large`. Embedchain supports both these models. Below you can find YAML config for both:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```yaml text-embedding-3-small.yaml
|
||||
embedder:
|
||||
provider: openai
|
||||
config:
|
||||
model: 'text-embedding-3-small'
|
||||
```
|
||||
|
||||
```yaml text-embedding-3-large.yaml
|
||||
embedder:
|
||||
provider: openai
|
||||
config:
|
||||
model: 'text-embedding-3-large'
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
@@ -52,7 +72,7 @@ To use Google AI embedding function, you have to set the `GOOGLE_API_KEY` enviro
|
||||
<CodeGroup>
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["GOOGLE_API_KEY"] = "xxx"
|
||||
|
||||
@@ -81,7 +101,7 @@ To use Azure OpenAI embedding model, you have to set some of the azure openai re
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["OPENAI_API_TYPE"] = "azure"
|
||||
os.environ["AZURE_OPENAI_ENDPOINT"] = "https://xxx.openai.azure.com/"
|
||||
@@ -119,7 +139,7 @@ GPT4All supports generating high quality embeddings of arbitrary length document
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load embedding model configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -148,7 +168,7 @@ Hugging Face supports generating embeddings of arbitrary length documents of tex
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load embedding model configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -179,7 +199,7 @@ Embedchain supports Google's VertexAI embeddings model through a simple interfac
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load embedding model configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
---
|
||||
title: 🔬 Evaluation
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
We provide out-of-the-box evaluation metrics for your RAG application. You can use them to evaluate your RAG applications and compare against different settings of your production RAG application.
|
||||
|
||||
Currently, we provide support for following evaluation metrics:
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Context Relevancy" href="#context_relevancy"></Card>
|
||||
<Card title="Answer Relevancy" href="#answer_relevancy"></Card>
|
||||
<Card title="Groundedness" href="#groundedness"></Card>
|
||||
<Card title="Custom Metric" href="#custom_metric"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Quickstart
|
||||
|
||||
Here is a basic example of running evaluation:
|
||||
|
||||
```python example.py
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
# Add data sources
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
# Run evaluation
|
||||
app.evaluate(["What is the net worth of Elon Musk?", "How many companies Elon Musk owns?"])
|
||||
# {'answer_relevancy': 0.9987286412340826, 'groundedness': 1.0, 'context_relevancy': 0.3571428571428571}
|
||||
```
|
||||
|
||||
Under the hood, Embedchain does the following:
|
||||
|
||||
1. Runs semantic search in the vector database and fetches context
|
||||
2. LLM call with question, context to fetch the answer
|
||||
3. Run evaluation on following metrics: `context relevancy`, `groundedness`, and `answer relevancy` and return result
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
We use OpenAI's `gpt-4` model as default LLM model for automatic evaluation. Hence, we require you to set `OPENAI_API_KEY` as an environment variable.
|
||||
|
||||
### Step-1: Create dataset
|
||||
|
||||
In order to evaluate your RAG application, you have to setup a dataset. A data point in the dataset consists of `questions`, `contexts`, `answer`. Here is an example of how to create a dataset for evaluation:
|
||||
|
||||
```python
|
||||
from embedchain.utils.eval import EvalData
|
||||
|
||||
data = [
|
||||
{
|
||||
"question": "What is the net worth of Elon Musk?",
|
||||
"contexts": [
|
||||
"Elon Musk PROFILEElon MuskCEO, ...",
|
||||
"a Twitter poll on whether the journalists' ...",
|
||||
"2016 and run by Jared Birchall.[335]...",
|
||||
],
|
||||
"answer": "As of the information provided, Elon Musk's net worth is $241.6 billion.",
|
||||
},
|
||||
{
|
||||
"question": "which companies does Elon Musk own?",
|
||||
"contexts": [
|
||||
"of December 2023[update], ...",
|
||||
"ThielCofounderView ProfileTeslaHolds ...",
|
||||
"Elon Musk PROFILEElon MuskCEO, ...",
|
||||
],
|
||||
"answer": "Elon Musk owns several companies, including Tesla, SpaceX, Neuralink, and The Boring Company.",
|
||||
},
|
||||
]
|
||||
|
||||
dataset = []
|
||||
|
||||
for d in data:
|
||||
eval_data = EvalData(question=d["question"], contexts=d["contexts"], answer=d["answer"])
|
||||
dataset.append(eval_data)
|
||||
```
|
||||
|
||||
### Step-2: Run evaluation
|
||||
|
||||
Once you have created your dataset, you can run evaluation on the dataset by picking the metric you want to run evaluation on.
|
||||
|
||||
For example, you can run evaluation on context relevancy metric using the following code:
|
||||
|
||||
```python
|
||||
from embedchain.evaluation.metrics import ContextRelevance
|
||||
metric = ContextRelevance()
|
||||
score = metric.evaluate(dataset)
|
||||
print(score)
|
||||
```
|
||||
|
||||
You can choose a different metric or write your own to run evaluation on. You can check the following links:
|
||||
|
||||
- [Context Relevancy](#context_relevancy)
|
||||
- [Answer relenvancy](#answer_relevancy)
|
||||
- [Groundedness](#groundedness)
|
||||
- [Build your own metric](#custom_metric)
|
||||
|
||||
## Metrics
|
||||
|
||||
### Context Relevancy <a id="context_relevancy"></a>
|
||||
|
||||
Context relevancy is a metric to determine "how relevant the context is to the question". We use OpenAI's `gpt-4` model to determine the relevancy of the context. We achieve this by prompting the model with the question and the context and asking it to return relevant sentences from the context. We then use the following formula to determine the score:
|
||||
|
||||
```
|
||||
context_relevance_score = num_relevant_sentences_in_context / num_of_sentences_in_context
|
||||
```
|
||||
|
||||
#### Examples
|
||||
|
||||
You can run the context relevancy evaluation with the following simple code:
|
||||
|
||||
```python
|
||||
from embedchain.evaluation.metrics import ContextRelevance
|
||||
|
||||
metric = ContextRelevance()
|
||||
score = metric.evaluate(dataset) # 'dataset' is definted in the create dataset section
|
||||
print(score)
|
||||
# 0.27975528364849833
|
||||
```
|
||||
|
||||
In the above example, we used sensible defaults for the evaluation. However, you can also configure the evaluation metric as per your needs using the `ContextRelevanceConfig` class.
|
||||
|
||||
Here is a more advanced example of how to pass a custom evaluation config for evaluating on context relevance metric:
|
||||
|
||||
```python
|
||||
from embedchain.config.evaluation.base import ContextRelevanceConfig
|
||||
from embedchain.evaluation.metrics import ContextRelevance
|
||||
|
||||
eval_config = ContextRelevanceConfig(model="gpt-4", api_key="sk-xxx", language="en")
|
||||
metric = ContextRelevance(config=eval_config)
|
||||
metric.evaluate(dataset)
|
||||
```
|
||||
|
||||
#### `ContextRelevanceConfig`
|
||||
|
||||
<ParamField path="model" type="str" optional>
|
||||
The model to use for the evaluation. Defaults to `gpt-4`. We only support openai's models for now.
|
||||
</ParamField>
|
||||
<ParamField path="api_key" type="str" optional>
|
||||
The openai api key to use for the evaluation. Defaults to `None`. If not provided, we will use the `OPENAI_API_KEY` environment variable.
|
||||
</ParamField>
|
||||
<ParamField path="language" type="str" optional>
|
||||
The language of the dataset being evaluated. We need this to determine the understand the context provided in the dataset. Defaults to `en`.
|
||||
</ParamField>
|
||||
<ParamField path="prompt" type="str" optional>
|
||||
The prompt to extract the relevant sentences from the context. Defaults to `CONTEXT_RELEVANCY_PROMPT`, which can be found at `embedchain.config.evaluation.base` path.
|
||||
</ParamField>
|
||||
|
||||
|
||||
### Answer Relevancy <a id="answer_relevancy"></a>
|
||||
|
||||
Answer relevancy is a metric to determine how relevant the answer is to the question. We prompt the model with the answer and asking it to generate questions from the answer. We then use the cosine similarity between the generated questions and the original question to determine the score.
|
||||
|
||||
```
|
||||
answer_relevancy_score = mean(cosine_similarity(generated_questions, original_question))
|
||||
```
|
||||
|
||||
#### Examples
|
||||
|
||||
You can run the answer relevancy evaluation with the following simple code:
|
||||
|
||||
```python
|
||||
from embedchain.evaluation.metrics import AnswerRelevance
|
||||
|
||||
metric = AnswerRelevance()
|
||||
score = metric.evaluate(dataset)
|
||||
print(score)
|
||||
# 0.9505334177461916
|
||||
```
|
||||
|
||||
In the above example, we used sensible defaults for the evaluation. However, you can also configure the evaluation metric as per your needs using the `AnswerRelevanceConfig` class. Here is a more advanced example where you can provide your own evaluation config:
|
||||
|
||||
```python
|
||||
from embedchain.config.evaluation.base import AnswerRelevanceConfig
|
||||
from embedchain.evaluation.metrics import AnswerRelevance
|
||||
|
||||
eval_config = AnswerRelevanceConfig(
|
||||
model='gpt-4',
|
||||
embedder="text-embedding-ada-002",
|
||||
api_key="sk-xxx",
|
||||
num_gen_questions=2
|
||||
)
|
||||
metric = AnswerRelevance(config=eval_config)
|
||||
score = metric.evaluate(dataset)
|
||||
```
|
||||
|
||||
#### `AnswerRelevanceConfig`
|
||||
|
||||
<ParamField path="model" type="str" optional>
|
||||
The model to use for the evaluation. Defaults to `gpt-4`. We only support openai's models for now.
|
||||
</ParamField>
|
||||
<ParamField path="embedder" type="str" optional>
|
||||
The embedder to use for embedding the text. Defaults to `text-embedding-ada-002`. We only support openai's embedders for now.
|
||||
</ParamField>
|
||||
<ParamField path="api_key" type="str" optional>
|
||||
The openai api key to use for the evaluation. Defaults to `None`. If not provided, we will use the `OPENAI_API_KEY` environment variable.
|
||||
</ParamField>
|
||||
<ParamField path="num_gen_questions" type="int" optional>
|
||||
The number of questions to generate for each answer. We use the generated questions to compare the similarity with the original question to determine the score. Defaults to `1`.
|
||||
</ParamField>
|
||||
<ParamField path="prompt" type="str" optional>
|
||||
The prompt to extract the `num_gen_questions` number of questions from the provided answer. Defaults to `ANSWER_RELEVANCY_PROMPT`, which can be found at `embedchain.config.evaluation.base` path.
|
||||
</ParamField>
|
||||
|
||||
## Groundedness <a id="groundedness"></a>
|
||||
|
||||
Groundedness is a metric to determine how grounded the answer is to the context. We use OpenAI's `gpt-4` model to determine the groundedness of the answer. We achieve this by prompting the model with the answer and asking it to generate claims from the answer. We then again prompt the model with the context and the generated claims to determine the verdict on the claims. We then use the following formula to determine the score:
|
||||
|
||||
```
|
||||
groundedness_score = (sum of all verdicts) / (total # of claims)
|
||||
```
|
||||
|
||||
You can run the groundedness evaluation with the following simple code:
|
||||
|
||||
```python
|
||||
from embedchain.evaluation.metrics import Groundedness
|
||||
metric = Groundedness()
|
||||
score = metric.evaluate(dataset) # dataset from above
|
||||
print(score)
|
||||
# 1.0
|
||||
```
|
||||
|
||||
In the above example, we used sensible defaults for the evaluation. However, you can also configure the evaluation metric as per your needs using the `GroundednessConfig` class. Here is a more advanced example where you can configure the evaluation config:
|
||||
|
||||
```python
|
||||
from embedchain.config.evaluation.base import GroundednessConfig
|
||||
from embedchain.evaluation.metrics import Groundedness
|
||||
|
||||
eval_config = GroundednessConfig(model='gpt-4', api_key="sk-xxx")
|
||||
metric = Groundedness(config=eval_config)
|
||||
score = metric.evaluate(dataset)
|
||||
```
|
||||
|
||||
|
||||
#### `GroundednessConfig`
|
||||
|
||||
<ParamField path="model" type="str" optional>
|
||||
The model to use for the evaluation. Defaults to `gpt-4`. We only support openai's models for now.
|
||||
</ParamField>
|
||||
<ParamField path="api_key" type="str" optional>
|
||||
The openai api key to use for the evaluation. Defaults to `None`. If not provided, we will use the `OPENAI_API_KEY` environment variable.
|
||||
</ParamField>
|
||||
<ParamField path="answer_claims_prompt" type="str" optional>
|
||||
The prompt to extract the claims from the provided answer. Defaults to `GROUNDEDNESS_ANSWER_CLAIMS_PROMPT`, which can be found at `embedchain.config.evaluation.base` path.
|
||||
</ParamField>
|
||||
<ParamField path="claims_inference_prompt" type="str" optional>
|
||||
The prompt to get verdicts on the claims from the answer from the given context. Defaults to `GROUNDEDNESS_CLAIMS_INFERENCE_PROMPT`, which can be found at `embedchain.config.evaluation.base` path.
|
||||
</ParamField>
|
||||
|
||||
## Custom <a id="custom_metric"></a>
|
||||
|
||||
You can also create your own evaluation metric by extending the `BaseMetric` class. You can find the source code for the existing metrics at `embedchain.evaluation.metrics` path.
|
||||
|
||||
<Note>
|
||||
You must provide the `name` of your custom metric in the `__init__` method of your class. This name will be used to identify your metric in the evaluation report.
|
||||
</Note>
|
||||
|
||||
```python
|
||||
from typing import Optional
|
||||
|
||||
from embedchain.config.base_config import BaseConfig
|
||||
from embedchain.evaluation.metrics import BaseMetric
|
||||
from embedchain.utils.eval import EvalData
|
||||
|
||||
class MyCustomMetric(BaseMetric):
|
||||
def __init__(self, config: Optional[BaseConfig] = None):
|
||||
super().__init__(name="my_custom_metric")
|
||||
|
||||
def evaluate(self, dataset: list[EvalData]):
|
||||
score = 0.0
|
||||
# write your evaluation logic here
|
||||
return score
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
title: 🧩 Introduction
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
You can configure following components
|
||||
|
||||
* [Data Source](/components/data-sources/overview)
|
||||
* [LLM](/components/llms)
|
||||
* [Embedding Model](/components/embedding-models)
|
||||
* [Vector Database](/components/vector-databases)
|
||||
@@ -12,12 +12,16 @@ Embedchain comes with built-in support for various popular large language models
|
||||
<Card title="Azure OpenAI" href="#azure-openai"></Card>
|
||||
<Card title="Anthropic" href="#anthropic"></Card>
|
||||
<Card title="Cohere" href="#cohere"></Card>
|
||||
<Card title="Ollama" href="#Ollama"></Card>
|
||||
<Card title="Together" href="#together"></Card>
|
||||
<Card title="Ollama" href="#ollama"></Card>
|
||||
<Card title="vLLM" href="#vllm"></Card>
|
||||
<Card title="GPT4All" href="#gpt4all"></Card>
|
||||
<Card title="JinaChat" href="#jinachat"></Card>
|
||||
<Card title="Hugging Face" href="#hugging-face"></Card>
|
||||
<Card title="Llama2" href="#llama2"></Card>
|
||||
<Card title="Vertex AI" href="#vertex-ai"></Card>
|
||||
<Card title="Mistral AI" href="#mistral-ai"></Card>
|
||||
<Card title="AWS Bedrock" href="#aws-bedrock"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## OpenAI
|
||||
@@ -28,7 +32,7 @@ Once you have obtained the key, you can use it like this:
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'xxx'
|
||||
|
||||
@@ -43,7 +47,7 @@ If you are looking to configure the different parameters of the LLM, you can do
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'xxx'
|
||||
|
||||
@@ -70,7 +74,7 @@ Examples:
|
||||
<Accordion title="Using Pydantic Models">
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
from embedchain.llm.openai import OpenAILlm
|
||||
import requests
|
||||
from pydantic import BaseModel, Field, ValidationError, field_validator
|
||||
@@ -122,7 +126,7 @@ print(result)
|
||||
<Accordion title="Using OpenAI JSON schema">
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
from embedchain.llm.openai import OpenAILlm
|
||||
import requests
|
||||
from pydantic import BaseModel, Field, ValidationError, field_validator
|
||||
@@ -157,7 +161,7 @@ print(result)
|
||||
<Accordion title="Using actual python functions">
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
from embedchain.llm.openai import OpenAILlm
|
||||
import requests
|
||||
from pydantic import BaseModel, Field, ValidationError, field_validator
|
||||
@@ -191,7 +195,7 @@ To use Google AI model, you have to set the `GOOGLE_API_KEY` environment variabl
|
||||
<CodeGroup>
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["GOOGLE_API_KEY"] = "xxx"
|
||||
|
||||
@@ -234,7 +238,7 @@ To use Azure OpenAI model, you have to set some of the azure openai related envi
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["OPENAI_API_TYPE"] = "azure"
|
||||
os.environ["OPENAI_API_BASE"] = "https://xxx.openai.azure.com/"
|
||||
@@ -248,7 +252,7 @@ app = App.from_config(config_path="config.yaml")
|
||||
llm:
|
||||
provider: azure_openai
|
||||
config:
|
||||
model: gpt-35-turbo
|
||||
model: gpt-3.5-turbo
|
||||
deployment_name: your_llm_deployment_name
|
||||
temperature: 0.5
|
||||
max_tokens: 1000
|
||||
@@ -273,7 +277,7 @@ To use anthropic's model, please set the `ANTHROPIC_API_KEY` which you find on t
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["ANTHROPIC_API_KEY"] = "xxx"
|
||||
|
||||
@@ -310,7 +314,7 @@ Once you have the API key, you are all set to use it with Embedchain.
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["COHERE_API_KEY"] = "xxx"
|
||||
|
||||
@@ -330,6 +334,42 @@ llm:
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Together
|
||||
|
||||
Install related dependencies using the following command:
|
||||
|
||||
```bash
|
||||
pip install --upgrade 'embedchain[together]'
|
||||
```
|
||||
|
||||
Set the `TOGETHER_API_KEY` as environment variable which you can find on their [Account settings page](https://api.together.xyz/settings/api-keys).
|
||||
|
||||
Once you have the API key, you are all set to use it with Embedchain.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import App
|
||||
|
||||
os.environ["TOGETHER_API_KEY"] = "xxx"
|
||||
|
||||
# load llm configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
```
|
||||
|
||||
```yaml config.yaml
|
||||
llm:
|
||||
provider: together
|
||||
config:
|
||||
model: togethercomputer/RedPajama-INCITE-7B-Base
|
||||
temperature: 0.5
|
||||
max_tokens: 1000
|
||||
top_p: 1
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Ollama
|
||||
|
||||
Setup Ollama using https://github.com/jmorganca/ollama
|
||||
@@ -338,7 +378,7 @@ Setup Ollama using https://github.com/jmorganca/ollama
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load llm configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -356,6 +396,35 @@ llm:
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
## vLLM
|
||||
|
||||
Setup vLLM by following instructions given in [their docs](https://docs.vllm.ai/en/latest/getting_started/installation.html).
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import App
|
||||
|
||||
# load llm configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
```
|
||||
|
||||
```yaml config.yaml
|
||||
llm:
|
||||
provider: vllm
|
||||
config:
|
||||
model: 'meta-llama/Llama-2-70b-hf'
|
||||
temperature: 0.5
|
||||
top_p: 1
|
||||
top_k: 10
|
||||
stream: true
|
||||
trust_remote_code: true
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## GPT4ALL
|
||||
|
||||
Install related dependencies using the following command:
|
||||
@@ -369,7 +438,7 @@ GPT4all is a free-to-use, locally running, privacy-aware chatbot. No GPU or inte
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load llm configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -401,7 +470,7 @@ Once you have the key, load the app using the config yaml file:
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["JINACHAT_API_KEY"] = "xxx"
|
||||
# load llm configuration from config.yaml file
|
||||
@@ -437,7 +506,7 @@ Once you have the token, load the app using the config yaml file:
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = "xxx"
|
||||
|
||||
@@ -457,6 +526,49 @@ llm:
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Custom Endpoints
|
||||
|
||||
|
||||
You can also use [Hugging Face Inference Endpoints](https://huggingface.co/docs/inference-endpoints/index#-inference-endpoints) to access custom endpoints. First, set the `HUGGINGFACE_ACCESS_TOKEN` as above.
|
||||
|
||||
Then, load the app using the config yaml file:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import App
|
||||
|
||||
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = "xxx"
|
||||
|
||||
# load llm configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
```
|
||||
|
||||
```yaml config.yaml
|
||||
llm:
|
||||
provider: huggingface
|
||||
config:
|
||||
endpoint: https://api-inference.huggingface.co/models/gpt2 # replace with your personal endpoint
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
If your endpoint requires additional parameters, you can pass them in the `model_kwargs` field:
|
||||
|
||||
```
|
||||
llm:
|
||||
provider: huggingface
|
||||
config:
|
||||
endpoint: <YOUR_ENDPOINT_URL_HERE>
|
||||
model_kwargs:
|
||||
max_new_tokens: 100
|
||||
temperature: 0.5
|
||||
```
|
||||
|
||||
Currently only supports `text-generation` and `text2text-generation` for now [[ref](https://api.python.langchain.com/en/latest/llms/langchain_community.llms.huggingface_endpoint.HuggingFaceEndpoint.html?highlight=huggingfaceendpoint#)].
|
||||
|
||||
See langchain's [hugging face endpoint](https://python.langchain.com/docs/integrations/chat/huggingface#huggingfaceendpoint) for more information.
|
||||
|
||||
## Llama2
|
||||
|
||||
Llama2 is integrated through [Replicate](https://replicate.com/). Set `REPLICATE_API_TOKEN` in environment variable which you can obtain from [their platform](https://replicate.com/account/api-tokens).
|
||||
@@ -467,7 +579,7 @@ Once you have the token, load the app using the config yaml file:
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["REPLICATE_API_TOKEN"] = "xxx"
|
||||
|
||||
@@ -494,7 +606,7 @@ Setup Google Cloud Platform application credentials by following the instruction
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load llm configuration from config.yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -510,5 +622,86 @@ llm:
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
## Mistral AI
|
||||
|
||||
Obtain the Mistral AI api key from their [console](https://console.mistral.ai/).
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
os.environ["MISTRAL_API_KEY"] = "xxx"
|
||||
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
response = app.query("what is the net worth of Elon Musk?")
|
||||
# As of January 16, 2024, Elon Musk's net worth is $225.4 billion.
|
||||
|
||||
response = app.chat("which companies does elon own?")
|
||||
# Elon Musk owns Tesla, SpaceX, Boring Company, Twitter, and X.
|
||||
|
||||
response = app.chat("what question did I ask you already?")
|
||||
# You have asked me several times already which companies Elon Musk owns, specifically Tesla, SpaceX, Boring Company, Twitter, and X.
|
||||
```
|
||||
|
||||
```yaml config.yaml
|
||||
llm:
|
||||
provider: mistralai
|
||||
config:
|
||||
model: mistral-tiny
|
||||
temperature: 0.5
|
||||
max_tokens: 1000
|
||||
top_p: 1
|
||||
embedder:
|
||||
provider: mistralai
|
||||
config:
|
||||
model: mistral-embed
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
## AWS Bedrock
|
||||
|
||||
### Setup
|
||||
- Before using the AWS Bedrock LLM, make sure you have the appropriate model access from [Bedrock Console](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess).
|
||||
- You will also need to authenticate the `boto3` client by using a method in the [AWS documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials)
|
||||
- You can optionally export an `AWS_REGION`
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import App
|
||||
|
||||
os.environ["AWS_ACCESS_KEY_ID"] = "xxx"
|
||||
os.environ["AWS_SECRET_ACCESS_KEY"] = "xxx"
|
||||
os.environ["AWS_REGION"] = "us-west-2"
|
||||
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
```
|
||||
|
||||
```yaml config.yaml
|
||||
llm:
|
||||
provider: aws_bedrock
|
||||
config:
|
||||
model: amazon.titan-text-express-v1
|
||||
# check notes below for model_kwargs
|
||||
model_kwargs:
|
||||
temperature: 0.5
|
||||
topP: 1
|
||||
maxTokenCount: 1000
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<br />
|
||||
<Note>
|
||||
The model arguments are different for each providers. Please refer to the [AWS Bedrock Documentation](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/providers) to find the appropriate arguments for your model.
|
||||
</Note>
|
||||
|
||||
<br/ >
|
||||
<Snippet file="missing-llm-tip.mdx" />
|
||||
|
||||
@@ -22,7 +22,7 @@ Utilizing a vector database alongside Embedchain is a seamless process. All you
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load chroma configuration from yaml file
|
||||
app = App.from_config(config_path="config1.yaml")
|
||||
@@ -67,7 +67,7 @@ You can authorize the connection to Elasticsearch by providing either `basic_aut
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load elasticsearch configuration from yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -97,7 +97,7 @@ pip install --upgrade 'embedchain[opensearch]'
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load opensearch configuration from yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -133,7 +133,7 @@ Set the Zilliz environment variables `ZILLIZ_CLOUD_URI` and `ZILLIZ_CLOUD_TOKEN`
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['ZILLIZ_CLOUD_URI'] = 'https://xxx.zillizcloud.com'
|
||||
os.environ['ZILLIZ_CLOUD_TOKEN'] = 'xxx'
|
||||
@@ -167,35 +167,61 @@ Install pinecone related dependencies using the following command:
|
||||
pip install --upgrade 'embedchain[pinecone]'
|
||||
```
|
||||
|
||||
In order to use Pinecone as vector database, set the environment variables `PINECONE_API_KEY` and `PINECONE_ENV` which you can find on [Pinecone dashboard](https://app.pinecone.io/).
|
||||
In order to use Pinecone as vector database, set the environment variable `PINECONE_API_KEY` which you can find on [Pinecone dashboard](https://app.pinecone.io/).
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load pinecone configuration from yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
app = App.from_config(config_path="pod_config.yaml")
|
||||
# or
|
||||
app = App.from_config(config_path="serverless_config.yaml")
|
||||
```
|
||||
|
||||
```yaml config.yaml
|
||||
```yaml pod_config.yaml
|
||||
vectordb:
|
||||
provider: pinecone
|
||||
config:
|
||||
metric: cosine
|
||||
vector_dimension: 1536
|
||||
collection_name: my-pinecone-index
|
||||
index_name: my-pinecone-index
|
||||
pod_config:
|
||||
environment: gcp-starter
|
||||
metadata_config:
|
||||
indexed:
|
||||
- "url"
|
||||
- "hash"
|
||||
```
|
||||
|
||||
```yaml serverless_config.yaml
|
||||
vectordb:
|
||||
provider: pinecone
|
||||
config:
|
||||
metric: cosine
|
||||
vector_dimension: 1536
|
||||
index_name: my-pinecone-index
|
||||
serverless_config:
|
||||
cloud: aws
|
||||
region: us-west-2
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
<br />
|
||||
<Note>
|
||||
You can find more information about Pinecone configuration [here](https://docs.pinecone.io/docs/manage-indexes#create-a-pod-based-index).
|
||||
You can also optionally provide `index_name` as a config param in yaml file to specify the index name. If not provided, the index name will be `{collection_name}-{vector_dimension}`.
|
||||
</Note>
|
||||
|
||||
## Qdrant
|
||||
|
||||
In order to use Qdrant as a vector database, set the environment variables `QDRANT_URL` and `QDRANT_API_KEY` which you can find on [Qdrant Dashboard](https://cloud.qdrant.io/).
|
||||
|
||||
<CodeGroup>
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load qdrant configuration from yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
@@ -215,7 +241,7 @@ In order to use Weaviate as a vector database, set the environment variables `WE
|
||||
|
||||
<CodeGroup>
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load weaviate configuration from yaml file
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
|
||||
@@ -27,7 +27,7 @@ make lint format
|
||||
### Authors
|
||||
|
||||
- Taranjeet Singh ([@taranjeetio](https://twitter.com/taranjeetio))
|
||||
- Deshraj Yadav ([@deshrajdry](https://twitter.com/taranjeetio))
|
||||
- Deshraj Yadav ([@deshrajdry](https://twitter.com/deshrajdry))
|
||||
|
||||
### Citation
|
||||
|
||||
@@ -36,7 +36,7 @@ If you utilize this repository, please consider citing it with:
|
||||
```
|
||||
@misc{embedchain,
|
||||
author = {Taranjeet Singh, Deshraj Yadav},
|
||||
title = {Embechain: Data platform for LLMs - Load, index, retrieve and sync any unstructured data},
|
||||
title = {Embechain: The Open Source RAG Framework},
|
||||
year = {2023},
|
||||
publisher = {GitHub},
|
||||
journal = {GitHub repository},
|
||||
|
||||
@@ -7,29 +7,8 @@ description: 'Deploy your RAG application to embedchain.ai platform'
|
||||
|
||||
Embedchain enables developers to deploy their LLM-powered apps in production using the [Embedchain platform](https://app.embedchain.ai). The platform offers free access to context on your data through its REST API. Once the pipeline is deployed, you can update your data sources anytime after deployment.
|
||||
|
||||
See the example below on how to use the deploy your app (for free):
|
||||
Deployment to Embedchain Platform is currently available on an invitation-only basis. To request access, please submit your information via the provided [Google Form](https://forms.gle/vigN11h7b4Ywat668). We will review your request and respond promptly.
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
|
||||
# Initialize app
|
||||
app = App()
|
||||
|
||||
# Add data source
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
|
||||
# Deploy your pipeline to Embedchain Platform
|
||||
app.deploy()
|
||||
|
||||
# 🔑 Enter your Embedchain API key. You can find the API key at https://app.embedchain.ai/settings/keys/
|
||||
# ec-xxxxxx
|
||||
|
||||
# 🛠️ Creating pipeline on the platform...
|
||||
# 🎉🎉🎉 Pipeline created successfully! View your pipeline: https://app.embedchain.ai/pipelines/xxxxx
|
||||
|
||||
# 🛠️ Adding data to your pipeline...
|
||||
# ✅ Data of type: web_page, value: https://www.forbes.com/profile/elon-musk added successfully.
|
||||
```
|
||||
|
||||
## Seeking help?
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
Fork the Embedchain repo on [Github](https://github.com/embedchain/embedchain) to create your own NextJS discord and slack bot powered by Embedchain.
|
||||
|
||||
If you run into problems with forking, please refer to [github docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) for forking a repo.
|
||||
|
||||
We will work from the `examples/nextjs` folder so change your current working directory by running the command - `cd <your_forked_repo>/examples/nextjs`
|
||||
|
||||
# Installation
|
||||
|
||||
First, lets start by install all the required packages and dependencies.
|
||||
|
||||
- Install all the required python packages by running ```pip install -r requirements.txt```
|
||||
|
||||
- We will use [Fly.io](https://fly.io/) to deploy our embedchain app, discord and slack bot. Follow the step one to install [Fly.io CLI](https://docs.embedchain.ai/deployment/fly_io#step-1-install-flyctl-command-line)
|
||||
|
||||
# Developement
|
||||
|
||||
## Embedchain App
|
||||
|
||||
First, we need an Embedchain app powered with the knowledge of NextJS. We have already created an embedchain app using FastAPI in `ec_app` folder for you. Feel free to ingest data of your choice to power the App.
|
||||
|
||||
<Note>
|
||||
Navigate to `ec_app` folder and create `.env` file in this folder and set your OpenAI API key as shown in `.env.example` file. If you want to use other open-source models, feel free to use the app config in `app.py`. More details for using custom configuration for Embedchain app is [available here](https://docs.embedchain.ai/api-reference/advanced/configuration).
|
||||
</Note>
|
||||
|
||||
Before running the ec commands to develope the app, open `fly.toml` file and update the `name` variable to something unique. This is important as `fly.io` requires users to provide a globally unique deployment app names.
|
||||
|
||||
Now, we need to launch this application with fly.io. You can see your app on [fly.io dashboard](https://fly.io/dashboard). Run the following command to launch your app on fly.io:
|
||||
```bash
|
||||
fly launch --no-deploy
|
||||
```
|
||||
|
||||
To run the app in development, run the following command:
|
||||
|
||||
```bash
|
||||
ec dev
|
||||
```
|
||||
|
||||
Run `ec deploy` to deploy your app on Fly.io. Once you deploy your app, save the endpoint on which our discord and slack bot will send requests.
|
||||
|
||||
|
||||
## Discord bot
|
||||
|
||||
For discord bot, you will need to create the bot on discord developer portal and get the discord bot token and your discord bot name.
|
||||
|
||||
While keeping in mind the following note, create the discord bot by following the instructions from our [discord bot docs](https://docs.embedchain.ai/examples/discord_bot) and get discord bot token.
|
||||
|
||||
<Note>
|
||||
You do not need to set `OPENAI_API_KEY` to run this discord bot. Follow the remaining instructions to create a discord bot app. We recommend you to give the following sets of bot permissions to run the discord bot without errors:
|
||||
|
||||
```
|
||||
(General Permissions)
|
||||
Read Message/View Channels
|
||||
|
||||
(Text Permissions)
|
||||
Send Messages
|
||||
Create Public Thread
|
||||
Create Private Thread
|
||||
Send Messages in Thread
|
||||
Manage Threads
|
||||
Embed Links
|
||||
Read Message History
|
||||
```
|
||||
</Note>
|
||||
|
||||
Once you have your discord bot token and discord app name. Navigate to `nextjs_discord` folder and create `.env` file and define your discord bot token, discord bot name and endpoint of your embedchain app as shown in `.env.example` file.
|
||||
|
||||
To run the app in development:
|
||||
|
||||
```bash
|
||||
python app.py
|
||||
```
|
||||
|
||||
Before deploying the app, open `fly.toml` file and update the `name` variable to something unique. This is important as `fly.io` requires users to provide a globally unique deployment app names.
|
||||
|
||||
Now, we need to launch this application with fly.io. You can see your app on [fly.io dashboard](https://fly.io/dashboard). Run the following command to launch your app on fly.io:
|
||||
```bash
|
||||
fly launch --no-deploy
|
||||
```
|
||||
|
||||
Run `ec deploy` to deploy your app on Fly.io. Once you deploy your app, your discord bot will be live!
|
||||
|
||||
|
||||
## Slack bot
|
||||
|
||||
For Slack bot, you will need to create the bot on slack developer portal and get the slack bot token and slack app token.
|
||||
|
||||
### Setup
|
||||
|
||||
- Create a workspace on Slack if you don't have one already by clicking [here](https://slack.com/intl/en-in/).
|
||||
- Create a new App on your Slack account by going [here](https://api.slack.com/apps).
|
||||
- Select `From Scratch`, then enter the Bot Name and select your workspace.
|
||||
- Go to `App Credentials` section on the `Basic Information` tab from the left sidebar, create your app token and save it in your `.env` file as `SLACK_APP_TOKEN`.
|
||||
- Go to `Socket Mode` tab from the left sidebar and enable the socket mode to listen to slack message from your workspace.
|
||||
- (Optional) Under the `App Home` tab you can change your App display name and default name.
|
||||
- Navigate to `Event Subscription` tab, and enable the event subscription so that we can listen to slack events.
|
||||
- Once you enable the event subscription, you will need to subscribe to bot events to authorize the bot to listen to app mention events of the bot. Do that by tapping on `Add Bot User Event` button and select `app_mention`.
|
||||
- On the left Sidebar, go to `OAuth and Permissions` and add the following scopes under `Bot Token Scopes`:
|
||||
```text
|
||||
app_mentions:read
|
||||
channels:history
|
||||
channels:read
|
||||
chat:write
|
||||
emoji:read
|
||||
reactions:write
|
||||
reactions:read
|
||||
```
|
||||
- Now select the option `Install to Workspace` and after it's done, copy the `Bot User OAuth Token` and set it in your `.env` file as `SLACK_BOT_TOKEN`.
|
||||
|
||||
Once you have your slack bot token and slack app token. Navigate to `nextjs_slack` folder and create `.env` file and define your slack bot token, slack app token and endpoint of your embedchain app as shown in `.env.example` file.
|
||||
|
||||
To run the app in development:
|
||||
|
||||
```bash
|
||||
python app.py
|
||||
```
|
||||
|
||||
Before deploying the app, open `fly.toml` file and update the `name` variable to something unique. This is important as `fly.io` requires users to provide a globally unique deployment app names.
|
||||
|
||||
Now, we need to launch this application with fly.io. You can see your app on [fly.io dashboard](https://fly.io/dashboard). Run the following command to launch your app on fly.io:
|
||||
```bash
|
||||
fly launch --no-deploy
|
||||
```
|
||||
|
||||
Run `ec deploy` to deploy your app on Fly.io. Once you deploy your app, your slack bot will be live!
|
||||
@@ -44,6 +44,10 @@ Get started with Embedchain by trying out the examples below. You can run the ex
|
||||
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/cohere.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" noZoom alt="Open In Colab"/></a></td>
|
||||
<td className="align-middle"><a target="_blank" href="https://replit.com/@taranjeetio/cohere#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&variant=small" noZoom alt="Try with Replit Badge"/></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="align-middle">Together</td>
|
||||
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/together.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" noZoom alt="Open In Colab"/></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="align-middle">Ollama</td>
|
||||
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/ollama.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" noZoom alt="Open In Colab"/></a></td>
|
||||
|
||||
@@ -37,7 +37,7 @@ llm:
|
||||
max_tokens: 1000
|
||||
top_p: 1
|
||||
stream: false
|
||||
template: |
|
||||
prompt: |
|
||||
Use the following pieces of context to answer the query at the end.
|
||||
If you don't know the answer, just say that you don't know, don't try to make up an answer.
|
||||
|
||||
@@ -81,6 +81,7 @@ curl --request POST \
|
||||
| `OPENAI_API_BASE` | Azure OpenAI |
|
||||
| `OPENAI_API_VERSION` | Azure OpenAI |
|
||||
| `COHERE_API_KEY` | Cohere |
|
||||
| `TOGETHER_API_KEY` | Together |
|
||||
| `ANTHROPIC_API_KEY` | Anthropic |
|
||||
| `JINACHAT_API_KEY` | Jina |
|
||||
| `HUGGINGFACE_ACCESS_TOKEN` | Huggingface |
|
||||
|
||||
@@ -20,7 +20,7 @@ Embedchain community has been super active in creating demos on top of Embedchai
|
||||
- [Create Instant ChatBot 🤖 using embedchain](https://databutton.com/v/h3e680h9) by Avra, ([Tweet](https://twitter.com/Avra_b/status/1674704745154641920/))
|
||||
- [JOBO 🤖 — The AI-driven sidekick to craft your resume](https://try-jobo.com/) by Enrico Willemse, ([LinkedIn Post](https://www.linkedin.com/posts/enrico-willemse_jobai-gptfun-embedchain-activity-7090340080879374336-ueLB/))
|
||||
- [Explore Your Knowledge Base: Interactive chats over various forms of documents](https://chatdocs.dkedar.com/) by Kedar Dabhadkar, ([LinkedIn Post](https://www.linkedin.com/posts/dkedar7_machinelearning-llmops-activity-7092524836639424513-2O3L/))
|
||||
- [Chatbot trained on 1000+ videos of Ester hicks the co-author behind the famous book Secret](https://ask-abraham.thoughtseed.repl.co) by Mohan Kumar
|
||||
- [Chatbot trained on 1000+ videos of Ester hicks the co-author behind the famous book Secret](https://askabraham.tokenofme.io/) by Mohan Kumar
|
||||
|
||||
|
||||
## Templates
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
[Embedchain Examples Repo](https://github.com/embedchain/examples) contains code on how to build your own Slack AI to chat with the unstructured data lying in your slack channels.
|
||||
|
||||

|
||||
|
||||
## Getting started
|
||||
|
||||
Create a Slack AI involves 3 steps
|
||||
|
||||
* Create slack user
|
||||
* Set environment variables
|
||||
* Run the app locally
|
||||
|
||||
### Step 1: Create Slack user token
|
||||
|
||||
Follow the steps given below to fetch your slack user token to get data through Slack APIs:
|
||||
|
||||
1. Create a workspace on Slack if you don’t have one already by clicking [here](https://slack.com/intl/en-in/).
|
||||
2. Create a new App on your Slack account by going [here](https://api.slack.com/apps).
|
||||
3. Select `From Scratch`, then enter the App Name and select your workspace.
|
||||
4. Navigate to `OAuth & Permissions` tab from the left sidebar and go to the `scopes` section. Add the following scopes under `User Token Scopes`:
|
||||
|
||||
```
|
||||
# Following scopes are needed for reading channel history
|
||||
channels:history
|
||||
channels:read
|
||||
|
||||
# Following scopes are needed to fetch list of channels from slack
|
||||
groups:read
|
||||
mpim:read
|
||||
im:read
|
||||
```
|
||||
|
||||
5. Click on the `Install to Workspace` button under `OAuth Tokens for Your Workspace` section in the same page and install the app in your slack workspace.
|
||||
6. After installing the app you will see the `User OAuth Token`, save that token as you will need to configure it as `SLACK_USER_TOKEN` for this demo.
|
||||
|
||||
### Step 2: Set environment variables
|
||||
|
||||
Navigate to `api` folder and set your `HUGGINGFACE_ACCESS_TOKEN` and `SLACK_USER_TOKEN` in `.env.example` file. Then rename the `.env.example` file to `.env`.
|
||||
|
||||
|
||||
<Note>
|
||||
By default, we use `Mixtral` model from Hugging Face. However, if you prefer to use OpenAI model, then set `OPENAI_API_KEY` instead of `HUGGINGFACE_ACCESS_TOKEN` along with `SLACK_USER_TOKEN` in `.env` file, and update the code in `api/utils/app.py` file to use OpenAI model instead of Hugging Face model.
|
||||
</Note>
|
||||
|
||||
### Step 3: Run app locally
|
||||
|
||||
Follow the instructions given below to run app locally based on your development setup (with docker or without docker):
|
||||
|
||||
#### With docker
|
||||
|
||||
```bash
|
||||
docker-compose build
|
||||
ec start --docker
|
||||
```
|
||||
|
||||
#### Without docker
|
||||
|
||||
```bash
|
||||
ec install-reqs
|
||||
ec start
|
||||
```
|
||||
|
||||
Finally, you will have the Slack AI frontend running on http://localhost:3000. You can also access the REST APIs on http://localhost:8000.
|
||||
|
||||
## Credits
|
||||
|
||||
This demo was built using the Embedchain's [full stack demo template](https://docs.embedchain.ai/get-started/full-stack). Follow the instructions [given here](https://docs.embedchain.ai/get-started/full-stack) to create your own full stack RAG application.
|
||||
@@ -10,23 +10,11 @@ After successfully setting up and testing your RAG app locally, the next step is
|
||||
<Card title="Modal.com" href="/deployment/modal_com"></Card>
|
||||
<Card title="Render.com" href="/deployment/render_com"></Card>
|
||||
<Card title="Streamlit.io" href="/deployment/streamlit_io"></Card>
|
||||
<Card title="Gradio.app" href="/deployment/gradio_app"></Card>
|
||||
<Card title="Huggingface.co" href="/deployment/huggingface_spaces"></Card>
|
||||
<Card title="Embedchain.ai" href="/deployment/embedchain_ai"></Card>
|
||||
<Card title="Self-hosting" href="#option-2-self-hosting"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Self-hosting
|
||||
|
||||
You can also deploy Embedchain as a self-hosted service using the dockerized REST API service that we provide. Please follow the [guide here](/examples/rest-api) on how to use the REST API service. Here are some tutorials on how to deploy a containerized application to different platforms like AWS, GCP, Azure etc:
|
||||
|
||||
- [Fly.io](/deployment/fly_io)
|
||||
- [Render.com](https://render.com/docs/deploy-an-image)
|
||||
- [Huggingface Spaces](https://huggingface.co/new-space)
|
||||
- [AWS EKS](https://docs.aws.amazon.com/eks/latest/userguide/sample-deployment.html)
|
||||
- [AWS ECS](https://docs.aws.amazon.com/codecatalyst/latest/userguide/deploy-tut-ecs.html)
|
||||
- [Google GKE](https://cloud.google.com/kubernetes-engine/docs/tutorials/hello-app)
|
||||
- [Azure App Service](https://learn.microsoft.com/en-us/training/modules/deploy-run-container-app-service/)
|
||||
|
||||
|
||||
## Seeking help?
|
||||
|
||||
If you run into issues with deployment, please feel free to reach out to us via any of the following methods:
|
||||
|
||||
@@ -11,7 +11,7 @@ Use the model provided on huggingface: `mistralai/Mistral-7B-v0.1`
|
||||
<CodeGroup>
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = "hf_your_token"
|
||||
|
||||
@@ -40,7 +40,7 @@ Use the model `gpt-4-turbo` provided my openai.
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'xxx'
|
||||
|
||||
@@ -65,7 +65,7 @@ llm:
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'xxx'
|
||||
|
||||
@@ -90,7 +90,7 @@ llm:
|
||||
<CodeGroup>
|
||||
|
||||
```python main.py
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
# load llm configuration from opensource.yaml file
|
||||
app = App.from_config(config_path="opensource.yaml")
|
||||
@@ -131,7 +131,7 @@ llm:
|
||||
|
||||
```python main.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
@@ -149,7 +149,7 @@ response = app.query("What is the net worth of Elon Musk?")
|
||||
Set up the app by adding an `id` in the config file. This keeps the data for future use. You can include this `id` in the yaml config or input it directly in `config` dict.
|
||||
```python app1.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
@@ -167,7 +167,7 @@ response = app.query("What is the net worth of Elon Musk?")
|
||||
```
|
||||
```python app2.py
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: '💻 Full stack'
|
||||
---
|
||||
|
||||
Get started with full-stack RAG applications using Embedchain's easy-to-use CLI tool. Set up everything with just a few commands, whether you prefer Docker or not.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Choose your setup method:
|
||||
|
||||
* [Without docker](#without-docker)
|
||||
* [With Docker](#with-docker)
|
||||
|
||||
### Without Docker
|
||||
|
||||
Ensure these are installed:
|
||||
|
||||
- Embedchain python package (`pip install embedchain`)
|
||||
- [Node.js](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/)
|
||||
|
||||
### With Docker
|
||||
|
||||
Install Docker from [Docker's official website](https://docs.docker.com/engine/install/).
|
||||
|
||||
## Quick Start Guide
|
||||
|
||||
### Install the package
|
||||
|
||||
Before proceeding, make sure you have the Embedchain package installed.
|
||||
|
||||
```bash
|
||||
pip install embedchain -U
|
||||
```
|
||||
|
||||
### Setting Up
|
||||
|
||||
For the purpose of the demo, you have to set `OPENAI_API_KEY` to start with but you can choose any llm by changing the configuration easily.
|
||||
|
||||
### Installation Commands
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```bash without docker
|
||||
ec create-app my-app
|
||||
cd my-app
|
||||
ec start
|
||||
```
|
||||
|
||||
```bash with docker
|
||||
ec create-app my-app --docker
|
||||
cd my-app
|
||||
ec start --docker
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### What Happens Next?
|
||||
|
||||
1. Embedchain fetches a full stack template (FastAPI backend, Next.JS frontend).
|
||||
2. Installs required components.
|
||||
3. Launches both frontend and backend servers.
|
||||
|
||||
### See It In Action
|
||||
|
||||
Open http://localhost:3000 to view the chat UI.
|
||||
|
||||

|
||||
|
||||
### Admin Panel
|
||||
|
||||
Check out the Embedchain admin panel to see the document chunks for your RAG application.
|
||||
|
||||

|
||||
|
||||
### API Server
|
||||
|
||||
If you want to access the API server, you can do so at http://localhost:8000/docs.
|
||||
|
||||

|
||||
|
||||
You can customize the UI and code as per your requirements.
|
||||
@@ -1,68 +1,83 @@
|
||||
---
|
||||
title: '⚡ Quickstart'
|
||||
description: '💡 Start building ChatGPT like apps in a minute on your own data'
|
||||
description: '💡 Create a RAG app on your own data in a minute'
|
||||
---
|
||||
|
||||
Install python package:
|
||||
## Installation
|
||||
|
||||
First install the Python package:
|
||||
|
||||
```bash
|
||||
pip install embedchain
|
||||
```
|
||||
|
||||
Creating an app involves 3 steps:
|
||||
Once you have installed the package, depending upon your preference you can either use:
|
||||
|
||||
<Steps>
|
||||
<Step title="⚙️ Import app instance">
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
app = App()
|
||||
```
|
||||
<Accordion title="Customize your app by a simple YAML config" icon="gear-complex">
|
||||
Embedchain provides a wide range of options to customize your app. You can customize the model, data sources, and much more.
|
||||
Explore the custom configurations [here](https://docs.embedchain.ai/advanced/configuration).
|
||||
<CodeGroup>
|
||||
```python yaml_app.py
|
||||
from embedchain import Pipeline as App
|
||||
app = App.from_config(config_path="config.yaml")
|
||||
```
|
||||
```python json_app.py
|
||||
from embedchain import Pipeline as App
|
||||
app = App.from_config(config_path="config.json")
|
||||
```
|
||||
```python app.py
|
||||
from embedchain import Pipeline as App
|
||||
config = {} # Add your config here
|
||||
app = App.from_config(config=config)
|
||||
```
|
||||
</CodeGroup>
|
||||
</Accordion>
|
||||
</Step>
|
||||
<Step title="🗃️ Add data sources">
|
||||
```python
|
||||
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
# app.add("path/to/file/elon_musk.pdf")
|
||||
```
|
||||
<Accordion title="Embedchain supports adding data from many data sources." icon="files">
|
||||
Embedchain supports adding data from many data sources including web pages, PDFs, databases, and more.
|
||||
Explore the list of supported [data sources](https://docs.embedchain.ai/data-sources/overview).
|
||||
</Accordion>
|
||||
</Step>
|
||||
<Step title="💬 Ask questions, chat, or search through your data with ease">
|
||||
```python
|
||||
app.query("What is the net worth of Elon Musk today?")
|
||||
# Answer: The net worth of Elon Musk today is $258.7 billion.
|
||||
```
|
||||
<hr />
|
||||
<Accordion title="Want to chat with your app?" icon="face-thinking">
|
||||
Embedchain provides a wide range of features to interact with your app. You can chat with your app, ask questions, search through your data, and much more.
|
||||
```python
|
||||
app.chat("How many companies does Elon Musk run? Name those")
|
||||
# Answer: Elon Musk runs 3 companies: Tesla, SpaceX, and Neuralink.
|
||||
app.chat("What is his net worth today?")
|
||||
# Answer: The net worth of Elon Musk today is $258.7 billion.
|
||||
```
|
||||
To learn about other features, click [here](https://docs.embedchain.ai/get-started/introduction)
|
||||
</Accordion>
|
||||
</Step>
|
||||
</Steps>
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Open Source Models" icon="osi" href="#open-source-models">
|
||||
This includes Open source LLMs like Mistral, Llama, etc.<br/>
|
||||
Free to use, and runs locally on your machine.
|
||||
</Card>
|
||||
<Card title="Paid Models" icon="dollar-sign" href="#paid-models" color="#4A154B">
|
||||
This includes paid LLMs like GPT 4, Claude, etc.<br/>
|
||||
Cost money and are accessible via an API.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Open Source Models
|
||||
|
||||
This section gives a quickstart example of using Mistral as the Open source LLM and Sentence transformers as the Open source embedding model. These models are free and run mostly on your local machine.
|
||||
|
||||
We are using Mistral hosted at Hugging Face, so will you need a Hugging Face token to run this example. Its *free* and you can create one [here](https://huggingface.co/docs/hub/security-tokens).
|
||||
|
||||
<CodeGroup>
|
||||
```python quickstart.py
|
||||
import os
|
||||
# replace this with your HF key
|
||||
os.environ["HUGGINGFACE_ACCESS_TOKEN"] = "hf_xxxx"
|
||||
|
||||
from embedchain import App
|
||||
app = App.from_config("mistral.yaml")
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
|
||||
app.query("What is the net worth of Elon Musk today?")
|
||||
# Answer: The net worth of Elon Musk today is $258.7 billion.
|
||||
```
|
||||
```yaml mistral.yaml
|
||||
llm:
|
||||
provider: huggingface
|
||||
config:
|
||||
model: 'mistralai/Mistral-7B-Instruct-v0.2'
|
||||
top_p: 0.5
|
||||
embedder:
|
||||
provider: huggingface
|
||||
config:
|
||||
model: 'sentence-transformers/all-mpnet-base-v2'
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Paid Models
|
||||
|
||||
In this section, we will use both LLM and embedding model from OpenAI.
|
||||
|
||||
```python quickstart.py
|
||||
import os
|
||||
# replace this with your OpenAI key
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xxxx"
|
||||
|
||||
from embedchain import App
|
||||
app = App()
|
||||
app.add("https://www.forbes.com/profile/elon-musk")
|
||||
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
|
||||
app.query("What is the net worth of Elon Musk today?")
|
||||
# Answer: The net worth of Elon Musk today is $258.7 billion.
|
||||
```
|
||||
|
||||
# Next Steps
|
||||
|
||||
Now that you have created your first app, you can follow any of the links:
|
||||
|
||||
* [Introduction](/get-started/introduction)
|
||||
* [Customization](/components/introduction)
|
||||
* [Use cases](/use-cases/introduction)
|
||||
* [Deployment](/get-started/deployment)
|
||||
|
||||
|
After Width: | Height: | Size: 262 KiB |
|
After Width: | Height: | Size: 758 KiB |
|
After Width: | Height: | Size: 605 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
@@ -21,7 +21,7 @@ Create a new file called `app.py` and add the following code:
|
||||
|
||||
```python
|
||||
import chainlit as cl
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
import os
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ os.environ['LANGCHAIN_PROJECT] = <your-project>
|
||||
|
||||
|
||||
```python
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
|
||||
|
||||
@@ -17,7 +17,7 @@ pip install embedchain streamlit
|
||||
<Tab title="app.py">
|
||||
```python
|
||||
import os
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
import streamlit as st
|
||||
|
||||
with st.sidebar:
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<svg width="1371" height="249" viewBox="0 0 1371 249" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M66.248 1V248.8H158.996V210.214H120.41V148.264H158.996V101.89H120.41V39.94H158.996V1H66.248ZM169.655 1V248.8H223.817V124.9L246.827 248.8H262.403L285.767 124.9V248.8H339.929V1H277.979L254.615 148.264L231.251 1H169.655ZM404.661 210.214V148.264H412.449C416.697 148.264 419.883 151.804 419.883 156.052V202.426C419.883 206.674 416.697 210.214 412.449 210.214H404.661ZM443.955 125.254L443.247 124.9C460.239 124.9 474.399 111.094 474.399 94.102V32.152C474.399 15.16 460.239 1 443.247 1H350.499V248.8H443.247C460.239 248.8 474.399 234.994 474.399 218.002V156.052C474.399 139.06 460.947 125.608 443.955 125.254ZM412.449 101.89H404.661V39.94H412.449C416.697 39.94 419.883 43.48 419.883 47.728V94.102C419.883 98.35 416.697 101.89 412.449 101.89ZM577.421 1H484.673V248.8H577.421V210.214H538.835V148.264H577.421V101.89H538.835V39.94H577.421V1ZM642.242 210.214V39.94H649.676C654.278 39.94 657.464 43.48 657.464 47.728V202.426C657.464 206.674 654.278 210.214 649.676 210.214H642.242ZM711.98 218.002V32.152C711.98 15.16 697.82 1 680.828 1H588.08V248.8H680.828C697.82 248.8 711.98 234.994 711.98 218.002ZM88 164.8H70V182.8H88V164.8Z" fill="white"/>
|
||||
<rect x="17" y="164.8" width="18" height="18" fill="white"/>
|
||||
<rect y="141.8" width="11" height="18" fill="white"/>
|
||||
<rect x="26" y="64.7998" width="30" height="30" fill="white"/>
|
||||
<rect x="1334.52" y="90.3779" width="26.6955" height="26.6955" fill="white"/>
|
||||
<rect x="1360.32" y="133.091" width="10.6782" height="16.0173" fill="white"/>
|
||||
<rect x="1334.52" y="148.219" width="16.0173" height="16.0173" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M723 217.646V31.2444C723 14.202 736.847 0 753.889 0H816.023C833.066 0 847.268 14.202 847.268 31.2444V85.5672H792.59V46.8667C792.59 42.6061 789.394 39.0556 784.779 39.0556C780.518 39.0556 777.323 42.6061 777.323 46.8667V202.024C777.323 206.284 780.518 209.835 784.779 209.835C789.394 209.835 792.59 206.284 792.59 202.024V163.323H847.268V217.646C847.268 234.688 833.066 248.535 816.023 248.535H753.889C736.847 248.535 723 234.688 723 217.646ZM856.144 248.535V0H910.467V101.189H925.734V0H980.057V248.535H925.734V147.701H910.467V248.535H856.144ZM1066.34 248.535L1062.79 209.835H1039.36L1035.45 248.535H988.941L1019.83 0H1081.96L1113.21 248.535H1066.34ZM1043.62 163.323H1058.18L1050.72 85.5672L1043.62 163.323ZM1176.06 248.535H1121.74V0H1176.06V248.535ZM1184.84 248.535V0H1239.17L1262.24 124.268V0H1308.76V75.2506H1302.48V101.946H1308.76V153.557H1294.47V169.575H1308.76V248.535H1254.43L1231.35 124.268V248.535H1184.84Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,24 +1,11 @@
|
||||
<svg width="1161" height="212" viewBox="0 0 1161 212" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1010.3 212V0H1056.64L1076.33 106V0H1116V212H1069.66L1049.98 106V212H1010.3Z" fill="white"/>
|
||||
<path d="M1001.3 212H954.958V0H1001.3V212Z" fill="white"/>
|
||||
<path d="M906.196 212L903.167 178.989H883.179L879.847 212H840.173L866.522 0H919.522L946.173 212H906.196ZM886.813 139.314H899.23L892.87 72.9886L886.813 139.314Z" fill="white"/>
|
||||
<path d="M725.385 212V0H771.722V86.3143H784.745V0H831.082V212H784.745V125.989H771.722V212H725.385Z" fill="white"/>
|
||||
<path d="M610.298 185.651V26.6514C610.298 12.1143 622.109 0 636.646 0H689.646C704.183 0 716.298 12.1143 716.298 26.6514V72.9886H669.658V39.9771C669.658 36.3429 666.932 33.3143 662.995 33.3143C659.36 33.3143 656.635 36.3429 656.635 39.9771V172.326C656.635 175.96 659.36 178.989 662.995 178.989C666.932 178.989 669.658 175.96 669.658 172.326V139.314H716.298V185.651C716.298 200.189 704.183 212 689.646 212H636.646C622.109 212 610.298 200.189 610.298 185.651Z" fill="white"/>
|
||||
<path d="M541.841 33.3143V178.989H548.201C552.138 178.989 554.864 175.96 554.864 172.326V39.9771C554.864 36.3429 552.138 33.3143 548.201 33.3143H541.841ZM601.504 26.6514V185.651C601.504 200.189 589.389 212 574.852 212H495.504V0H574.852C589.389 0 601.504 12.1143 601.504 26.6514Z" fill="white"/>
|
||||
<path d="M407.037 212V0H486.385V33.3143H453.374V86.3143H486.385V125.989H453.374V178.989H486.385V212H407.037Z" fill="white"/>
|
||||
<path d="M338.587 125.989V178.989H345.249C348.884 178.989 351.609 175.96 351.609 172.326V132.651C351.609 129.017 348.884 125.989 345.249 125.989H338.587ZM371.598 106L372.204 106.303C386.741 106.606 398.249 118.114 398.249 132.651V185.651C398.249 200.189 386.135 212 371.598 212H292.249V0H371.598C386.135 0 398.249 12.1143 398.249 26.6514V79.6514C398.249 94.1886 386.135 106 371.598 106ZM338.587 86.3143H345.249C348.884 86.3143 351.609 83.2857 351.609 79.6514V39.9771C351.609 36.3429 348.884 33.3143 345.249 33.3143H338.587V86.3143Z" fill="white"/>
|
||||
<path d="M137.532 212V0H190.23L210.218 125.989L230.207 0H283.207V212H236.87V106L216.881 212H203.555L183.87 106V212H137.532Z" fill="white"/>
|
||||
<path d="M49.0637 212V0H128.412V33.3143H95.4008V86.3143H128.412V125.989H95.4008V178.989H128.412V212H49.0637Z" fill="white"/>
|
||||
<rect x="1125.62" y="65.6279" width="25.2381" height="25.238" fill="white"/>
|
||||
<path d="M1150.86 106H1160.95V121.143H1150.86V106Z" fill="white"/>
|
||||
<rect x="1125.62" y="121.118" width="15.1428" height="15.1429" fill="white"/>
|
||||
<rect x="1095.33" y="50.5068" width="25.2381" height="25.238" fill="#010312"/>
|
||||
<rect x="1105.43" y="111.022" width="15.1428" height="15.1429" fill="#010312"/>
|
||||
<rect x="1085.23" y="126.23" width="15.1428" height="15.1429" fill="#010312"/>
|
||||
<rect x="42.9069" y="55.4932" width="10.0952" height="25.238" fill="#010312"/>
|
||||
<rect x="45.4301" y="121.118" width="10.0952" height="20.1904" fill="#010312"/>
|
||||
<rect x="22.7124" y="55.5215" width="25.2381" height="25.238" fill="white"/>
|
||||
<path d="M0 121.148H10.0952V136.291H0V121.148Z" fill="white"/>
|
||||
<rect x="15.1404" y="141.375" width="15.1428" height="15.1429" fill="white"/>
|
||||
<rect x="60.5702" y="141.375" width="15.1428" height="15.1429" fill="#010312"/>
|
||||
<svg width="2052" height="549" viewBox="0 0 2052 549" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="2052" height="549" fill="#2A2B4C"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M406.248 151V398.8H498.996V360.214H460.41V298.264H498.996V251.89H460.41V189.94H498.996V151H406.248ZM509.655 151V398.8H563.817V274.9L586.827 398.8H602.403L625.767 274.9V398.8H679.929V151H617.979L594.615 298.264L571.251 151H509.655ZM744.661 360.214V298.264H752.449C756.697 298.264 759.883 301.804 759.883 306.052V352.426C759.883 356.674 756.697 360.214 752.449 360.214H744.661ZM783.955 275.254L783.247 274.9C800.239 274.9 814.399 261.094 814.399 244.102V182.152C814.399 165.16 800.239 151 783.247 151H690.499V398.8H783.247C800.239 398.8 814.399 384.994 814.399 368.002V306.052C814.399 289.06 800.947 275.608 783.955 275.254ZM752.449 251.89H744.661V189.94H752.449C756.697 189.94 759.883 193.48 759.883 197.728V244.102C759.883 248.35 756.697 251.89 752.449 251.89ZM917.421 151H824.673V398.8H917.421V360.214H878.835V298.264H917.421V251.89H878.835V189.94H917.421V151ZM982.242 360.214V189.94H989.676C994.278 189.94 997.464 193.48 997.464 197.728V352.426C997.464 356.674 994.278 360.214 989.676 360.214H982.242ZM1051.98 368.002V182.152C1051.98 165.16 1037.82 151 1020.83 151H928.08V398.8H1020.83C1037.82 398.8 1051.98 384.994 1051.98 368.002ZM428 314.8H410V332.8H428V314.8Z" fill="white"/>
|
||||
<rect x="357" y="314.8" width="18" height="18" fill="white"/>
|
||||
<rect x="340" y="291.8" width="11" height="18" fill="white"/>
|
||||
<rect x="366" y="214.8" width="30" height="30" fill="white"/>
|
||||
<rect x="1674.52" y="240.378" width="26.6955" height="26.6955" fill="white"/>
|
||||
<rect x="1700.32" y="283.091" width="10.6782" height="16.0173" fill="white"/>
|
||||
<rect x="1674.52" y="298.218" width="16.0173" height="16.0173" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1063 367.646V181.244C1063 164.202 1076.85 150 1093.89 150H1156.02C1173.07 150 1187.27 164.202 1187.27 181.244V235.567H1132.59V196.867C1132.59 192.606 1129.39 189.056 1124.78 189.056C1120.52 189.056 1117.32 192.606 1117.32 196.867V352.024C1117.32 356.284 1120.52 359.835 1124.78 359.835C1129.39 359.835 1132.59 356.284 1132.59 352.024V313.323H1187.27V367.646C1187.27 384.688 1173.07 398.535 1156.02 398.535H1093.89C1076.85 398.535 1063 384.688 1063 367.646ZM1196.14 398.535V150H1250.47V251.189H1265.73V150H1320.06V398.535H1265.73V297.701H1250.47V398.535H1196.14ZM1406.34 398.535L1402.79 359.835H1379.36L1375.45 398.535H1328.94L1359.83 150H1421.96L1453.21 398.535H1406.34ZM1383.62 313.323H1398.18L1390.72 235.567L1383.62 313.323ZM1516.06 398.535H1461.74V150H1516.06V398.535ZM1524.84 398.535V150H1579.17L1602.24 274.268V150H1648.76V225.251H1642.48V251.946H1648.76V303.557H1634.47V319.575H1648.76V398.535H1594.43L1571.35 274.268V398.535H1524.84Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg width="1371" height="249" viewBox="0 0 1371 249" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M66.248 1V248.8H158.996V210.214H120.41V148.264H158.996V101.89H120.41V39.94H158.996V1H66.248ZM169.655 1V248.8H223.817V124.9L246.827 248.8H262.403L285.767 124.9V248.8H339.929V1H277.979L254.615 148.264L231.251 1H169.655ZM404.661 210.214V148.264H412.449C416.697 148.264 419.883 151.804 419.883 156.052V202.426C419.883 206.674 416.697 210.214 412.449 210.214H404.661ZM443.955 125.254L443.247 124.9C460.239 124.9 474.399 111.094 474.399 94.102V32.152C474.399 15.16 460.239 1 443.247 1H350.499V248.8H443.247C460.239 248.8 474.399 234.994 474.399 218.002V156.052C474.399 139.06 460.947 125.608 443.955 125.254ZM412.449 101.89H404.661V39.94H412.449C416.697 39.94 419.883 43.48 419.883 47.728V94.102C419.883 98.35 416.697 101.89 412.449 101.89ZM577.421 1H484.673V248.8H577.421V210.214H538.835V148.264H577.421V101.89H538.835V39.94H577.421V1ZM642.242 210.214V39.94H649.676C654.278 39.94 657.464 43.48 657.464 47.728V202.426C657.464 206.674 654.278 210.214 649.676 210.214H642.242ZM711.98 218.002V32.152C711.98 15.16 697.82 1 680.828 1H588.08V248.8H680.828C697.82 248.8 711.98 234.994 711.98 218.002ZM88 164.8H70V182.8H88V164.8Z" fill="#2A2B4C"/>
|
||||
<rect x="17" y="164.8" width="18" height="18" fill="#2A2B4C"/>
|
||||
<rect y="141.8" width="11" height="18" fill="#2A2B4C"/>
|
||||
<rect x="26" y="64.7998" width="30" height="30" fill="#2A2B4C"/>
|
||||
<rect x="1334.52" y="90.3779" width="26.6955" height="26.6955" fill="#2A2B4C"/>
|
||||
<rect x="1360.32" y="133.091" width="10.6782" height="16.0173" fill="#2A2B4C"/>
|
||||
<rect x="1334.52" y="148.219" width="16.0173" height="16.0173" fill="#2A2B4C"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M723 217.646V31.2444C723 14.202 736.847 0 753.889 0H816.023C833.066 0 847.268 14.202 847.268 31.2444V85.5672H792.59V46.8667C792.59 42.6061 789.394 39.0556 784.779 39.0556C780.518 39.0556 777.323 42.6061 777.323 46.8667V202.024C777.323 206.284 780.518 209.835 784.779 209.835C789.394 209.835 792.59 206.284 792.59 202.024V163.323H847.268V217.646C847.268 234.688 833.066 248.535 816.023 248.535H753.889C736.847 248.535 723 234.688 723 217.646ZM856.144 248.535V0H910.467V101.189H925.734V0H980.057V248.535H925.734V147.701H910.467V248.535H856.144ZM1066.34 248.535L1062.79 209.835H1039.36L1035.45 248.535H988.941L1019.83 0H1081.96L1113.21 248.535H1066.34ZM1043.62 163.323H1058.18L1050.72 85.5672L1043.62 163.323ZM1176.06 248.535H1121.74V0H1176.06V248.535ZM1184.84 248.535V0H1239.17L1262.24 124.268V0H1308.76V75.2506H1302.48V101.946H1308.76V153.557H1294.47V169.575H1308.76V248.535H1254.43L1231.35 124.268V248.535H1184.84Z" fill="#2A2B4C"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,24 +1,11 @@
|
||||
<svg width="1161" height="212" viewBox="0 0 1161 212" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1010.3 212V0H1056.64L1076.33 106V0H1116V212H1069.66L1049.98 106V212H1010.3Z" fill="#010312"/>
|
||||
<path d="M1001.3 212H954.958V0H1001.3V212Z" fill="#010312"/>
|
||||
<path d="M906.196 212L903.167 178.989H883.179L879.847 212H840.173L866.522 0H919.522L946.173 212H906.196ZM886.813 139.314H899.23L892.87 72.9886L886.813 139.314Z" fill="#010312"/>
|
||||
<path d="M725.385 212V0H771.722V86.3143H784.745V0H831.082V212H784.745V125.989H771.722V212H725.385Z" fill="#010312"/>
|
||||
<path d="M610.298 185.651V26.6514C610.298 12.1143 622.109 0 636.646 0H689.646C704.183 0 716.298 12.1143 716.298 26.6514V72.9886H669.658V39.9771C669.658 36.3429 666.932 33.3143 662.995 33.3143C659.36 33.3143 656.635 36.3429 656.635 39.9771V172.326C656.635 175.96 659.36 178.989 662.995 178.989C666.932 178.989 669.658 175.96 669.658 172.326V139.314H716.298V185.651C716.298 200.189 704.183 212 689.646 212H636.646C622.109 212 610.298 200.189 610.298 185.651Z" fill="#010312"/>
|
||||
<path d="M541.841 33.3143V178.989H548.201C552.138 178.989 554.864 175.96 554.864 172.326V39.9771C554.864 36.3429 552.138 33.3143 548.201 33.3143H541.841ZM601.504 26.6514V185.651C601.504 200.189 589.389 212 574.852 212H495.504V0H574.852C589.389 0 601.504 12.1143 601.504 26.6514Z" fill="#010312"/>
|
||||
<path d="M407.037 212V0H486.385V33.3143H453.374V86.3143H486.385V125.989H453.374V178.989H486.385V212H407.037Z" fill="#010312"/>
|
||||
<path d="M338.587 125.989V178.989H345.249C348.884 178.989 351.609 175.96 351.609 172.326V132.651C351.609 129.017 348.884 125.989 345.249 125.989H338.587ZM371.598 106L372.204 106.303C386.741 106.606 398.249 118.114 398.249 132.651V185.651C398.249 200.189 386.135 212 371.598 212H292.249V0H371.598C386.135 0 398.249 12.1143 398.249 26.6514V79.6514C398.249 94.1886 386.135 106 371.598 106ZM338.587 86.3143H345.249C348.884 86.3143 351.609 83.2857 351.609 79.6514V39.9771C351.609 36.3429 348.884 33.3143 345.249 33.3143H338.587V86.3143Z" fill="#010312"/>
|
||||
<path d="M137.532 212V0H190.23L210.218 125.989L230.207 0H283.207V212H236.87V106L216.881 212H203.555L183.87 106V212H137.532Z" fill="#010312"/>
|
||||
<path d="M49.0637 212V0H128.412V33.3143H95.4008V86.3143H128.412V125.989H95.4008V178.989H128.412V212H49.0637Z" fill="#010312"/>
|
||||
<rect x="1125.62" y="65.6279" width="25.2381" height="25.238" fill="#010312"/>
|
||||
<path d="M1150.86 106H1160.95V121.143H1150.86V106Z" fill="#010312"/>
|
||||
<rect x="1125.62" y="121.118" width="15.1428" height="15.1429" fill="#010312"/>
|
||||
<rect x="1095.33" y="50.5068" width="25.2381" height="25.238" fill="white"/>
|
||||
<rect x="1105.43" y="111.022" width="15.1428" height="15.1429" fill="white"/>
|
||||
<rect x="1085.23" y="126.23" width="15.1428" height="15.1429" fill="white"/>
|
||||
<rect x="42.9069" y="55.4932" width="10.0952" height="25.238" fill="white"/>
|
||||
<rect x="45.4301" y="121.118" width="10.0952" height="20.1904" fill="white"/>
|
||||
<rect x="22.7124" y="55.5215" width="25.2381" height="25.238" fill="#010312"/>
|
||||
<path d="M0 121.148H10.0952V136.291H0V121.148Z" fill="#010312"/>
|
||||
<rect x="15.1404" y="141.375" width="15.1428" height="15.1429" fill="#010312"/>
|
||||
<rect x="60.5702" y="141.375" width="15.1428" height="15.1429" fill="white"/>
|
||||
<svg width="2052" height="549" viewBox="0 0 2052 549" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="2052" height="549" fill="#2A2B4C"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M406.248 151V398.8H498.996V360.214H460.41V298.264H498.996V251.89H460.41V189.94H498.996V151H406.248ZM509.655 151V398.8H563.817V274.9L586.827 398.8H602.403L625.767 274.9V398.8H679.929V151H617.979L594.615 298.264L571.251 151H509.655ZM744.661 360.214V298.264H752.449C756.697 298.264 759.883 301.804 759.883 306.052V352.426C759.883 356.674 756.697 360.214 752.449 360.214H744.661ZM783.955 275.254L783.247 274.9C800.239 274.9 814.399 261.094 814.399 244.102V182.152C814.399 165.16 800.239 151 783.247 151H690.499V398.8H783.247C800.239 398.8 814.399 384.994 814.399 368.002V306.052C814.399 289.06 800.947 275.608 783.955 275.254ZM752.449 251.89H744.661V189.94H752.449C756.697 189.94 759.883 193.48 759.883 197.728V244.102C759.883 248.35 756.697 251.89 752.449 251.89ZM917.421 151H824.673V398.8H917.421V360.214H878.835V298.264H917.421V251.89H878.835V189.94H917.421V151ZM982.242 360.214V189.94H989.676C994.278 189.94 997.464 193.48 997.464 197.728V352.426C997.464 356.674 994.278 360.214 989.676 360.214H982.242ZM1051.98 368.002V182.152C1051.98 165.16 1037.82 151 1020.83 151H928.08V398.8H1020.83C1037.82 398.8 1051.98 384.994 1051.98 368.002ZM428 314.8H410V332.8H428V314.8Z" fill="white"/>
|
||||
<rect x="357" y="314.8" width="18" height="18" fill="white"/>
|
||||
<rect x="340" y="291.8" width="11" height="18" fill="white"/>
|
||||
<rect x="366" y="214.8" width="30" height="30" fill="white"/>
|
||||
<rect x="1674.52" y="240.378" width="26.6955" height="26.6955" fill="white"/>
|
||||
<rect x="1700.32" y="283.091" width="10.6782" height="16.0173" fill="white"/>
|
||||
<rect x="1674.52" y="298.218" width="16.0173" height="16.0173" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M1063 367.646V181.244C1063 164.202 1076.85 150 1093.89 150H1156.02C1173.07 150 1187.27 164.202 1187.27 181.244V235.567H1132.59V196.867C1132.59 192.606 1129.39 189.056 1124.78 189.056C1120.52 189.056 1117.32 192.606 1117.32 196.867V352.024C1117.32 356.284 1120.52 359.835 1124.78 359.835C1129.39 359.835 1132.59 356.284 1132.59 352.024V313.323H1187.27V367.646C1187.27 384.688 1173.07 398.535 1156.02 398.535H1093.89C1076.85 398.535 1063 384.688 1063 367.646ZM1196.14 398.535V150H1250.47V251.189H1265.73V150H1320.06V398.535H1265.73V297.701H1250.47V398.535H1196.14ZM1406.34 398.535L1402.79 359.835H1379.36L1375.45 398.535H1328.94L1359.83 150H1421.96L1453.21 398.535H1406.34ZM1383.62 313.323H1398.18L1390.72 235.567L1383.62 313.323ZM1516.06 398.535H1461.74V150H1516.06V398.535ZM1524.84 398.535V150H1579.17L1602.24 274.268V150H1648.76V225.251H1642.48V251.946H1648.76V303.557H1634.47V319.575H1648.76V398.535H1594.43L1571.35 274.268V398.535H1524.84Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.8 KiB |
@@ -2,8 +2,8 @@
|
||||
"$schema": "https://mintlify.com/schema.json",
|
||||
"name": "Embedchain",
|
||||
"logo": {
|
||||
"dark": "/logo/dark.svg",
|
||||
"light": "/logo/light.svg",
|
||||
"dark": "/logo/dark-rt.svg",
|
||||
"light": "/logo/light-rt.svg",
|
||||
"href": "https://github.com/embedchain/embedchain"
|
||||
},
|
||||
"favicon": "/favicon.png",
|
||||
@@ -41,16 +41,6 @@
|
||||
"name": "Talk to founders",
|
||||
"icon": "calendar",
|
||||
"url": "https://cal.com/taranjeetio/ec"
|
||||
},
|
||||
{
|
||||
"name": "Join our slack",
|
||||
"icon": "slack",
|
||||
"url": "https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw"
|
||||
},
|
||||
{
|
||||
"name": "Join our discord",
|
||||
"icon": "discord",
|
||||
"url": "https://discord.gg/CUU9FPhRNt"
|
||||
}
|
||||
],
|
||||
"topbarLinks": [
|
||||
@@ -61,7 +51,7 @@
|
||||
],
|
||||
"topbarCtaButton": {
|
||||
"name": "Join our slack",
|
||||
"url": "https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw"
|
||||
"url": "https://embedchain.ai/slack"
|
||||
},
|
||||
"primaryTab": {
|
||||
"name": "Documentation"
|
||||
@@ -70,17 +60,79 @@
|
||||
{
|
||||
"group": "Get Started",
|
||||
"pages": [
|
||||
"get-started/introduction",
|
||||
"get-started/quickstart",
|
||||
"get-started/introduction",
|
||||
"get-started/faq",
|
||||
"get-started/full-stack",
|
||||
{
|
||||
"group": "🔗 Integrations",
|
||||
"group": "🔗 Integrations",
|
||||
"pages": [
|
||||
"integration/langsmith",
|
||||
"integration/chainlit",
|
||||
"integration/streamlit-mistral"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Use cases",
|
||||
"pages": [
|
||||
"use-cases/introduction",
|
||||
"use-cases/chatbots",
|
||||
"use-cases/question-answering",
|
||||
"use-cases/semantic-search"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Components",
|
||||
"pages": [
|
||||
"components/introduction",
|
||||
{
|
||||
"group": "Data sources",
|
||||
"pages": [
|
||||
|
||||
"components/data-sources/overview",
|
||||
{
|
||||
"group": "Data types",
|
||||
"pages": [
|
||||
"components/data-sources/pdf-file",
|
||||
"components/data-sources/csv",
|
||||
"components/data-sources/json",
|
||||
"components/data-sources/text",
|
||||
"components/data-sources/directory",
|
||||
"components/data-sources/web-page",
|
||||
"components/data-sources/youtube-channel",
|
||||
"components/data-sources/youtube-video",
|
||||
"components/data-sources/docs-site",
|
||||
"components/data-sources/mdx",
|
||||
"components/data-sources/docx",
|
||||
"components/data-sources/notion",
|
||||
"components/data-sources/sitemap",
|
||||
"components/data-sources/xml",
|
||||
"components/data-sources/qna",
|
||||
"components/data-sources/openapi",
|
||||
"components/data-sources/gmail",
|
||||
"components/data-sources/github",
|
||||
"components/data-sources/postgres",
|
||||
"components/data-sources/mysql",
|
||||
"components/data-sources/slack",
|
||||
"components/data-sources/discord",
|
||||
"components/data-sources/discourse",
|
||||
"components/data-sources/substack",
|
||||
"components/data-sources/beehiiv",
|
||||
"components/data-sources/directory",
|
||||
"components/data-sources/dropbox",
|
||||
"components/data-sources/image",
|
||||
"components/data-sources/custom"
|
||||
]
|
||||
},
|
||||
"components/data-sources/data-type-handling"
|
||||
]
|
||||
},
|
||||
"get-started/faq"
|
||||
"components/llms",
|
||||
"components/vector-databases",
|
||||
"components/embedding-models",
|
||||
"components/evaluation"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -91,55 +143,9 @@
|
||||
"deployment/modal_com",
|
||||
"deployment/render_com",
|
||||
"deployment/streamlit_io",
|
||||
"deployment/embedchain_ai",
|
||||
"deployment/gradio_app",
|
||||
"deployment/huggingface_spaces"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Use cases",
|
||||
"pages": [
|
||||
"use-cases/chatbots",
|
||||
"use-cases/question-answering",
|
||||
"use-cases/semantic-search"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Components",
|
||||
"pages": [
|
||||
{
|
||||
"group": "Data sources",
|
||||
"pages": [
|
||||
"components/data-sources/overview",
|
||||
{
|
||||
"group": "Data types",
|
||||
"pages": [
|
||||
"components/data-sources/csv",
|
||||
"components/data-sources/json",
|
||||
"components/data-sources/docs-site",
|
||||
"components/data-sources/docx",
|
||||
"components/data-sources/mdx",
|
||||
"components/data-sources/notion",
|
||||
"components/data-sources/pdf-file",
|
||||
"components/data-sources/qna",
|
||||
"components/data-sources/sitemap",
|
||||
"components/data-sources/text",
|
||||
"components/data-sources/web-page",
|
||||
"components/data-sources/openapi",
|
||||
"components/data-sources/youtube-video",
|
||||
"components/data-sources/discourse",
|
||||
"components/data-sources/substack",
|
||||
"components/data-sources/discord",
|
||||
"components/data-sources/beehiiv",
|
||||
"components/data-sources/directory"
|
||||
]
|
||||
},
|
||||
"components/data-sources/data-type-handling"
|
||||
]
|
||||
},
|
||||
"components/llms",
|
||||
"components/vector-databases",
|
||||
"components/embedding-models"
|
||||
"deployment/huggingface_spaces",
|
||||
"deployment/embedchain_ai"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -169,7 +175,9 @@
|
||||
},
|
||||
"examples/full_stack",
|
||||
"examples/openai-assistant",
|
||||
"examples/opensource-assistant"
|
||||
"examples/opensource-assistant",
|
||||
"examples/nextjs-assistant",
|
||||
"examples/slack-AI"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -191,17 +199,19 @@
|
||||
{
|
||||
"group": "API Reference",
|
||||
"pages": [
|
||||
"api-reference/pipeline/overview",
|
||||
"api-reference/app/overview",
|
||||
{
|
||||
"group": "Pipeline methods",
|
||||
"group": "App methods",
|
||||
"pages": [
|
||||
"api-reference/pipeline/add",
|
||||
"api-reference/pipeline/query",
|
||||
"api-reference/pipeline/chat",
|
||||
"api-reference/pipeline/search",
|
||||
"api-reference/pipeline/deploy",
|
||||
"api-reference/pipeline/reset",
|
||||
"api-reference/pipeline/delete"
|
||||
"api-reference/app/add",
|
||||
"api-reference/app/query",
|
||||
"api-reference/app/chat",
|
||||
"api-reference/app/search",
|
||||
"api-reference/app/get",
|
||||
"api-reference/app/evaluate",
|
||||
"api-reference/app/deploy",
|
||||
"api-reference/app/reset",
|
||||
"api-reference/app/delete"
|
||||
]
|
||||
},
|
||||
"api-reference/store/openai-assistant",
|
||||
@@ -229,7 +239,7 @@
|
||||
"footerSocials": {
|
||||
"website": "https://embedchain.ai",
|
||||
"github": "https://github.com/embedchain/embedchain",
|
||||
"slack": "https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw",
|
||||
"slack": "https://embedchain.ai/slack",
|
||||
"discord": "https://discord.gg/6PzXDgEjG5",
|
||||
"twitter": "https://twitter.com/embedchain",
|
||||
"linkedin": "https://www.linkedin.com/company/embedchain"
|
||||
@@ -239,6 +249,9 @@
|
||||
"posthog": {
|
||||
"apiKey": "phc_PHQDA5KwztijnSojsxJ2c1DuJd52QCzJzT2xnSGvjN2",
|
||||
"apiHost": "https://app.embedchain.ai/ingest"
|
||||
},
|
||||
"ga4": {
|
||||
"measurementId": "G-4QK7FJE6T3"
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
---
|
||||
title: 'FAQs'
|
||||
---
|
||||
@@ -1,3 +0,0 @@
|
||||
---
|
||||
title: 'Overview'
|
||||
---
|
||||
@@ -1,3 +0,0 @@
|
||||
---
|
||||
title: 'Quickstart'
|
||||
---
|
||||
@@ -1,3 +0,0 @@
|
||||
---
|
||||
title: 'Roadmap'
|
||||
---
|
||||
@@ -1,3 +0,0 @@
|
||||
---
|
||||
title: 'Security'
|
||||
---
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: 'Chatbots'
|
||||
title: '🤖 Chatbots'
|
||||
---
|
||||
|
||||
Chatbots, especially those powered by Large Language Models (LLMs), have a wide range of use cases, significantly enhancing various aspects of business, education, and personal assistance. Here are some key applications:
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: 🧱 Introduction
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
You can use embedchain to create the following usecases:
|
||||
|
||||
* [Chatbots](/use-cases/chatbots)
|
||||
* [Question Answering](/use-cases/question-answering)
|
||||
* [Semantic Search](/use-cases/semantic-search)
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: 'Question Answering'
|
||||
title: '❓ Question Answering'
|
||||
---
|
||||
|
||||
Utilizing large language models (LLMs) for question answering is a transformative application, bringing significant benefits to various real-world situations. Embedchain extensively supports tasks related to question answering, including summarization, content creation, language translation, and data analysis. The versatility of question answering with LLMs enables solutions for numerous practical applications such as:
|
||||
@@ -24,7 +24,7 @@ Quickly create a RAG pipeline to answer queries about the [Next.JS Framework](ht
|
||||
First, let's create your RAG pipeline. Open your Python environment and enter:
|
||||
|
||||
```python Create pipeline
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
app = App()
|
||||
```
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
title: '🔍 Semantic Search'
|
||||
---
|
||||
|
||||
Semantic searching, which involves understanding the intent and contextual meaning behind search queries, is yet another popular use-case of RAG. It has several popular use cases across various domains:
|
||||
|
||||
- **Information Retrieval**: Enhances search accuracy in databases and websites
|
||||
@@ -19,7 +23,7 @@ Embedchain offers a simple yet customizable `search()` API that you can use for
|
||||
First, let's create your RAG pipeline. Open your Python environment and enter:
|
||||
|
||||
```python Create pipeline
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain import App
|
||||
app = App()
|
||||
```
|
||||
|
||||
@@ -48,18 +52,24 @@ app.search("Summarize the features of Next.js 14?")
|
||||
[
|
||||
{
|
||||
'context': 'Next.js 14 | Next.jsBack to BlogThursday, October 26th 2023Next.js 14Posted byLee Robinson@leeerobTim Neutkens@timneutkensAs we announced at Next.js Conf, Next.js 14 is our most focused release with: Turbopack: 5,000 tests passing for App & Pages Router 53% faster local server startup 94% faster code updates with Fast Refresh Server Actions (Stable): Progressively enhanced mutations Integrated with caching & revalidating Simple function calls, or works natively with forms Partial Prerendering',
|
||||
'source': 'https://nextjs.org/blog/next-14',
|
||||
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
|
||||
'metadata': {
|
||||
'source': 'https://nextjs.org/blog/next-14',
|
||||
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
|
||||
}
|
||||
},
|
||||
{
|
||||
'context': 'Next.js 13.3 | Next.jsBack to BlogThursday, April 6th 2023Next.js 13.3Posted byDelba de Oliveira@delba_oliveiraTim Neutkens@timneutkensNext.js 13.3 adds popular community-requested features, including: File-Based Metadata API: Dynamically generate sitemaps, robots, favicons, and more. Dynamic Open Graph Images: Generate OG images using JSX, HTML, and CSS. Static Export for App Router: Static / Single-Page Application (SPA) support for Server Components. Parallel Routes and Interception: Advanced',
|
||||
'source': 'https://nextjs.org/blog/next-13-3',
|
||||
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
|
||||
'metadata': {
|
||||
'source': 'https://nextjs.org/blog/next-13-3',
|
||||
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
|
||||
}
|
||||
},
|
||||
{
|
||||
'context': 'Upgrading: Version 14 | Next.js MenuUsing App RouterFeatures available in /appApp Router.UpgradingVersion 14Version 14 Upgrading from 13 to 14 To update to Next.js version 14, run the following command using your preferred package manager: Terminalnpm i next@latest react@latest react-dom@latest eslint-config-next@latest Terminalyarn add next@latest react@latest react-dom@latest eslint-config-next@latest Terminalpnpm up next react react-dom eslint-config-next -latest Terminalbun add next@latest',
|
||||
'source': 'https://nextjs.org/docs/app/building-your-application/upgrading/version-14',
|
||||
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
|
||||
'metadata': {
|
||||
'source': 'https://nextjs.org/docs/app/building-your-application/upgrading/version-14',
|
||||
'document_id': '6c8d1a7b-ea34-4927-8823-daa29dcfc5af--b83edb69b8fc7e442ff8ca311b48510e6c80bf00caa806b3a6acb34e1bcdd5d5'
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
@@ -178,7 +178,7 @@ await app.addLocal("qna_pair", ["Question", "Answer"]);
|
||||
|
||||
## Testing
|
||||
|
||||
Before you consume valueable tokens, you should make sure that the embedding you have done works and that it's receiving the correct document from the database.
|
||||
Before you consume valuable tokens, you should make sure that the embedding you have done works and that it's receiving the correct document from the database.
|
||||
|
||||
For this you can use the `dryRun` method.
|
||||
|
||||
|
||||
@@ -2,10 +2,9 @@ import importlib.metadata
|
||||
|
||||
__version__ = importlib.metadata.version(__package__ or __name__)
|
||||
|
||||
from embedchain.apps.app import App # noqa: F401
|
||||
from embedchain.app import App # noqa: F401
|
||||
from embedchain.client import Client # noqa: F401
|
||||
from embedchain.pipeline import Pipeline # noqa: F401
|
||||
from embedchain.vectordb.chroma import ChromaDB # noqa: F401
|
||||
|
||||
# Setup the user directory if doesn't exist already
|
||||
Client.setup_dir()
|
||||
|
||||
@@ -0,0 +1,539 @@
|
||||
import ast
|
||||
import concurrent.futures
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sqlite3
|
||||
import uuid
|
||||
from typing import Any, Optional, Union
|
||||
|
||||
import requests
|
||||
import yaml
|
||||
from tqdm import tqdm
|
||||
|
||||
from embedchain.cache import (Config, ExactMatchEvaluation,
|
||||
SearchDistanceEvaluation, cache,
|
||||
gptcache_data_manager, gptcache_pre_function)
|
||||
from embedchain.client import Client
|
||||
from embedchain.config import AppConfig, CacheConfig, ChunkerConfig
|
||||
from embedchain.constants import SQLITE_PATH
|
||||
from embedchain.embedchain import EmbedChain
|
||||
from embedchain.embedder.base import BaseEmbedder
|
||||
from embedchain.embedder.openai import OpenAIEmbedder
|
||||
from embedchain.evaluation.base import BaseMetric
|
||||
from embedchain.evaluation.metrics import (AnswerRelevance, ContextRelevance,
|
||||
Groundedness)
|
||||
from embedchain.factory import EmbedderFactory, LlmFactory, VectorDBFactory
|
||||
from embedchain.helpers.json_serializable import register_deserializable
|
||||
from embedchain.llm.base import BaseLlm
|
||||
from embedchain.llm.openai import OpenAILlm
|
||||
from embedchain.telemetry.posthog import AnonymousTelemetry
|
||||
from embedchain.utils.evaluation import EvalData, EvalMetric
|
||||
from embedchain.utils.misc import validate_config
|
||||
from embedchain.vectordb.base import BaseVectorDB
|
||||
from embedchain.vectordb.chroma import ChromaDB
|
||||
|
||||
# Set up the user directory if it doesn't exist already
|
||||
Client.setup_dir()
|
||||
|
||||
|
||||
@register_deserializable
|
||||
class App(EmbedChain):
|
||||
"""
|
||||
EmbedChain App lets you create a LLM powered app for your unstructured
|
||||
data by defining your chosen data source, embedding model,
|
||||
and vector database.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
id: str = None,
|
||||
name: str = None,
|
||||
config: AppConfig = None,
|
||||
db: BaseVectorDB = None,
|
||||
embedding_model: BaseEmbedder = None,
|
||||
llm: BaseLlm = None,
|
||||
config_data: dict = None,
|
||||
log_level=logging.WARN,
|
||||
auto_deploy: bool = False,
|
||||
chunker: ChunkerConfig = None,
|
||||
cache_config: CacheConfig = None,
|
||||
):
|
||||
"""
|
||||
Initialize a new `App` instance.
|
||||
|
||||
:param config: Configuration for the pipeline, defaults to None
|
||||
:type config: AppConfig, optional
|
||||
:param db: The database to use for storing and retrieving embeddings, defaults to None
|
||||
:type db: BaseVectorDB, optional
|
||||
:param embedding_model: The embedding model used to calculate embeddings, defaults to None
|
||||
:type embedding_model: BaseEmbedder, optional
|
||||
:param llm: The LLM model used to calculate embeddings, defaults to None
|
||||
:type llm: BaseLlm, optional
|
||||
:param config_data: Config dictionary, defaults to None
|
||||
:type config_data: dict, optional
|
||||
:param log_level: Log level to use, defaults to logging.WARN
|
||||
:type log_level: int, optional
|
||||
:param auto_deploy: Whether to deploy the pipeline automatically, defaults to False
|
||||
:type auto_deploy: bool, optional
|
||||
:raises Exception: If an error occurs while creating the pipeline
|
||||
"""
|
||||
if id and config_data:
|
||||
raise Exception("Cannot provide both id and config. Please provide only one of them.")
|
||||
|
||||
if id and name:
|
||||
raise Exception("Cannot provide both id and name. Please provide only one of them.")
|
||||
|
||||
if name and config:
|
||||
raise Exception("Cannot provide both name and config. Please provide only one of them.")
|
||||
|
||||
logging.basicConfig(level=log_level, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.auto_deploy = auto_deploy
|
||||
# Store the dict config as an attribute to be able to send it
|
||||
self.config_data = config_data if (config_data and validate_config(config_data)) else None
|
||||
self.client = None
|
||||
# pipeline_id from the backend
|
||||
self.id = None
|
||||
self.chunker = None
|
||||
if chunker:
|
||||
self.chunker = ChunkerConfig(**chunker)
|
||||
self.cache_config = cache_config
|
||||
|
||||
self.config = config or AppConfig()
|
||||
self.name = self.config.name
|
||||
self.config.id = self.local_id = str(uuid.uuid4()) if self.config.id is None else self.config.id
|
||||
|
||||
if id is not None:
|
||||
# Init client first since user is trying to fetch the pipeline
|
||||
# details from the platform
|
||||
self._init_client()
|
||||
pipeline_details = self._get_pipeline(id)
|
||||
self.config.id = self.local_id = pipeline_details["metadata"]["local_id"]
|
||||
self.id = id
|
||||
|
||||
if name is not None:
|
||||
self.name = name
|
||||
|
||||
self.embedding_model = embedding_model or OpenAIEmbedder()
|
||||
self.db = db or ChromaDB()
|
||||
self.llm = llm or OpenAILlm()
|
||||
self._init_db()
|
||||
|
||||
# If cache_config is provided, initializing the cache ...
|
||||
if self.cache_config is not None:
|
||||
self._init_cache()
|
||||
|
||||
# Send anonymous telemetry
|
||||
self._telemetry_props = {"class": self.__class__.__name__}
|
||||
self.telemetry = AnonymousTelemetry(enabled=self.config.collect_metrics)
|
||||
|
||||
# Establish a connection to the SQLite database
|
||||
self.connection = sqlite3.connect(SQLITE_PATH, check_same_thread=False)
|
||||
self.cursor = self.connection.cursor()
|
||||
|
||||
# Create the 'data_sources' table if it doesn't exist
|
||||
self.cursor.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS data_sources (
|
||||
pipeline_id TEXT,
|
||||
hash TEXT,
|
||||
type TEXT,
|
||||
value TEXT,
|
||||
metadata TEXT,
|
||||
is_uploaded INTEGER DEFAULT 0,
|
||||
PRIMARY KEY (pipeline_id, hash)
|
||||
)
|
||||
"""
|
||||
)
|
||||
self.connection.commit()
|
||||
# Send anonymous telemetry
|
||||
self.telemetry.capture(event_name="init", properties=self._telemetry_props)
|
||||
|
||||
self.user_asks = []
|
||||
if self.auto_deploy:
|
||||
self.deploy()
|
||||
|
||||
def _init_db(self):
|
||||
"""
|
||||
Initialize the database.
|
||||
"""
|
||||
self.db._set_embedder(self.embedding_model)
|
||||
self.db._initialize()
|
||||
self.db.set_collection_name(self.db.config.collection_name)
|
||||
|
||||
def _init_cache(self):
|
||||
if self.cache_config.similarity_eval_config.strategy == "exact":
|
||||
similarity_eval_func = ExactMatchEvaluation()
|
||||
else:
|
||||
similarity_eval_func = SearchDistanceEvaluation(
|
||||
max_distance=self.cache_config.similarity_eval_config.max_distance,
|
||||
positive=self.cache_config.similarity_eval_config.positive,
|
||||
)
|
||||
|
||||
cache.init(
|
||||
pre_embedding_func=gptcache_pre_function,
|
||||
embedding_func=self.embedding_model.to_embeddings,
|
||||
data_manager=gptcache_data_manager(vector_dimension=self.embedding_model.vector_dimension),
|
||||
similarity_evaluation=similarity_eval_func,
|
||||
config=Config(**self.cache_config.init_config.as_dict()),
|
||||
)
|
||||
|
||||
def _init_client(self):
|
||||
"""
|
||||
Initialize the client.
|
||||
"""
|
||||
config = Client.load_config()
|
||||
if config.get("api_key"):
|
||||
self.client = Client()
|
||||
else:
|
||||
api_key = input(
|
||||
"🔑 Enter your Embedchain API key. You can find the API key at https://app.embedchain.ai/settings/keys/ \n" # noqa: E501
|
||||
)
|
||||
self.client = Client(api_key=api_key)
|
||||
|
||||
def _get_pipeline(self, id):
|
||||
"""
|
||||
Get existing pipeline
|
||||
"""
|
||||
print("🛠️ Fetching pipeline details from the platform...")
|
||||
url = f"{self.client.host}/api/v1/pipelines/{id}/cli/"
|
||||
r = requests.get(
|
||||
url,
|
||||
headers={"Authorization": f"Token {self.client.api_key}"},
|
||||
)
|
||||
if r.status_code == 404:
|
||||
raise Exception(f"❌ Pipeline with id {id} not found!")
|
||||
|
||||
print(
|
||||
f"🎉 Pipeline loaded successfully! Pipeline url: https://app.embedchain.ai/pipelines/{r.json()['id']}\n" # noqa: E501
|
||||
)
|
||||
return r.json()
|
||||
|
||||
def _create_pipeline(self):
|
||||
"""
|
||||
Create a pipeline on the platform.
|
||||
"""
|
||||
print("🛠️ Creating pipeline on the platform...")
|
||||
# self.config_data is a dict. Pass it inside the key 'yaml_config' to the backend
|
||||
payload = {
|
||||
"yaml_config": json.dumps(self.config_data),
|
||||
"name": self.name,
|
||||
"local_id": self.local_id,
|
||||
}
|
||||
url = f"{self.client.host}/api/v1/pipelines/cli/create/"
|
||||
r = requests.post(
|
||||
url,
|
||||
json=payload,
|
||||
headers={"Authorization": f"Token {self.client.api_key}"},
|
||||
)
|
||||
if r.status_code not in [200, 201]:
|
||||
raise Exception(f"❌ Error occurred while creating pipeline. API response: {r.text}")
|
||||
|
||||
if r.status_code == 200:
|
||||
print(
|
||||
f"🎉🎉🎉 Existing pipeline found! View your pipeline: https://app.embedchain.ai/pipelines/{r.json()['id']}\n" # noqa: E501
|
||||
) # noqa: E501
|
||||
elif r.status_code == 201:
|
||||
print(
|
||||
f"🎉🎉🎉 Pipeline created successfully! View your pipeline: https://app.embedchain.ai/pipelines/{r.json()['id']}\n" # noqa: E501
|
||||
)
|
||||
return r.json()
|
||||
|
||||
def _get_presigned_url(self, data_type, data_value):
|
||||
payload = {"data_type": data_type, "data_value": data_value}
|
||||
r = requests.post(
|
||||
f"{self.client.host}/api/v1/pipelines/{self.id}/cli/presigned_url/",
|
||||
json=payload,
|
||||
headers={"Authorization": f"Token {self.client.api_key}"},
|
||||
)
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
def _upload_file_to_presigned_url(self, presigned_url, file_path):
|
||||
try:
|
||||
with open(file_path, "rb") as file:
|
||||
response = requests.put(presigned_url, data=file)
|
||||
response.raise_for_status()
|
||||
return response.status_code == 200
|
||||
except Exception as e:
|
||||
self.logger.exception(f"Error occurred during file upload: {str(e)}")
|
||||
print("❌ Error occurred during file upload!")
|
||||
return False
|
||||
|
||||
def _upload_data_to_pipeline(self, data_type, data_value, metadata=None):
|
||||
payload = {
|
||||
"data_type": data_type,
|
||||
"data_value": data_value,
|
||||
"metadata": metadata,
|
||||
}
|
||||
try:
|
||||
self._send_api_request(f"/api/v1/pipelines/{self.id}/cli/add/", payload)
|
||||
# print the local file path if user tries to upload a local file
|
||||
printed_value = metadata.get("file_path") if metadata.get("file_path") else data_value
|
||||
print(f"✅ Data of type: {data_type}, value: {printed_value} added successfully.")
|
||||
except Exception as e:
|
||||
print(f"❌ Error occurred during data upload for type {data_type}!. Error: {str(e)}")
|
||||
|
||||
def _send_api_request(self, endpoint, payload):
|
||||
url = f"{self.client.host}{endpoint}"
|
||||
headers = {"Authorization": f"Token {self.client.api_key}"}
|
||||
response = requests.post(url, json=payload, headers=headers)
|
||||
response.raise_for_status()
|
||||
return response
|
||||
|
||||
def _process_and_upload_data(self, data_hash, data_type, data_value):
|
||||
if os.path.isabs(data_value):
|
||||
presigned_url_data = self._get_presigned_url(data_type, data_value)
|
||||
presigned_url = presigned_url_data["presigned_url"]
|
||||
s3_key = presigned_url_data["s3_key"]
|
||||
if self._upload_file_to_presigned_url(presigned_url, file_path=data_value):
|
||||
metadata = {"file_path": data_value, "s3_key": s3_key}
|
||||
data_value = presigned_url
|
||||
else:
|
||||
self.logger.error(f"File upload failed for hash: {data_hash}")
|
||||
return False
|
||||
else:
|
||||
if data_type == "qna_pair":
|
||||
data_value = list(ast.literal_eval(data_value))
|
||||
metadata = {}
|
||||
|
||||
try:
|
||||
self._upload_data_to_pipeline(data_type, data_value, metadata)
|
||||
self._mark_data_as_uploaded(data_hash)
|
||||
return True
|
||||
except Exception:
|
||||
print(f"❌ Error occurred during data upload for hash {data_hash}!")
|
||||
return False
|
||||
|
||||
def _mark_data_as_uploaded(self, data_hash):
|
||||
self.cursor.execute(
|
||||
"UPDATE data_sources SET is_uploaded = 1 WHERE hash = ? AND pipeline_id = ?",
|
||||
(data_hash, self.local_id),
|
||||
)
|
||||
self.connection.commit()
|
||||
|
||||
def get_data_sources(self):
|
||||
db_data = self.cursor.execute("SELECT * FROM data_sources WHERE pipeline_id = ?", (self.local_id,)).fetchall()
|
||||
|
||||
data_sources = []
|
||||
for data in db_data:
|
||||
data_sources.append({"data_type": data[2], "data_value": data[3], "metadata": data[4]})
|
||||
|
||||
return data_sources
|
||||
|
||||
def deploy(self):
|
||||
if self.client is None:
|
||||
self._init_client()
|
||||
|
||||
pipeline_data = self._create_pipeline()
|
||||
self.id = pipeline_data["id"]
|
||||
|
||||
results = self.cursor.execute(
|
||||
"SELECT * FROM data_sources WHERE pipeline_id = ? AND is_uploaded = 0", (self.local_id,) # noqa:E501
|
||||
).fetchall()
|
||||
|
||||
if len(results) > 0:
|
||||
print("🛠️ Adding data to your pipeline...")
|
||||
for result in results:
|
||||
data_hash, data_type, data_value = result[1], result[2], result[3]
|
||||
self._process_and_upload_data(data_hash, data_type, data_value)
|
||||
|
||||
# Send anonymous telemetry
|
||||
self.telemetry.capture(event_name="deploy", properties=self._telemetry_props)
|
||||
|
||||
@classmethod
|
||||
def from_config(
|
||||
cls,
|
||||
config_path: Optional[str] = None,
|
||||
config: Optional[dict[str, Any]] = None,
|
||||
auto_deploy: bool = False,
|
||||
yaml_path: Optional[str] = None,
|
||||
):
|
||||
"""
|
||||
Instantiate a Pipeline object from a configuration.
|
||||
|
||||
:param config_path: Path to the YAML or JSON configuration file.
|
||||
:type config_path: Optional[str]
|
||||
:param config: A dictionary containing the configuration.
|
||||
:type config: Optional[dict[str, Any]]
|
||||
:param auto_deploy: Whether to deploy the pipeline automatically, defaults to False
|
||||
:type auto_deploy: bool, optional
|
||||
:param yaml_path: (Deprecated) Path to the YAML configuration file. Use config_path instead.
|
||||
:type yaml_path: Optional[str]
|
||||
:return: An instance of the Pipeline class.
|
||||
:rtype: Pipeline
|
||||
"""
|
||||
# Backward compatibility for yaml_path
|
||||
if yaml_path and not config_path:
|
||||
config_path = yaml_path
|
||||
|
||||
if config_path and config:
|
||||
raise ValueError("Please provide only one of config_path or config.")
|
||||
|
||||
config_data = None
|
||||
|
||||
if config_path:
|
||||
file_extension = os.path.splitext(config_path)[1]
|
||||
with open(config_path, "r", encoding="UTF-8") as file:
|
||||
if file_extension in [".yaml", ".yml"]:
|
||||
config_data = yaml.safe_load(file)
|
||||
elif file_extension == ".json":
|
||||
config_data = json.load(file)
|
||||
else:
|
||||
raise ValueError("config_path must be a path to a YAML or JSON file.")
|
||||
elif config and isinstance(config, dict):
|
||||
config_data = config
|
||||
else:
|
||||
logging.error(
|
||||
"Please provide either a config file path (YAML or JSON) or a config dictionary. Falling back to defaults because no config is provided.", # noqa: E501
|
||||
)
|
||||
config_data = {}
|
||||
|
||||
try:
|
||||
validate_config(config_data)
|
||||
except Exception as e:
|
||||
raise Exception(f"Error occurred while validating the config. Error: {str(e)}")
|
||||
|
||||
app_config_data = config_data.get("app", {}).get("config", {})
|
||||
db_config_data = config_data.get("vectordb", {})
|
||||
embedding_model_config_data = config_data.get("embedding_model", config_data.get("embedder", {}))
|
||||
llm_config_data = config_data.get("llm", {})
|
||||
chunker_config_data = config_data.get("chunker", {})
|
||||
cache_config_data = config_data.get("cache", None)
|
||||
|
||||
app_config = AppConfig(**app_config_data)
|
||||
|
||||
db_provider = db_config_data.get("provider", "chroma")
|
||||
db = VectorDBFactory.create(db_provider, db_config_data.get("config", {}))
|
||||
|
||||
if llm_config_data:
|
||||
llm_provider = llm_config_data.get("provider", "openai")
|
||||
llm = LlmFactory.create(llm_provider, llm_config_data.get("config", {}))
|
||||
else:
|
||||
llm = None
|
||||
|
||||
embedding_model_provider = embedding_model_config_data.get("provider", "openai")
|
||||
embedding_model = EmbedderFactory.create(
|
||||
embedding_model_provider, embedding_model_config_data.get("config", {})
|
||||
)
|
||||
|
||||
if cache_config_data is not None:
|
||||
cache_config = CacheConfig.from_config(cache_config_data)
|
||||
else:
|
||||
cache_config = None
|
||||
|
||||
# Send anonymous telemetry
|
||||
event_properties = {"init_type": "config_data"}
|
||||
AnonymousTelemetry().capture(event_name="init", properties=event_properties)
|
||||
|
||||
return cls(
|
||||
config=app_config,
|
||||
llm=llm,
|
||||
db=db,
|
||||
embedding_model=embedding_model,
|
||||
config_data=config_data,
|
||||
auto_deploy=auto_deploy,
|
||||
chunker=chunker_config_data,
|
||||
cache_config=cache_config,
|
||||
)
|
||||
|
||||
def _eval(self, dataset: list[EvalData], metric: Union[BaseMetric, str]):
|
||||
"""
|
||||
Evaluate the app on a dataset for a given metric.
|
||||
"""
|
||||
metric_str = metric.name if isinstance(metric, BaseMetric) else metric
|
||||
eval_class_map = {
|
||||
EvalMetric.CONTEXT_RELEVANCY.value: ContextRelevance,
|
||||
EvalMetric.ANSWER_RELEVANCY.value: AnswerRelevance,
|
||||
EvalMetric.GROUNDEDNESS.value: Groundedness,
|
||||
}
|
||||
|
||||
if metric_str in eval_class_map:
|
||||
return eval_class_map[metric_str]().evaluate(dataset)
|
||||
|
||||
# Handle the case for custom metrics
|
||||
if isinstance(metric, BaseMetric):
|
||||
return metric.evaluate(dataset)
|
||||
else:
|
||||
raise ValueError(f"Invalid metric: {metric}")
|
||||
|
||||
def evaluate(
|
||||
self,
|
||||
questions: Union[str, list[str]],
|
||||
metrics: Optional[list[Union[BaseMetric, str]]] = None,
|
||||
num_workers: int = 4,
|
||||
):
|
||||
"""
|
||||
Evaluate the app on a question.
|
||||
|
||||
param: questions: A question or a list of questions to evaluate.
|
||||
type: questions: Union[str, list[str]]
|
||||
param: metrics: A list of metrics to evaluate. Defaults to all metrics.
|
||||
type: metrics: Optional[list[Union[BaseMetric, str]]]
|
||||
param: num_workers: Number of workers to use for parallel processing.
|
||||
type: num_workers: int
|
||||
return: A dictionary containing the evaluation results.
|
||||
rtype: dict
|
||||
"""
|
||||
if "OPENAI_API_KEY" not in os.environ:
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable with permission to use `gpt4` model.")
|
||||
|
||||
queries, answers, contexts = [], [], []
|
||||
if isinstance(questions, list):
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
|
||||
future_to_data = {executor.submit(self.query, q, citations=True): q for q in questions}
|
||||
for future in tqdm(
|
||||
concurrent.futures.as_completed(future_to_data),
|
||||
total=len(future_to_data),
|
||||
desc="Getting answer and contexts for questions",
|
||||
):
|
||||
question = future_to_data[future]
|
||||
queries.append(question)
|
||||
answer, context = future.result()
|
||||
answers.append(answer)
|
||||
contexts.append(list(map(lambda x: x[0], context)))
|
||||
else:
|
||||
answer, context = self.query(questions, citations=True)
|
||||
queries = [questions]
|
||||
answers = [answer]
|
||||
contexts = [list(map(lambda x: x[0], context))]
|
||||
|
||||
metrics = metrics or [
|
||||
EvalMetric.CONTEXT_RELEVANCY.value,
|
||||
EvalMetric.ANSWER_RELEVANCY.value,
|
||||
EvalMetric.GROUNDEDNESS.value,
|
||||
]
|
||||
|
||||
logging.info(f"Collecting data from {len(queries)} questions for evaluation...")
|
||||
dataset = []
|
||||
for q, a, c in zip(queries, answers, contexts):
|
||||
dataset.append(EvalData(question=q, answer=a, contexts=c))
|
||||
|
||||
logging.info(f"Evaluating {len(dataset)} data points...")
|
||||
result = {}
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=num_workers) as executor:
|
||||
future_to_metric = {executor.submit(self._eval, dataset, metric): metric for metric in metrics}
|
||||
for future in tqdm(
|
||||
concurrent.futures.as_completed(future_to_metric),
|
||||
total=len(future_to_metric),
|
||||
desc="Evaluating metrics",
|
||||
):
|
||||
metric = future_to_metric[future]
|
||||
if isinstance(metric, BaseMetric):
|
||||
result[metric.name] = future.result()
|
||||
else:
|
||||
result[metric] = future.result()
|
||||
|
||||
if self.config.collect_metrics:
|
||||
telemetry_props = self._telemetry_props
|
||||
metrics_names = []
|
||||
for metric in metrics:
|
||||
if isinstance(metric, BaseMetric):
|
||||
metrics_names.append(metric.name)
|
||||
else:
|
||||
metrics_names.append(metric)
|
||||
telemetry_props["metrics"] = metrics_names
|
||||
self.telemetry.capture(event_name="evaluate", properties=telemetry_props)
|
||||
|
||||
return result
|
||||
@@ -1,157 +0,0 @@
|
||||
from typing import Optional
|
||||
|
||||
import yaml
|
||||
|
||||
from embedchain.config import (AppConfig, BaseEmbedderConfig, BaseLlmConfig,
|
||||
ChunkerConfig)
|
||||
from embedchain.config.vectordb.base import BaseVectorDbConfig
|
||||
from embedchain.embedchain import EmbedChain
|
||||
from embedchain.embedder.base import BaseEmbedder
|
||||
from embedchain.embedder.openai import OpenAIEmbedder
|
||||
from embedchain.factory import EmbedderFactory, LlmFactory, VectorDBFactory
|
||||
from embedchain.helpers.json_serializable import register_deserializable
|
||||
from embedchain.llm.base import BaseLlm
|
||||
from embedchain.llm.openai import OpenAILlm
|
||||
from embedchain.utils import validate_config
|
||||
from embedchain.vectordb.base import BaseVectorDB
|
||||
from embedchain.vectordb.chroma import ChromaDB
|
||||
|
||||
|
||||
@register_deserializable
|
||||
class App(EmbedChain):
|
||||
"""
|
||||
The EmbedChain app in it's simplest and most straightforward form.
|
||||
An opinionated choice of LLM, vector database and embedding model.
|
||||
|
||||
Methods:
|
||||
add(source, data_type): adds the data from the given URL to the vector db.
|
||||
query(query): finds answer to the given query using vector database and LLM.
|
||||
chat(query): finds answer to the given query using vector database and LLM, with conversation history.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: Optional[AppConfig] = None,
|
||||
llm: BaseLlm = None,
|
||||
llm_config: Optional[BaseLlmConfig] = None,
|
||||
db: BaseVectorDB = None,
|
||||
db_config: Optional[BaseVectorDbConfig] = None,
|
||||
embedder: BaseEmbedder = None,
|
||||
embedder_config: Optional[BaseEmbedderConfig] = None,
|
||||
system_prompt: Optional[str] = None,
|
||||
chunker: Optional[ChunkerConfig] = None,
|
||||
):
|
||||
"""
|
||||
Initialize a new `App` instance.
|
||||
|
||||
:param config: Config for the app instance., defaults to None
|
||||
:type config: Optional[AppConfig], optional
|
||||
:param llm: LLM Class instance. example: `from embedchain.llm.openai import OpenAILlm`, defaults to OpenAiLlm
|
||||
:type llm: BaseLlm, optional
|
||||
:param llm_config: Allows you to configure the LLM, e.g. how many documents to return,
|
||||
example: `from embedchain.config import BaseLlmConfig`, defaults to None
|
||||
:type llm_config: Optional[BaseLlmConfig], optional
|
||||
:param db: The database to use for storing and retrieving embeddings,
|
||||
example: `from embedchain.vectordb.chroma_db import ChromaDb`, defaults to ChromaDb
|
||||
:type db: BaseVectorDB, optional
|
||||
:param db_config: Allows you to configure the vector database,
|
||||
example: `from embedchain.config import ChromaDbConfig`, defaults to None
|
||||
:type db_config: Optional[BaseVectorDbConfig], optional
|
||||
:param embedder: The embedder (embedding model and function) use to calculate embeddings.
|
||||
example: `from embedchain.embedder.gpt4all_embedder import GPT4AllEmbedder`, defaults to OpenAIEmbedder
|
||||
:type embedder: BaseEmbedder, optional
|
||||
:param embedder_config: Allows you to configure the Embedder.
|
||||
example: `from embedchain.config import BaseEmbedderConfig`, defaults to None
|
||||
:type embedder_config: Optional[BaseEmbedderConfig], optional
|
||||
:param system_prompt: System prompt that will be provided to the LLM as such, defaults to None
|
||||
:type system_prompt: Optional[str], optional
|
||||
:raises TypeError: LLM, database or embedder or their config is not a valid class instance.
|
||||
"""
|
||||
# Type check configs
|
||||
if config and not isinstance(config, AppConfig):
|
||||
raise TypeError(
|
||||
"Config is not a `AppConfig` instance. "
|
||||
"Please make sure the type is right and that you are passing an instance."
|
||||
)
|
||||
if llm_config and not isinstance(llm_config, BaseLlmConfig):
|
||||
raise TypeError(
|
||||
"`llm_config` is not a `BaseLlmConfig` instance. "
|
||||
"Please make sure the type is right and that you are passing an instance."
|
||||
)
|
||||
if db_config and not isinstance(db_config, BaseVectorDbConfig):
|
||||
raise TypeError(
|
||||
"`db_config` is not a `BaseVectorDbConfig` instance. "
|
||||
"Please make sure the type is right and that you are passing an instance."
|
||||
)
|
||||
if embedder_config and not isinstance(embedder_config, BaseEmbedderConfig):
|
||||
raise TypeError(
|
||||
"`embedder_config` is not a `BaseEmbedderConfig` instance. "
|
||||
"Please make sure the type is right and that you are passing an instance."
|
||||
)
|
||||
|
||||
# Assign defaults
|
||||
if config is None:
|
||||
config = AppConfig()
|
||||
if llm is None:
|
||||
llm = OpenAILlm(config=llm_config)
|
||||
if db is None:
|
||||
db = ChromaDB(config=db_config)
|
||||
if embedder is None:
|
||||
embedder = OpenAIEmbedder(config=embedder_config)
|
||||
|
||||
self.chunker = None
|
||||
if chunker:
|
||||
self.chunker = ChunkerConfig(**chunker)
|
||||
# Type check assignments
|
||||
if not isinstance(llm, BaseLlm):
|
||||
raise TypeError(
|
||||
"LLM is not a `BaseLlm` instance. "
|
||||
"Please make sure the type is right and that you are passing an instance."
|
||||
)
|
||||
if not isinstance(db, BaseVectorDB):
|
||||
raise TypeError(
|
||||
"Database is not a `BaseVectorDB` instance. "
|
||||
"Please make sure the type is right and that you are passing an instance."
|
||||
)
|
||||
if not isinstance(embedder, BaseEmbedder):
|
||||
raise TypeError(
|
||||
"Embedder is not a `BaseEmbedder` instance. "
|
||||
"Please make sure the type is right and that you are passing an instance."
|
||||
)
|
||||
super().__init__(config, llm=llm, db=db, embedder=embedder, system_prompt=system_prompt)
|
||||
|
||||
@classmethod
|
||||
def from_config(cls, yaml_path: str):
|
||||
"""
|
||||
Instantiate an App object from a YAML configuration file.
|
||||
|
||||
:param yaml_path: Path to the YAML configuration file.
|
||||
:type yaml_path: str
|
||||
:return: An instance of the App class.
|
||||
:rtype: App
|
||||
"""
|
||||
with open(yaml_path, "r") as file:
|
||||
config_data = yaml.safe_load(file)
|
||||
|
||||
try:
|
||||
validate_config(config_data)
|
||||
except Exception as e:
|
||||
raise Exception(f"❌ Error occurred while validating the YAML config. Error: {str(e)}")
|
||||
|
||||
app_config_data = config_data.get("app", {})
|
||||
llm_config_data = config_data.get("llm", {})
|
||||
db_config_data = config_data.get("vectordb", {})
|
||||
embedding_model_config_data = config_data.get("embedding_model", config_data.get("embedder", {}))
|
||||
chunker_config_data = config_data.get("chunker", {})
|
||||
|
||||
app_config = AppConfig(**app_config_data.get("config", {}))
|
||||
|
||||
llm_provider = llm_config_data.get("provider", "openai")
|
||||
llm = LlmFactory.create(llm_provider, llm_config_data.get("config", {}))
|
||||
|
||||
db_provider = db_config_data.get("provider", "chroma")
|
||||
db = VectorDBFactory.create(db_provider, db_config_data.get("config", {}))
|
||||
|
||||
embedder_provider = embedding_model_config_data.get("provider", "openai")
|
||||
embedder = EmbedderFactory.create(embedder_provider, embedding_model_config_data.get("config", {}))
|
||||
return cls(config=app_config, llm=llm, db=db, embedder=embedder, chunker=chunker_config_data)
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Any
|
||||
|
||||
from embedchain import Pipeline as App
|
||||
from embedchain.config import AddConfig, BaseLlmConfig, PipelineConfig
|
||||
from embedchain import App
|
||||
from embedchain.config import AddConfig, AppConfig, BaseLlmConfig
|
||||
from embedchain.embedder.openai import OpenAIEmbedder
|
||||
from embedchain.helpers.json_serializable import (JSONSerializable,
|
||||
register_deserializable)
|
||||
@@ -12,7 +12,7 @@ from embedchain.vectordb.chroma import ChromaDB
|
||||
@register_deserializable
|
||||
class BaseBot(JSONSerializable):
|
||||
def __init__(self):
|
||||
self.app = App(config=PipelineConfig(), llm=OpenAILlm(), db=ChromaDB(), embedding_model=OpenAIEmbedder())
|
||||
self.app = App(config=AppConfig(), llm=OpenAILlm(), db=ChromaDB(), embedding_model=OpenAIEmbedder())
|
||||
|
||||
def add(self, data: Any, config: AddConfig = None):
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
from typing import List, Optional
|
||||
from typing import Optional
|
||||
|
||||
from embedchain.helpers.json_serializable import register_deserializable
|
||||
|
||||
@@ -53,7 +53,7 @@ class PoeBot(BaseBot, PoeBot):
|
||||
answer = self.handle_message(last_message, history)
|
||||
yield self.text_event(answer)
|
||||
|
||||
def handle_message(self, message, history: Optional[List[str]] = None):
|
||||
def handle_message(self, message, history: Optional[list[str]] = None):
|
||||
if message.startswith("/add "):
|
||||
response = self.add_data(message)
|
||||
else:
|
||||
@@ -70,7 +70,7 @@ class PoeBot(BaseBot, PoeBot):
|
||||
# response = "Some error occurred while adding data."
|
||||
# return response
|
||||
|
||||
def ask_bot(self, message, history: List[str]):
|
||||
def ask_bot(self, message, history: list[str]):
|
||||
try:
|
||||
self.app.llm.set_history(history=history)
|
||||
response = self.query(message)
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import logging
|
||||
import os # noqa: F401
|
||||
from typing import Any
|
||||
|
||||
from gptcache import cache # noqa: F401
|
||||
from gptcache.adapter.adapter import adapt # noqa: F401
|
||||
from gptcache.config import Config # noqa: F401
|
||||
from gptcache.manager import get_data_manager
|
||||
from gptcache.manager.scalar_data.base import Answer
|
||||
from gptcache.manager.scalar_data.base import DataType as CacheDataType
|
||||
from gptcache.session import Session
|
||||
from gptcache.similarity_evaluation.distance import \
|
||||
SearchDistanceEvaluation # noqa: F401
|
||||
from gptcache.similarity_evaluation.exact_match import \
|
||||
ExactMatchEvaluation # noqa: F401
|
||||
|
||||
|
||||
def gptcache_pre_function(data: dict[str, Any], **params: dict[str, Any]):
|
||||
return data["input_query"]
|
||||
|
||||
|
||||
def gptcache_data_manager(vector_dimension):
|
||||
return get_data_manager(cache_base="sqlite", vector_base="chromadb", max_size=1000, eviction="LRU")
|
||||
|
||||
|
||||
def gptcache_data_convert(cache_data):
|
||||
logging.info("[Cache] Cache hit, returning cache data...")
|
||||
return cache_data
|
||||
|
||||
|
||||
def gptcache_update_cache_callback(llm_data, update_cache_func, *args, **kwargs):
|
||||
logging.info("[Cache] Cache missed, updating cache...")
|
||||
update_cache_func(Answer(llm_data, CacheDataType.STR))
|
||||
return llm_data
|
||||
|
||||
|
||||
def _gptcache_session_hit_func(cur_session_id: str, cache_session_ids: list, cache_questions: list, cache_answer: str):
|
||||
return cur_session_id in cache_session_ids
|
||||
|
||||
|
||||
def get_gptcache_session(session_id: str):
|
||||
return Session(name=session_id, check_hit_func=_gptcache_session_hit_func)
|
||||
@@ -17,7 +17,7 @@ class BaseChunker(JSONSerializable):
|
||||
"""
|
||||
Loads data and chunks it.
|
||||
|
||||
:param loader: The loader which's `load_data` method is used to create
|
||||
:param loader: The loader whose `load_data` method is used to create
|
||||
the raw data.
|
||||
:param src: The data to be handled by the loader. Can be a URL for
|
||||
remote sources or local content for local loaders.
|
||||
@@ -25,9 +25,9 @@ class BaseChunker(JSONSerializable):
|
||||
"""
|
||||
documents = []
|
||||
chunk_ids = []
|
||||
idMap = {}
|
||||
id_map = {}
|
||||
min_chunk_size = config.min_chunk_size if config is not None else 1
|
||||
logging.info(f"[INFO] Skipping chunks smaller than {min_chunk_size} characters")
|
||||
logging.info(f"Skipping chunks smaller than {min_chunk_size} characters")
|
||||
data_result = loader.load_data(src)
|
||||
data_records = data_result["data"]
|
||||
doc_id = data_result["doc_id"]
|
||||
@@ -39,21 +39,24 @@ class BaseChunker(JSONSerializable):
|
||||
for data in data_records:
|
||||
content = data["content"]
|
||||
|
||||
meta_data = data["meta_data"]
|
||||
metadata = data["meta_data"]
|
||||
# add data type to meta data to allow query using data type
|
||||
meta_data["data_type"] = self.data_type.value
|
||||
meta_data["doc_id"] = doc_id
|
||||
url = meta_data["url"]
|
||||
metadata["data_type"] = self.data_type.value
|
||||
metadata["doc_id"] = doc_id
|
||||
|
||||
# TODO: Currently defaulting to the src as the url. This is done intentianally since some
|
||||
# of the data types like 'gmail' loader doesn't have the url in the meta data.
|
||||
url = metadata.get("url", src)
|
||||
|
||||
chunks = self.get_chunks(content)
|
||||
for chunk in chunks:
|
||||
chunk_id = hashlib.sha256((chunk + url).encode()).hexdigest()
|
||||
chunk_id = f"{app_id}--{chunk_id}" if app_id is not None else chunk_id
|
||||
if idMap.get(chunk_id) is None and len(chunk) >= min_chunk_size:
|
||||
idMap[chunk_id] = True
|
||||
if id_map.get(chunk_id) is None and len(chunk) >= min_chunk_size:
|
||||
id_map[chunk_id] = True
|
||||
chunk_ids.append(chunk_id)
|
||||
documents.append(chunk)
|
||||
metadatas.append(meta_data)
|
||||
metadatas.append(metadata)
|
||||
return {
|
||||
"documents": documents,
|
||||
"ids": chunk_ids,
|
||||
@@ -77,5 +80,6 @@ class BaseChunker(JSONSerializable):
|
||||
|
||||
# TODO: This should be done during initialization. This means it has to be done in the child classes.
|
||||
|
||||
def get_word_count(self, documents):
|
||||
@staticmethod
|
||||
def get_word_count(documents) -> int:
|
||||
return sum([len(document.split(" ")) for document in documents])
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
from typing import Optional
|
||||
|
||||
from langchain.text_splitter import RecursiveCharacterTextSplitter
|
||||
|
||||
from embedchain.chunkers.base_chunker import BaseChunker
|
||||
from embedchain.config.add_config import ChunkerConfig
|
||||
from embedchain.helpers.json_serializable import register_deserializable
|
||||
|
||||
|
||||
@register_deserializable
|
||||
class GoogleDriveChunker(BaseChunker):
|
||||
"""Chunker for google drive folder."""
|
||||
|
||||
def __init__(self, config: Optional[ChunkerConfig] = None):
|
||||
if config is None:
|
||||
config = ChunkerConfig(chunk_size=1000, chunk_overlap=0, length_function=len)
|
||||
text_splitter = RecursiveCharacterTextSplitter(
|
||||
chunk_size=config.chunk_size,
|
||||
chunk_overlap=config.chunk_overlap,
|
||||
length_function=config.length_function,
|
||||
)
|
||||
super().__init__(text_splitter)
|
||||