Compare commits

...

74 Commits

Author SHA1 Message Date
Deshraj Yadav 29bd038579 [Bug fix] Fix missing dependency issue with gmail (#862) 2023-10-27 20:02:03 -07:00
Deshraj Yadav f6c4f86986 [Pipelines] Improvements in pipelines feature (#861) 2023-10-27 18:42:46 -07:00
Deven Patel 68183e9dce [Feature] Gmail Loader (#841) 2023-10-27 18:05:08 -07:00
Deshraj Yadav 78ec91a3a9 [Bug fix] Fix sqlite related issue with api server example (#857) 2023-10-26 21:54:45 -07:00
Deven Patel c95d458e52 Add tests for gpt4all llm (#852) 2023-10-26 20:41:28 -07:00
Deshraj Yadav 191ae3ec1e Update README (#855) 2023-10-26 11:11:05 -07:00
Deshraj Yadav ab9598d00a Update version to v0.0.77 (#851) 2023-10-26 09:51:51 -07:00
Deven Patel 0f8a2e624a [Improvement] Add support for gpt4all through langchain (#838) 2023-10-25 22:25:00 -07:00
Deven Patel d77e8da3f3 [Feature] Update db.query to return source of context (#831) 2023-10-25 22:20:32 -07:00
Sidharth Mohanty a27eeb3255 [Bug fix] import App shouldn't throw other llm deps errors (#837) 2023-10-25 20:48:53 -07:00
Deshraj Yadav 413ccb83e6 [Bug fix] Fix issues related to creating pipelines (#850) 2023-10-25 20:26:58 -07:00
Deven Patel 797bb567c6 [feat]: Add openapi spec data loader (#818) 2023-10-25 14:19:13 -07:00
Deshraj Yadav f2a5dc40ee Update package version to v0.0.76 (#849) 2023-10-25 13:40:00 -07:00
Deshraj Yadav 3979480532 [Feature] Add support for deploying local pipelines to Embedchain platform (#847) 2023-10-25 13:36:24 -07:00
Abhinesh 76f1993e7a Update CONTRIBUTING.md (#845) 2023-10-25 13:31:39 -07:00
Deshraj Yadav d783fa2b89 [chore]: Add poetry lock file (#848) 2023-10-25 12:53:06 -07:00
Sidharth Mohanty bbce18caac [Bug fix] reset() erases everything from db (#844) 2023-10-25 10:22:20 -07:00
Deshraj Yadav 3ce2d8a656 Bump version to v0.0.75 (#836) 2023-10-19 21:06:49 -07:00
Deshraj Yadav a5c86a2f5c [Bugfix]: Fix issue of context overspilling into other apps (#835) 2023-10-19 17:46:33 -07:00
Deshraj Yadav d18e533adf [Feature] Setup base for creating pipelines in embedchain (#834) 2023-10-19 17:46:15 -07:00
Sidharth Mohanty 2b881aaad0 Cache dependencies in CI (#832) 2023-10-19 13:59:02 -07:00
Sidharth Mohanty 39cc07608f [chore] Update repl links to launch main.py directly (#830) 2023-10-19 13:53:07 -07:00
Sidharth Mohanty 9894cfcced [docs] add links to example repositories (#833) 2023-10-19 13:51:08 -07:00
Sidharth Mohanty b5d80be037 Remove person_app, open_source app, llama2_app with their configs (#829) 2023-10-19 01:13:52 -07:00
Sidharth Mohanty b7870fbd9b [Bug fix] Table content alignment in example docs table (#828) 2023-10-18 21:38:31 -07:00
Sidharth Mohanty 36e6d486fc [chore] Remove image.jpg produced by tests and add cleanup in test (#827) 2023-10-18 21:38:00 -07:00
Sidharth Mohanty 2d5dc84f1a [chore] Update LLM YAML config docs (#826) 2023-10-18 21:37:45 -07:00
Deshraj Yadav b47405e1bd Update version to v0.0.74 (#825) 2023-10-18 17:12:51 -07:00
Muhammad Muzammil 8b64deab40 [Feature]: Unstructured File Loader Support - USF (#815) 2023-10-18 16:43:41 -07:00
Rupesh Bansal c8846e0e93 [Feature] Add Qdrant support (#822) 2023-10-18 14:27:57 -07:00
Deven Patel 7641cba01d [Feature] JSON data loader support (#816) 2023-10-18 13:53:15 -07:00
Sidharth Mohanty 4dc1785ef1 [docs] Examples table with notebooks and replit links (#823) 2023-10-18 10:29:41 -07:00
Sidharth Mohanty b2286f3e34 Google Colab Notebooks for LLMs, Embedders and VectorDBs (#821) 2023-10-18 09:04:06 -07:00
Sidharth Mohanty 65a20aa457 [Bug fix] Anthropic, Llama2 and VertexAI LLMs dependencies (#820) 2023-10-18 01:10:46 -07:00
Rupesh Bansal d8a7d71344 [Feature] Batch uploading in chromadb (#814) 2023-10-17 22:22:29 -07:00
Deshraj Yadav bb490df9a6 Bump version to v0.0.73 (#819) 2023-10-17 22:19:22 -07:00
Rupesh Bansal cdfd6519c8 [Feature] Add support for weaviate vector db (#782) 2023-10-17 22:18:53 -07:00
Sidharth Mohanty e8a2846449 Improve and add more tests (#807) 2023-10-17 14:06:47 -07:00
Sidharth Mohanty d065cbf934 [Bug fix] Qna pair not loading properly (#817) 2023-10-17 11:34:03 -07:00
Sidharth Mohanty 413b107b9a Update dependencies for fast installation (#811) 2023-10-17 08:21:30 -07:00
Deshraj Yadav c336292346 Update version to v0.0.72 (#809) 2023-10-16 13:33:36 -07:00
Deshraj Yadav adf50f1e81 [Docs] Add docs for Azure OpenAI provider (#804) 2023-10-16 13:31:56 -07:00
Deshraj Yadav 636bc0a99d [feature]: Improve pinecone db integration (#806) 2023-10-15 02:26:35 -07:00
Rupesh Bansal a7a61fae1d [Feature] Pinecone Vector DB support (#723) 2023-10-15 01:54:07 -07:00
Sidharth Mohanty 5ec12212e4 Improve tests (#800) 2023-10-14 19:16:27 -07:00
Deshraj Yadav 77c90a308e [Docs]: Clean up docs (#802) 2023-10-14 19:14:24 -07:00
Deshraj Yadav 4a8c50f886 [docs]: Revamp embedchain docs (#799) 2023-10-13 15:38:15 -07:00
Deshraj Yadav a86d7f52e9 [Feature]: Add support for creating app using yaml config (#787) 2023-10-12 15:35:49 -07:00
Sidharth Mohanty 4820ea15d6 Improve tests (#795) 2023-10-12 13:15:22 -07:00
Deshraj Yadav b5de605e2b Update version to 0.0.69 (#792) 2023-10-11 13:20:59 -07:00
LuciAkirami d6ed2050d4 feature: Add support for zilliz vector database (#771) 2023-10-11 13:17:33 -07:00
Deshraj Yadav 16e123b7bb [docs]: add telemetry information in readme (#786) 2023-10-09 13:02:55 -07:00
Deshraj Yadav 4eb91683a9 Bump version to 0.0.68 (#785) 2023-10-09 12:41:30 -07:00
Sidharth Mohanty 0cb78b9067 Add Hugging Face Hub LLM support (#762) 2023-10-09 12:15:22 -07:00
Sidharth Mohanty e226a89637 Add Jina LLM support (#760) 2023-10-09 12:06:36 -07:00
SerSamgy 431f8c2c6a Feat: Improve test coverage of DocsSiteLoader (#758) 2023-10-09 12:03:40 -07:00
Rupesh Bansal 19a9141c2d Added Clip dependency (#778) 2023-10-09 12:02:45 -07:00
Rupesh Bansal bc649b9a85 Added docs for skip_embedding and embeddings argument of vectordbs (#784) 2023-10-09 12:01:44 -07:00
Shreya Shrivastava 702067e521 Improve user readability of .env.example (#781) 2023-10-09 12:01:23 -07:00
Sidharth Mohanty 03a84daf9d Add Cohere LLM support (#751) 2023-10-09 11:54:24 -07:00
Sidharth Mohanty b91d922600 Improve tests (#780) 2023-10-09 11:26:21 -07:00
Prikshit ed02aebf9a Rename 'PersonApp.py' to 'person_app.py' (#752) 2023-10-09 08:05:11 -07:00
Prikshit 1a048390fd Rename _get_athrophic_answer to _get_answer (#775) 2023-10-07 02:22:49 -07:00
Richard Awoyemi 1741d3bef6 [fix]: Fix sitemap loader (#753) 2023-10-06 16:24:15 -07:00
Ojuswi Rastogi 540a0a3685 [feat]: Add support for XML file format (#757) 2023-10-06 15:39:32 -07:00
SerSamgy d2fd3ce434 [tests]: add more tests for pdf_file loader (#769) 2023-10-06 14:10:45 -07:00
Deshraj Yadav ea76868d65 [docs]: update readme (#767) 2023-10-04 18:14:16 -07:00
Deshraj Yadav f31351bedb [OpenSearch] Small bug fixes in query 2023-10-04 18:07:46 -07:00
Deshraj Yadav 8863983c7b [Images] Remove 'clip' from the list of depdencies since pypi doesn't allow it (#766) 2023-10-04 17:08:27 -07:00
Deshraj Yadav 64a34cac32 [OpenSearch] Add chunks specific to an app_id if present (#765) 2023-10-04 15:46:22 -07:00
Deshraj Yadav 352e71461d [OpenSearch]: Fix add() and query() for opensearch db (#764) 2023-10-04 12:53:07 -07:00
Deshraj Yadav 87d0b5c76f [bugfix] Fix issue when llm config is not defined (#763) 2023-10-04 12:08:21 -07:00
Rupesh Bansal d0af018b8d Add support for image dataset (#571)
Co-authored-by: Rupesh Bansal <rupeshbansal@Shankars-MacBook-Air.local>
2023-10-04 09:50:40 +05:30
Taranjeet Singh 55e9a1cbd6 fix: update notebook link and link in example (#748) 2023-10-01 04:43:26 +05:30
204 changed files with 18115 additions and 1957 deletions
+1 -1
View File
@@ -1 +1 @@
OPENAI_API_KEY=
OPENAI_API_KEY="your-openai-api-key"
+2 -2
View File
@@ -23,10 +23,10 @@ jobs:
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: poetry install
- name: Build a binary wheel and a source tarball
run: poetry build
+14 -6
View File
@@ -19,14 +19,23 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install poetry
run: pip install poetry==1.4.2
uses: snok/install-poetry@v1
with:
version: 1.4.2
virtualenvs-create: true
virtualenvs-in-project: true
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v2
with:
path: .venv
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
run: poetry install --all-extras
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
- name: Lint with ruff
run: make ci_lint
- name: Test with pytest
run: make ci_test
- name: Generate coverage report
run: make lint
- name: Run tests and generate coverage report
run: make coverage
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
@@ -34,4 +43,3 @@ jobs:
file: coverage.xml
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+7 -2
View File
@@ -76,7 +76,7 @@ docs/_build/
target/
# Jupyter Notebook
.ipynb_checkpoints
*.yaml
# IPython
profile_default/
@@ -165,9 +165,14 @@ cython_debug/
# Database
db
test-db
.vscode
/poetry.lock
.idea/
.DS_Store
notebooks/*.yaml
.ipynb_checkpoints/
!configs/*.yaml
+4 -4
View File
@@ -1,10 +1,10 @@
# Contributing to embedchain
Let us make contributing easy, collaborative and fun.
Let us make contribution easy, collaborative and fun.
## Submit your Contribution through PR
To make a contribution, follow the following steps:
To make a contribution, follow these steps:
1. Fork and clone this repository
2. Do the changes on your fork with dedicated feature branch `feature/f1`
@@ -35,7 +35,7 @@ poetry shell
### 📌 Pre-commit
To ensure our standards, make sure to install pre-commit before star to contribute.
To ensure our standards, make sure to install pre-commit before starting to contribute.
```bash
pre-commit install
@@ -51,7 +51,7 @@ make lint
Make sure that the linter does not report any errors or warnings before submitting a pull request.
### Code Format with `black`
### Code Formatting with `black`
We use `black` to reformat the code by running the following command:
+9 -9
View File
@@ -9,12 +9,18 @@ PROJECT_NAME := embedchain
install:
poetry install
install_all:
poetry install --all-extras
install_es:
poetry install --extras elasticsearch
install_opensearch:
poetry install --extras opensearch
install_milvus:
poetry install --extras milvus
shell:
poetry shell
@@ -25,20 +31,14 @@ format:
$(PYTHON) -m black .
$(PYTHON) -m isort .
lint:
$(PYTHON) -m ruff .
clean:
rm -rf dist build *.egg-info
test:
$(PYTHON) -m pytest
ci_lint:
lint:
poetry run ruff .
ci_test:
poetry run pytest
test:
poetry run pytest $(file)
coverage:
poetry run pytest --cov=$(PROJECT_NAME) --cov-report=xml
+50 -8
View File
@@ -1,5 +1,7 @@
# embedchain
<a href="https://runacap.com/ross-index/q3-2023/" target="_blank" rel="noopener"><img style="width: 260px; height: 56px" src="https://runacap.com/wp-content/uploads/2023/10/ROSS_badge_black_Q3_2023.svg" alt="ROSS Index - Fastest Growing Open-Source Startups in Q3 2023 | Runa Capital" width="260" height="56"/></a>
[![PyPI](https://img.shields.io/pypi/v/embedchain)](https://pypi.org/project/embedchain/)
[![Slack](https://img.shields.io/badge/slack-embedchain-brightgreen.svg?logo=slack)](https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw)
[![Discord](https://dcbadge.vercel.app/api/server/6PzXDgEjG5?style=flat)](https://discord.gg/CUU9FPhRNt)
@@ -8,7 +10,7 @@
[![Open in Colab](https://camo.githubusercontent.com/84f0493939e0c4de4e6dbe113251b4bfb5353e57134ffd9fcab6b8714514d4d1/68747470733a2f2f636f6c61622e72657365617263682e676f6f676c652e636f6d2f6173736574732f636f6c61622d62616467652e737667)](https://colab.research.google.com/drive/138lMWhENGeEu7Q1-6lNbNTHGLZXBBz_B?usp=sharing)
[![codecov](https://codecov.io/gh/embedchain/embedchain/graph/badge.svg?token=EMRRHZXW1Q)](https://codecov.io/gh/embedchain/embedchain)
Embedchain is a framework to easily create LLM powered bots over any dataset. If you want a javascript version, check out [embedchain-js](https://github.com/embedchain/embedchain/tree/main/embedchain-js)
Embedchain is a Data Platform for LLMs - load, index, retrieve, and sync any unstructured data. Using embedchain, you can easily create LLM powered apps over any data. If you want a javascript version, check out [embedchain-js](https://github.com/embedchain/embedchain/tree/main/embedchain-js)
## Community
@@ -28,7 +30,7 @@ pip install --upgrade embedchain
Try out embedchain in your browser:
[![Open in Colab](https://camo.githubusercontent.com/84f0493939e0c4de4e6dbe113251b4bfb5353e57134ffd9fcab6b8714514d4d1/68747470733a2f2f636f6c61622e72657365617263682e676f6f676c652e636f6d2f6173736574732f636f6c61622d62616467652e737667)](https://colab.research.google.com/drive/138lMWhENGeEu7Q1-6lNbNTHGLZXBBz_B?usp=sharing)
[![Open in Colab](https://camo.githubusercontent.com/84f0493939e0c4de4e6dbe113251b4bfb5353e57134ffd9fcab6b8714514d4d1/68747470733a2f2f636f6c61622e72657365617263682e676f6f676c652e636f6d2f6173736574732f636f6c61622d62616467652e737667)](https://colab.research.google.com/drive/17ON1LPonnXAtLaZEebnOktstB_1cJJmh?usp=sharing)
## 📖 Documentation
@@ -36,17 +38,25 @@ The documentation for embedchain can be found at [docs.embedchain.ai](https://do
## 💻 Usage
Embedchain empowers you to create chatbot models similar to ChatGPT, using your own evolving dataset.
Embedchain empowers you to create ChatGPT like apps, on your own dynamic dataset.
### Data Types Supported
### Data types supported
* Youtube video
* PDF file
* CSV file
* Web page
* MDX file
* XML file
* Sitemap
* Doc file
* Code documentation website loader
* Notion
* JSON file
* OpenAPI specs
* Code docs website
* Unstructured file loader and many more
You can find the full list of data types on [our documentation](https://docs.embedchain.ai/data-sources/).
### Queries
@@ -63,13 +73,41 @@ elon_bot = App()
# Embed online resources
elon_bot.add("https://en.wikipedia.org/wiki/Elon_Musk")
elon_bot.add("https://www.forbes.com/profile/elon-musk")
elon_bot.add("https://www.youtube.com/watch?v=MxZpaJK74Y4")
elon_bot.add("https://www.youtube.com/watch?v=RcYjXbSJBN8")
# Query the bot
elon_bot.query("How many companies does Elon Musk run and name those?")
# Answer: Elon Musk currently runs several companies. As of my knowledge, he is the CEO and lead designer of SpaceX, the CEO and product architect of Tesla, Inc., the CEO and founder of Neuralink, and the CEO and founder of The Boring Company. However, please note that this information may change over time, so it's always good to verify the latest updates.
```
## Examples
| LLM | Google Colab | Replit |
|--------------|---------------|----------|
| OpenAI | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/openai.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/openai#main.py) |
| Anthropic | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/anthropic.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/anthropic#main.py) |
| Azure OpenAI | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/azure-openai.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/azureopenai#main.py) |
| VertexAI | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/vertex_ai.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/vertexai#main.py) |
| Cohere | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/cohere.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/cohere#main.py) |
| Hugging Face | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/hugging_face_hub.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/huggingface#main.py) |
| JinaChat | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/jina.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/jina#main.py) |
| GPT4All | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/gpt4all.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/gpt4all#main.py) |
| Llama2 | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/llama2.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/llama2#main.py) |
| Embedding model | Google Colab | Replit |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| OpenAI | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/openai.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/openai#main.py) |
| VertexAI | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/vertex_ai.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/vertexai#main.py) |
| GPT4All | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/gpt4all.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/gpt4all#main.py) |
| Hugging Face | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/hugging_face_hub.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/huggingface#main.py) |
| Vector DB | Google Colab | Replit |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| ChromaDB | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/chromadb.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/chromadb#main.py) |
| Elasticsearch | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/elasticsearch.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/elasticsearchdb#main.py) |
| Opensearch | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/opensearch.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/opensearchdb#main.py) |
| Pinecone | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/pinecone.ipynb) | [![Try with Replit Badge](https://replit.com/badge?caption=Try%20with%20Replit&variant=small)](https://replit.com/@taranjeetio/pineconedb#main.py) |
## 🤝 Contributing
Contributions are welcome! Please check out the issues on the repository, and feel free to open a pull request.
@@ -81,14 +119,18 @@ For more reference, please go through [Development Guide](https://docs.embedchai
<img src="https://contrib.rocks/image?repo=embedchain/embedchain" />
</a>
## Telemetry
We collect anonymous usage metrics to enhance our package's quality and user experience. This includes data like feature usage frequency and system info, but never personal details. The data helps us prioritize improvements and ensure compatibility. If you wish to opt-out, set the `app.config.collect_metrics = False` in the code. We prioritize data security and don't share this data externally.
## Citation
If you utilize this repository, please consider citing it with:
```
@misc{embedchain,
author = {Taranjeet Singh},
title = {Embedchain: Framework to easily create LLM powered bots over any dataset},
author = {Taranjeet Singh, Deshraj Yadav},
title = {Embedchain: Data platform for LLMs - load, index, retrieve, and sync any unstructured data},
year = {2023},
publisher = {GitHub},
journal = {GitHub repository},
+8
View File
@@ -0,0 +1,8 @@
llm:
provider: anthropic
model: 'claude-instant-1'
config:
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
+19
View File
@@ -0,0 +1,19 @@
app:
config:
id: azure-openai-app
llm:
provider: azure_openai
model: gpt-35-turbo
config:
deployment_name: your_llm_deployment_name
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
embedder:
provider: azure_openai
config:
model: text-embedding-ada-002
deployment_name: you_embedding_model_deployment_name
+26
View File
@@ -0,0 +1,26 @@
app:
config:
id: 'my-app'
collection_name: 'my-app'
llm:
provider: openai
model: 'gpt-3.5-turbo'
config:
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
vectordb:
provider: chroma
config:
collection_name: 'my-app'
dir: db
allow_reset: true
embedder:
provider: openai
config:
model: 'text-embedding-ada-002'
deployment_name: null
+7
View File
@@ -0,0 +1,7 @@
llm:
provider: cohere
model: large
config:
temperature: 0.5
max_tokens: 1000
top_p: 1
+35
View File
@@ -0,0 +1,35 @@
app:
config:
id: 'full-stack-app'
llm:
provider: openai
model: 'gpt-3.5-turbo'
config:
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
template: |
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.
$context
Query: $query
Helpful Answer:
system_prompt: |
Act as William Shakespeare. Answer the following questions in the style of William Shakespeare.
vectordb:
provider: chroma
config:
collection_name: 'my-collection-name'
dir: db
allow_reset: true
embedder:
provider: openai
config:
model: 'text-embedding-ada-002'
+11
View File
@@ -0,0 +1,11 @@
llm:
provider: gpt4all
config:
model: 'orca-mini-3b.ggmlv3.q4_0.bin'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
embedder:
provider: gpt4all
+8
View File
@@ -0,0 +1,8 @@
llm:
provider: huggingface
model: 'google/flan-t5-xxl'
config:
temperature: 0.5
max_tokens: 1000
top_p: 0.5
stream: false
+7
View File
@@ -0,0 +1,7 @@
llm:
provider: jina
config:
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
+8
View File
@@ -0,0 +1,8 @@
llm:
provider: llama2
model: 'a16z-infra/llama13b-v2-chat:df7690f1994d94e96ad9d568eac121aecf50684a0b0963b25a41cc40061269e5'
config:
temperature: 0.5
max_tokens: 1000
top_p: 0.5
stream: false
+33
View File
@@ -0,0 +1,33 @@
app:
config:
id: 'my-app'
log_level: 'WARN'
collect_metrics: true
collection_name: 'my-app'
llm:
provider: openai
model: 'gpt-3.5-turbo'
config:
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
vectordb:
provider: opensearch
config:
opensearch_url: 'https://localhost:9200'
http_auth:
- admin
- admin
vector_dimension: 1536
collection_name: 'my-app'
use_ssl: false
verify_certs: false
embedder:
provider: openai
config:
model: 'text-embedding-ada-002'
deployment_name: null
+26
View File
@@ -0,0 +1,26 @@
app:
config:
id: 'open-source-app'
collection_name: 'open-source-app'
collect_metrics: false
llm:
provider: gpt4all
config:
model: 'orca-mini-3b.ggmlv3.q4_0.bin'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
vectordb:
provider: chroma
config:
collection_name: 'open-source-app'
dir: db
allow_reset: true
embedder:
provider: gpt4all
config:
deployment_name: null
+6
View File
@@ -0,0 +1,6 @@
vectordb:
provider: pinecone
config:
metric: cosine
vector_dimension: 1536
collection_name: my-pinecone-index
+26
View File
@@ -0,0 +1,26 @@
pipeline:
config:
name: Example pipeline
id: pipeline-1 # Make sure that id is different every time you create a new pipeline
vectordb:
provider: chroma
config:
collection_name: pipeline-1
dir: db
allow_reset: true
llm:
provider: gpt4all
config:
model: 'orca-mini-3b.ggmlv3.q4_0.bin'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
embedding_model:
provider: gpt4all
config:
model: 'all-MiniLM-L6-v2'
deployment_name: null
+6
View File
@@ -0,0 +1,6 @@
llm:
provider: vertexai
model: 'chat-bison'
config:
temperature: 0.5
top_p: 0.5
+4
View File
@@ -0,0 +1,4 @@
vectordb:
provider: weaviate
config:
collection_name: my_weaviate_index
+10
View File
@@ -0,0 +1,10 @@
install:
npm i -g mintlify
run_local:
mintlify dev
troubleshoot:
mintlify install
.PHONY: install run_local troubleshoot
+11
View File
@@ -0,0 +1,11 @@
<CardGroup cols={3}>
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
Join our slack community
</Card>
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
Join our discord community
</Card>
<Card title="Schedule a call" icon="calendar" href="https://cal.com/taranjeetio/ec">
Schedule a call with Embedchain founder
</Card>
</CardGroup>
@@ -0,0 +1,18 @@
<Tip>
If you can't find the specific data source, please feel free to request through one of the following channels and help us prioritize.
<CardGroup cols={2}>
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
Let us know on our slack community
</Card>
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
Let us know on discord community
</Card>
<Card title="GitHub" icon="github" href="https://github.com/embedchain/embedchain/issues/new?assignees=&labels=&projects=&template=feature_request.yml" color="#181717">
Open an issue on our GitHub
</Card>
<Card title="Schedule a call" icon="calendar" href="https://cal.com/taranjeetio/ec">
Schedule a call with Embedchain founder
</Card>
</CardGroup>
</Tip>
+18
View File
@@ -0,0 +1,18 @@
<Tip>
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.
<CardGroup cols={2}>
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
Let us know on our slack community
</Card>
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
Let us know on discord community
</Card>
<Card title="GitHub" icon="github" href="https://github.com/embedchain/embedchain/issues/new?assignees=&labels=&projects=&template=feature_request.yml" color="#181717">
Open an issue on our GitHub
</Card>
<Card title="Schedule a call" icon="calendar" href="https://cal.com/taranjeetio/ec">
Schedule a call with Embedchain founder
</Card>
</CardGroup>
</Tip>
+18
View File
@@ -0,0 +1,18 @@
<Tip>
If you can't find the specific vector database, please feel free to request through one of the following channels and help us prioritize.
<CardGroup cols={2}>
<Card title="Slack" icon="slack" href="https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw" color="#4A154B">
Let us know on our slack community
</Card>
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
Let us know on discord community
</Card>
<Card title="GitHub" icon="github" href="https://github.com/embedchain/embedchain/issues/new?assignees=&labels=&projects=&template=feature_request.yml" color="#181717">
Open an issue on our GitHub
</Card>
<Card title="Schedule a call" icon="calendar" href="https://cal.com/taranjeetio/ec">
Schedule a call with Embedchain founder
</Card>
</CardGroup>
</Tip>
-213
View File
@@ -1,213 +0,0 @@
---
title: '📱 App types'
---
## App Types
Embedchain supports a variety of LLMs, embedding functions/models and vector databases.
Our app gives you full control over which components you want to use, you can mix and match them to your hearts content.
<Tip>
Out of the box, if you just use `app = App()`, Embedchain uses what we believe to be the best configuration available. This might include paid/proprietary components. Currently, this is
* LLM: OpenAi (gpt-3.5-turbo)
* Embedder: OpenAi (text-embedding-ada-002)
* Database: ChromaDB
</Tip>
### LLM
#### Choosing an LLM
The following LLM providers are supported by Embedchain:
- OPENAI
- ANTHPROPIC
- VERTEX_AI
- GPT4ALL
- AZURE_OPENAI
- LLAMA2
You can choose one by importing it from `embedchain.llm`. E.g.:
```python
from embedchain import App
from embedchain.llm.llama2 import Llama2Llm
app = App(llm=Llama2Llm())
```
#### Configuration
The LLMs can be configured by passing an LlmConfig object.
The config options can be found [here](/advanced/query_configuration#llmconfig)
```python
from embedchain import App
from embedchain.llm.llama2 import Llama2Llm
from embedchain.config import LlmConfig
app = App(llm=Llama2Llm(), llm_config=LlmConfig(number_documents=3, temperature=0))
```
### Embedder
#### Choosing an Embedder
The following providers for embedding functions are supported by Embedchain:
- OPENAI
- HUGGING_FACE
- VERTEX_AI
- GPT4ALL
- AZURE_OPENAI
You can choose one by importing it from `embedchain.embedder`. E.g.:
```python
from embedchain import App
from embedchain.embedder.vertexai import VertexAiEmbedder
app = App(embedder=VertexAiEmbedder())
```
#### Configuration
The LLMs can be configured by passing an EmbedderConfig object.
```python
from embedchain import App
from embedchain.embedder.openai import OpenAiEmbedder
from embedchain.config import EmbedderConfig
app = App(embedder=OpenAiEmbedder(), embedder_config=EmbedderConfig(model="text-embedding-ada-002"))
```
<Tip>
You can also pass an `LlmConfig` instance directly to the `query` or `chat` method.
This creates a temporary config for that request alone, so you could, for example, use a different model (from the same provider) or get more context documents for a specific query.
</Tip>
### Vector Database
#### Choosing a Vector Database
The following vector databases are supported by Embedchain:
- ChromaDB
- Elasticsearch
You can choose one by importing it from `embedchain.vectordb`. E.g.:
```python
from embedchain import App
from embedchain.vectordb.elasticsearch import ElasticsearchDB
app = App(db=ElasticsearchDB())
```
#### Configuration
The vector databases can be configured by passing a specific config object.
These vary greatly between the different vector databases.
```python
from embedchain import App
from embedchain.vectordb.elasticsearch import ElasticsearchDB
from embedchain.config import ElasticsearchDBConfig
app = App(db=ElasticsearchDB(), db_config=ElasticsearchDBConfig())
```
### PersonApp
```python
from embedchain import PersonApp
naval_chat_bot = PersonApp("name_of_person_or_character") #Like "Yoda"
```
- `PersonApp` uses OpenAI's model, so these are paid models. 💸 You will be charged for embedding model usage and LLM usage.
- `PersonApp` uses OpenAI's embedding model to create embeddings for chunks and ChatGPT API as LLM to get answer given the relevant docs. Make sure that you have an OpenAI account and an API key. If you don't have an API key, you can create one by visiting [this link](https://platform.openai.com/account/api-keys).
- Once you have the API key, set it in an environment variable called `OPENAI_API_KEY`
```python
import os
os.environ["OPENAI_API_KEY"] = "sk-xxxx"
```
### Full Configuration Examples
Embedchain previously offered fully configured classes, namely `App`, `OpenSourceApp`, `CustomApp` and `Llama2App`.
We deprecated these apps. The reason for this decision was that it was hard to switch from to a different LLM, embedder or vector db, if you one day decided that that's what you want to do.
The new app allows drop-in replacements, such as changing `App(llm=OpenAiLlm())` to `App(llm=Llama2Llm())`.
To make the switch to our new, fully configurable app easier, we provide you with full examples for what the old classes would look like implemented as a new app.
You can swap these in, and if you decide you want to try a different model one day, you don't have to rewrite your whole bot.
#### App
App without any configuration is still using the best options available, so you can keep using:
```python
from embedchain import App
app = App()
```
#### OpenSourceApp
Use this snippet to run an open source app.
```python
from embedchain import App
from embedchain.llm.gpt4all import GPT4ALLLlm
from embedchain.embedder.gpt4all import GPT4AllEmbedder
from embedchain.vectordb.chroma import ChromaDB
app = App(llm=GPT4ALLLlm(), embedder=GPT4AllEmbedder(), db=ChromaDB())
```
#### Llama2App
```python
from embedchain import App
from embedchain.llm.llama2 import Llama2Llm
app = App(llm=Llama2Llm())
```
#### CustomApp
Every app is a custom app now.
If you were previously using a `CustomApp`, you can now just change it to `App`.
Here's one example, what you could do if we combined everything shown on this page.
```python
from embedchain import App
from embedchain.config import ElasticsearchDBConfig, EmbedderConfig, LlmConfig
from embedchain.embedder.openai import OpenAiEmbedder
from embedchain.llm.llama2 import Llama2Llm
from embedchain.vectordb.elasticsearch import ElasticsearchDB
app = App(
llm=Llama2Llm(),
llm_config=LlmConfig(number_documents=3, temperature=0),
embedder=OpenAiEmbedder(),
embedder_config=EmbedderConfig(model="text-embedding-ada-002"),
db=ElasticsearchDB(),
db_config=ElasticsearchDBConfig(),
)
```
### Compatibility with other apps
- If there is any other app instance in your script or app, you can change the import as
```python
from embedchain import App as EmbedChainApp
from embedchain import PersonApp as EmbedChainPersonApp
# or
from embedchain import App as ECApp
from embedchain import PersonApp as ECPApp
```
+57 -86
View File
@@ -4,101 +4,72 @@ title: '⚙️ Custom configurations'
Embedchain is made to work out of the box. However, for advanced users we're also offering configuration options. All of these configuration options are optional and have sane defaults.
## Concept
The main `App` class is available in the following varieties: `CustomApp`, `OpenSourceApp` and `Llama2App` and `App`. The first is fully configurable, the others are opinionated in some aspects.
You can configure different components of your app (`llm`, `embedding model`, or `vector database`) through a simple yaml configuration that Embedchain offers. Here is a generic full-stack example of the yaml config:
The `App` class has three subclasses: `llm`, `db` and `embedder`. These are the core ingredients that make up an EmbedChain app.
App plus each one of the subclasses have a `config` attribute.
You can pass a `Config` instance as an argument during initialization to persistently configure a class.
These configs can be imported from `embedchain.config`
```yaml
app:
config:
id: 'full-stack-app'
There are `set` methods for some things that should not (only) be set at start-up, like `app.db.set_collection_name`.
llm:
provider: openai
config:
model: 'gpt-3.5-turbo'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
template: |
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.
## Examples
$context
### General
Query: $query
Here's the readme example with configuration options.
Helpful Answer:
system_prompt: |
Act as William Shakespeare. Answer the following questions in the style of William Shakespeare.
```python
from embedchain import App
from embedchain.config import AppConfig, AddConfig, LlmConfig, ChunkerConfig
vectordb:
provider: chroma
config:
collection_name: 'full-stack-app'
dir: db
allow_reset: true
# Example: set the log level for debugging
config = AppConfig(log_level="DEBUG")
naval_chat_bot = App(config)
# Example: specify a custom collection name
naval_chat_bot.db.set_collection_name("naval_chat_bot")
# Example: define your own chunker config for `youtube_video`
chunker_config = ChunkerConfig(chunk_size=1000, chunk_overlap=100, length_function=len)
# Example: Add your chunker config to an AddConfig to actually use it
add_config = AddConfig(chunker=chunker_config)
naval_chat_bot.add("https://www.youtube.com/watch?v=3qHkcs3kG44", config=add_config)
# Example: Reset to default
add_config = AddConfig()
naval_chat_bot.add("https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf", config=add_config)
naval_chat_bot.add("https://nav.al/feedback", config=add_config)
naval_chat_bot.add("https://nav.al/agi", config=add_config)
naval_chat_bot.add(("Who is Naval Ravikant?", "Naval Ravikant is an Indian-American entrepreneur and investor."), config=add_config)
# Change the number of documents.
query_config = LlmConfig(number_documents=5)
print(naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?", config=query_config))
embedder:
provider: openai
config:
model: 'text-embedding-ada-002'
```
### Custom prompt template
Alright, let's dive into what each key means in the yaml config above:
Here's the example of using custom prompt template with `.query`
1. `app` Section:
- `config`:
- `id` (String): The ID or name of your full-stack application.
2. `llm` Section:
- `provider` (String): The provider for the language model, which is set to 'openai'. You can find the full list of llm providers in [our docs](/components/llms).
- `model` (String): The specific model being used, 'gpt-3.5-turbo'.
- `config`:
- `temperature` (Float): Controls the randomness of the model's output. A higher value (closer to 1) makes the output more random.
- `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.
- `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.
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`:
- `collection_name` (String): The initial collection name for the database, set to 'full-stack-app'.
- `dir` (String): The directory for the database, set to 'db'.
- `allow_reset` (Boolean): Indicates whether resetting the database is allowed, set to true.
4. `embedder` Section:
- `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'.
```python
from string import Template
If you have questions about the configuration above, please feel free to reach out to us using one of the following methods:
import wikipedia
from embedchain import App
from embedchain.config import LlmConfig
einstein_chat_bot = App()
# Embed Wikipedia page
page = wikipedia.page("Albert Einstein")
einstein_chat_bot.add(page.content)
# Example: use your own custom template with `$context` and `$query`
einstein_chat_template = Template(
"""
You are Albert Einstein, a German-born theoretical physicist,
widely ranked among the greatest and most influential scientists of all time.
Use the following information about Albert Einstein to respond to
the human's query acting as Albert Einstein.
Context: $context
Keep the response brief. If you don't know the answer, just say that you don't know, don't try to make up an answer.
Human: $query
Albert Einstein:"""
)
# Example: Use the template, also add a system prompt.
llm_config = LlmConfig(template=einstein_chat_template, system_prompt="You are Albert Einstein.")
queries = [
"Where did you complete your studies?",
"Why did you win nobel prize?",
"Why did you divorce your first wife?",
]
for query in queries:
response = einstein_chat_bot.query(query, config=llm_config)
print("Query: ", query)
print("Response: ", response)
# Output
# Query: Where did you complete your studies?
# Response: I completed my secondary education at the Argovian cantonal school in Aarau, Switzerland.
# Query: Why did you win nobel prize?
# Response: I won the Nobel Prize in Physics in 1921 for my services to Theoretical Physics, particularly for my discovery of the law of the photoelectric effect.
# Query: Why did you divorce your first wife?
# Response: We divorced due to living apart for five years.
```
<Snippet file="get-help.mdx" />
-75
View File
@@ -1,75 +0,0 @@
---
title: '🤝 Interface types'
---
## Interface Types
The embedchain app exposes the following methods.
### Query Interface
- This interface is like a question answering bot. It takes a question and gets the answer. It does not maintain context about the previous chats.❓
- To use this, call `.query()` function to get the answer for any query.
```python
print(naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?"))
# answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
```
### Chat Interface
- This interface is a chat interface that remembers previous conversations. Right now it remembers 5 conversations by default. 💬
- To use this, call `.chat` function to get the answer for any query.
```python
print(naval_chat_bot.chat("How to be happy in life?"))
# answer: The most important trick to being happy is to realize happiness is a skill you develop and a choice you make. You choose to be happy, and then you work at it. It's just like building muscles or succeeding at your job. It's about recognizing the abundance and gifts around you at all times.
print(naval_chat_bot.chat("who is naval ravikant?"))
# answer: Naval Ravikant is an Indian-American entrepreneur and investor.
print(naval_chat_bot.chat("what did the author say about happiness?"))
# answer: The author, Naval Ravikant, believes that happiness is a choice you make and a skill you develop. He compares the mind to the body, stating that just as the body can be molded and changed, so can the mind. He emphasizes the importance of being present in the moment and not getting caught up in regrets of the past or worries about the future. By being present and grateful for where you are, you can experience true happiness.
```
#### Dry Run
Dry Run is an option in the `add`, `query` and `chat` methods that allows the user to display the data chunks and their constructed prompt which is not sent to the LLM, to save money. It's used for [testing](/advanced/testing#dry-run).
### Stream Response
- You can add config to your query method to stream responses like ChatGPT does. You would require a downstream handler to render the chunk in your desirable format. Supports both OpenAI model and OpenSourceApp. 📊
- To use this, instantiate a `LlmConfig` or `ChatConfig` object with `stream=True`. Then pass it to the `.chat()` or `.query()` method. The following example iterates through the chunks and prints them as they appear.
```python
app = App()
query_config = LlmConfig(stream = True)
resp = app.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?", query_config)
for chunk in resp:
print(chunk, end="", flush=True)
# answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
```
### Other Methods
#### Reset
Resets the database and deletes all embeddings. Irreversible. Requires reinitialization afterwards.
```python
app.reset()
```
#### Count
Counts the number of embeddings (chunks) in the database.
```python
print(app.db.count())
# returns: 481
```
-79
View File
@@ -1,79 +0,0 @@
---
title: '🔍 Query configurations'
---
## AppConfig
| option | description | type | default |
|-----------|-----------------------|---------------------------------|------------------------|
| log_level | log level | string | WARNING |
| embedding_fn| embedding function | chromadb.utils.embedding_functions | \{text-embedding-ada-002\} |
| db | vector database (experimental) | BaseVectorDB | ChromaDB |
| collection_name | initial collection name for the database | string | embedchain_store |
| collect_metrics | collect anonymous telemetry data to improve embedchain | boolean | true |
## AddConfig
|option|description|type|default|
|---|---|---|---|
|chunker|chunker config|ChunkerConfig|Default values for chunker depends on the `data_type`. Please refer [ChunkerConfig](#chunker-config)|
|loader|loader config|LoaderConfig|None|
Yes, you are passing `ChunkerConfig` to `AddConfig`, like so:
```python
chunker_config = ChunkerConfig(chunk_size=100)
add_config = AddConfig(chunker=chunker_config)
app.add("lorem ipsum", config=add_config)
```
### ChunkerConfig
|option|description|type|default|
|---|---|---|---|
|chunk_size|Maximum size of chunks to return|int|Default value for various `data_type` mentioned below|
|chunk_overlap|Overlap in characters between chunks|int|Default value for various `data_type` mentioned below|
|length_function|Function that measures the length of given chunks|typing.Callable|Default value for various `data_type` mentioned below|
Default values of chunker config parameters for different `data_type`:
|data_type|chunk_size|chunk_overlap|length_function|
|---|---|---|---|
|docx|1000|0|len|
|text|300|0|len|
|qna_pair|300|0|len|
|web_page|500|0|len|
|pdf_file|1000|0|len|
|youtube_video|2000|0|len|
|docs_site|500|50|len|
|notion|300|0|len|
### LoaderConfig
_coming soon_
## LlmConfig
|option|description|type|default|
|---|---|---|---|
|number_documents|Absolute number of documents to pull from the database as context.|int|1
|template|custom template for prompt. If history is used with query, $history has to be included as well.|Template|Template("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. \$context Query: \$query Helpful Answer:")|
|model|name of the model used.|string|depends on app type|
|temperature|Controls the randomness of the model's output. Higher values (closer to 1) make output more random, lower values make it more deterministic.|float|0|
|max_tokens|Controls how many tokens are used. Exact implementation (whether it counts prompt and/or response) depends on the model.|int|1000|
|top_p|Controls the diversity of words. Higher values (closer to 1) make word selection more diverse, lower values make words less diverse.|float|1|
|history|include conversation history from your client or database.|any (recommendation: list[str])|None|
|stream|control if response is streamed back to the user.|bool|False|
|deployment_name|t.b.a.|str|None|
|system_prompt|System prompt string. Unused if none.|str|None|
|where|filter for context search.|dict|None|
## ChatConfig
All options for query and...
_coming soon_
`history` is not supported, as that is handled is handled automatically, the config option is not supported.
-40
View File
@@ -1,40 +0,0 @@
---
title: '🧪 Testing'
---
## Methods for testing
### Dry Run
Before you consume valueable tokens, you should make sure that data chunks are properly created and the embedding you have done works and that it's receiving the correct document from the database.
- For `query` or `chat` method, you can add this to your script:
```python
print(naval_chat_bot.query('Can you tell me who Naval Ravikant is?', dry_run=True))
'''
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.
Q: Who is Naval Ravikant?
A: Naval Ravikant is an Indian-American entrepreneur and investor.
Query: Can you tell me who Naval Ravikant is?
Helpful Answer:
'''
```
_The embedding is confirmed to work as expected. It returns the right document, even if the question is asked slightly different. No prompt tokens have been consumed._
The dry run will still consume tokens to embed your query, but it is only **~1/15 of the prompt.**
- For `add` method, you can add this to your script:
```python
print(naval_chat_bot.add('https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf', dry_run=True))
'''
{'chunks': ['THE ALMANACK OF NAVAL RAVIKANT', 'GETTING RICH IS NOT JUST ABOUT LUCK;', 'HAPPINESS IS NOT JUST A TRAIT WE ARE'], 'metadata': [{'source': 'C:\\Users\\Dev\\AppData\\Local\\Temp\\tmp3g5mjoiz\\tmp.pdf', 'page': 0, 'url': 'https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf', 'data_type': 'pdf_file'}, {'source': 'C:\\Users\\Dev\\AppData\\Local\\Temp\\tmp3g5mjoiz\\tmp.pdf', 'page': 2, 'url': 'https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf', 'data_type': 'pdf_file'}, {'source': 'C:\\Users\\Dev\\AppData\\Local\\Temp\\tmp3g5mjoiz\\tmp.pdf', 'page': 2, 'url': 'https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf', 'data_type': 'pdf_file'}], 'count': 7358, 'type': <DataType.PDF_FILE: 'pdf_file'>}
# less items to show for readability
'''
```
-118
View File
@@ -1,118 +0,0 @@
---
title: '💾 Vector Database'
---
We support `Chroma`, `Elasticsearch` and `OpenSearch` as vector databases.
`Chroma` is used as a default database.
## Elasticsearch
### Minimal Example
In order to use `Elasticsearch` as vector database we need to use App type `CustomApp`.
1. Set the environment variables in a `.env` file.
```
OPENAI_API_KEY=sk-SECRETKEY
ELASTICSEARCH_API_KEY=SECRETKEY==
ELASTICSEARCH_URL=https://secret-domain.europe-west3.gcp.cloud.es.io:443
```
Please note that the key needs certain privileges. For testing you can just toggle off `restrict privileges` under `/app/management/security/api_keys/` in your web interface.
2. Load the app
```python
from embedchain import CustomApp
from embedchain.embedder.openai import OpenAIEmbedder
from embedchain.llm.openai import OpenAILlm
from embedchain.vectordb.elasticsearch import ElasticsearchDB
es_app = CustomApp(
llm=OpenAILlm(),
embedder=OpenAIEmbedder(),
db=ElasticsearchDB(),
)
```
### More custom settings
You can get a URL for elasticsearch in the cloud, or run it locally.
The following example shows you how to configure embedchain to work with a locally running elasticsearch.
Instead of using an API key, we use http login credentials. The localhost url can be defined in .env or in the config.
```python
import os
from embedchain import CustomApp
from embedchain.config import CustomAppConfig, ElasticsearchDBConfig
from embedchain.embedder.openai import OpenAIEmbedder
from embedchain.llm.openai import OpenAILlm
from embedchain.vectordb.elasticsearch import ElasticsearchDB
es_config = ElasticsearchDBConfig(
# elasticsearch url or list of nodes url with different hosts and ports.
es_url='https://localhost:9200',
# pass named parameters supported by Python Elasticsearch client
http_auth=("elastic", "secret"),
ca_certs="~/binaries/elasticsearch-8.7.0/config/certs/http_ca.crt" # your cert path
# verify_certs=False # Alternative, if you aren't using certs
) # pass named parameters supported by elasticsearch-py
es_app = CustomApp(
config=CustomAppConfig(log_level="INFO"),
llm=OpenAILlm(),
embedder=OpenAIEmbedder(),
db=ElasticsearchDB(config=es_config),
)
```
3. This should log your connection details to the console.
4. Alternatively to a URL, you `ElasticsearchDBConfig` accepts `es_url` as a list of nodes url with different hosts and ports.
5. Additionally we can pass named parameters supported by Python Elasticsearch client.
## OpenSearch 🔍
To use OpenSearch as a vector database with a CustomApp, follow these simple steps:
1. Set the `OPENAI_API_KEY` environment variable:
```
OPENAI_API_KEY=sk-xxxx
```
2. Define the OpenSearch configuration in your Python code:
```python
from embedchain import CustomApp
from embedchain.config import OpenSearchDBConfig
from embedchain.embedder.openai import OpenAIEmbedder
from embedchain.llm.openai import OpenAILlm
from embedchain.vectordb.opensearch import OpenSearchDB
opensearch_url = "https://localhost:9200"
http_auth = ("username", "password")
db_config = OpenSearchDBConfig(
opensearch_url=opensearch_url,
http_auth=http_auth,
collection_name="embedchain-app",
use_ssl=True,
timeout=30,
)
db = OpenSearchDB(config=db_config)
```
2. Instantiate the app and add data:
```python
app = CustomApp(llm=OpenAILlm(), embedder=OpenAIEmbedder(), db=db)
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
app.add("https://www.forbes.com/profile/elon-musk")
app.add("https://www.britannica.com/biography/Elon-Musk")
```
3. You're all set! Start querying using the following command:
```python
app.query("What is the net worth of Elon Musk?")
```
+20 -10
View File
@@ -4,15 +4,25 @@ title: 🤝 Connect with Us
We believe in building a vibrant and supportive community around embedchain. There are various channels through which you can connect with us, stay updated, and contribute to the ongoing discussions:
* Slack: Our Slack workspace provides a platform for more structured discussions and channels dedicated to different topics. Feel free to jump in and start contributing. [Join Slack](https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw).
* Discord: Join our Discord server to engage in real-time conversations with the community members and the project maintainers. It’s a great place to seek help and discuss anything related to the project. [Join Discord](https://discord.gg/CUU9FPhRNt).
* Twitter: Follow us on Twitter for the latest news, announcements, and highlights from our community. It’s also a quick way to reach out to us. [Follow @embedchain](https://twitter.com/embedchain).
* LinkedIn: Connect with us on LinkedIn to stay updated on official announcements, job openings, and professional networking opportunities within our community. [Follow Our Page](https://www.linkedin.com/company/embedchain/).
* Newsletter: Subscribe to our newsletter for a curated list of project updates, community contributions, and upcoming events. It’s a compact way to stay in the loop with what’s happening in our community. [Subscribe Now](https://embedchain.substack.com/).
<CardGroup cols={3}>
<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">
Join our slack community
</Card>
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
Join our discord community
</Card>
<Card title="LinkedIn" icon="linkedin" href="https://www.linkedin.com/company/embedchain/">
Connect with us on LinkedIn
</Card>
<Card title="Schedule a call" icon="calendar" href="https://cal.com/taranjeetio/ec">
Schedule a call with Embedchain founder
</Card>
<Card title="Newsletter" icon="message" href="https://embedchain.substack.com/">
Subscribe to our newsletter
</Card>
</CardGroup>
We look forward to connecting with you and seeing how we can create amazing things together!
+173
View File
@@ -0,0 +1,173 @@
---
title: 🧩 Embedding models
---
## Overview
Embedchain supports several embedding models from the following providers:
<CardGroup cols={4}>
<Card title="OpenAI" href="#openai"></Card>
<Card title="Azure OpenAI" href="#azure-openai"></Card>
<Card title="GPT4All" href="#gpt4all"></Card>
<Card title="Hugging Face" href="#hugging-face"></Card>
<Card title="Vertex AI" href="#vertex-ai"></Card>
</CardGroup>
## OpenAI
To use OpenAI embedding function, you have to set the `OPENAI_API_KEY` environment variable. You can obtain the OpenAI API key from the [OpenAI Platform](https://platform.openai.com/account/api-keys).
Once you have obtained the key, you can use it like this:
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
# load embedding model configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
app.add("https://en.wikipedia.org/wiki/OpenAI")
app.query("What is OpenAI?")
```
```yaml config.yaml
embedder:
provider: openai
config:
model: 'text-embedding-ada-002'
```
</CodeGroup>
## Azure OpenAI
To use Azure OpenAI embedding model, you have to set some of the azure openai related environment variables as given in the code block below:
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_BASE"] = "https://xxx.openai.azure.com/"
os.environ["OPENAI_API_KEY"] = "xxx"
os.environ["OPENAI_API_VERSION"] = "xxx"
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: azure_openai
config:
model: gpt-35-turbo
deployment_name: your_llm_deployment_name
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
embedder:
provider: azure_openai
config:
model: text-embedding-ada-002
deployment_name: you_embedding_model_deployment_name
```
</CodeGroup>
You can find the list of models and deployment name on the [Azure OpenAI Platform](https://oai.azure.com/portal).
## GPT4ALL
GPT4All supports generating high quality embeddings of arbitrary length documents of text using a CPU optimized contrastively trained Sentence Transformer.
<CodeGroup>
```python main.py
from embedchain import App
# load embedding model configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: gpt4all
config:
model: 'orca-mini-3b.ggmlv3.q4_0.bin'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
embedder:
provider: gpt4all
```
</CodeGroup>
## Hugging Face
Hugging Face supports generating embeddings of arbitrary length documents of text using Sentence Transformer library. Example of how to generate embeddings using hugging face is given below:
<CodeGroup>
```python main.py
from embedchain import App
# load embedding model configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: huggingface
config:
model: 'google/flan-t5-xxl'
temperature: 0.5
max_tokens: 1000
top_p: 0.5
stream: false
embedder:
provider: huggingface
config:
model: 'sentence-transformers/all-mpnet-base-v2'
```
</CodeGroup>
## Vertex AI
Embedchain supports Google's VertexAI embeddings model through a simple interface. You just have to pass the `model_name` in the config yaml and it would work out of the box.
<CodeGroup>
```python main.py
from embedchain import App
# load embedding model configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: vertexai
config:
model: 'chat-bison'
temperature: 0.5
top_p: 0.5
embedder:
provider: vertexai
config:
model: 'textembedding-gecko'
```
</CodeGroup>
+325
View File
@@ -0,0 +1,325 @@
---
title: 🤖 Large language models (LLMs)
---
## Overview
Embedchain comes with built-in support for various popular large language models. We handle the complexity of integrating these models for you, allowing you to easily customize your language model interactions through a user-friendly interface.
<CardGroup cols={4}>
<Card title="OpenAI" href="#openai"></Card>
<Card title="Azure OpenAI" href="#azure-openai"></Card>
<Card title="Anthropic" href="#anthropic"></Card>
<Card title="Cohere" href="#cohere"></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>
</CardGroup>
## OpenAI
To use OpenAI LLM models, you have to set the `OPENAI_API_KEY` environment variable. You can obtain the OpenAI API key from the [OpenAI Platform](https://platform.openai.com/account/api-keys).
Once you have obtained the key, you can use it like this:
```python
import os
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
app = App()
app.add("https://en.wikipedia.org/wiki/OpenAI")
app.query("What is OpenAI?")
```
If you are looking to configure the different parameters of the LLM, you can do so by loading the app using a [yaml config](https://github.com/embedchain/embedchain/blob/main/configs/chroma.yaml) file.
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
# load llm configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: openai
config:
model: 'gpt-3.5-turbo'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
```
</CodeGroup>
## Azure OpenAI
To use Azure OpenAI model, you have to set some of the azure openai related environment variables as given in the code block below:
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ["OPENAI_API_TYPE"] = "azure"
os.environ["OPENAI_API_BASE"] = "https://xxx.openai.azure.com/"
os.environ["OPENAI_API_KEY"] = "xxx"
os.environ["OPENAI_API_VERSION"] = "xxx"
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: azure_openai
config:
model: gpt-35-turbo
deployment_name: your_llm_deployment_name
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
embedder:
provider: azure_openai
config:
model: text-embedding-ada-002
deployment_name: you_embedding_model_deployment_name
```
</CodeGroup>
You can find the list of models and deployment name on the [Azure OpenAI Platform](https://oai.azure.com/portal).
## Anthropic
To use anthropic's model, please set the `ANTHROPIC_API_KEY` which you find on their [Account Settings Page](https://console.anthropic.com/account/keys).
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ["ANTHROPIC_API_KEY"] = "xxx"
# load llm configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: anthropic
config:
model: 'claude-instant-1'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
```
</CodeGroup>
## Cohere
Install related dependencies using the following command:
```bash
pip install --upgrade 'embedchain[cohere]'
```
Set the `COHERE_API_KEY` as environment variable which you can find on their [Account settings page](https://dashboard.cohere.com/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["COHERE_API_KEY"] = "xxx"
# load llm configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: cohere
config:
model: large
temperature: 0.5
max_tokens: 1000
top_p: 1
```
</CodeGroup>
## GPT4ALL
Install related dependencies using the following command:
```bash
pip install --upgrade 'embedchain[opensource]'
```
GPT4all is a free-to-use, locally running, privacy-aware chatbot. No GPU or internet required. You can use this with Embedchain using the following code:
<CodeGroup>
```python main.py
from embedchain import App
# load llm configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: gpt4all
config:
model: 'orca-mini-3b.ggmlv3.q4_0.bin'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
embedder:
provider: gpt4all
```
</CodeGroup>
## JinaChat
First, set `JINACHAT_API_KEY` in environment variable which you can obtain from [their platform](https://chat.jina.ai/api).
Once you have the key, load the app using the config yaml file:
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ["JINACHAT_API_KEY"] = "xxx"
# load llm configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: jina
config:
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
```
</CodeGroup>
## Hugging Face
Install related dependencies using the following command:
```bash
pip install --upgrade 'embedchain[huggingface_hub]'
```
First, set `HUGGINGFACE_ACCESS_TOKEN` in environment variable which you can obtain from [their platform](https://huggingface.co/settings/tokens).
Once you have the token, 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(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: huggingface
config:
model: 'google/flan-t5-xxl'
temperature: 0.5
max_tokens: 1000
top_p: 0.5
stream: false
```
</CodeGroup>
## 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).
Once you have the token, load the app using the config yaml file:
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ["REPLICATE_API_TOKEN"] = "xxx"
# load llm configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: llama2
config:
model: 'a16z-infra/llama13b-v2-chat:df7690f1994d94e96ad9d568eac121aecf50684a0b0963b25a41cc40061269e5'
temperature: 0.5
max_tokens: 1000
top_p: 0.5
stream: false
```
</CodeGroup>
## Vertex AI
Setup Google Cloud Platform application credentials by following the instruction on [GCP](https://cloud.google.com/docs/authentication/external/set-up-adc). Once setup is done, use the following code to create an app using VertexAI as provider:
<CodeGroup>
```python main.py
from embedchain import App
# load llm configuration from config.yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
llm:
provider: vertexai
config:
model: 'chat-bison'
temperature: 0.5
top_p: 0.5
```
</CodeGroup>
<br/ >
<Snippet file="missing-llm-tip.mdx" />
+224
View File
@@ -0,0 +1,224 @@
---
title: 🗄️ Vector databases
---
## Overview
Utilizing a vector database alongside Embedchain is a seamless process. All you need to do is configure it within the YAML configuration file. We've provided examples for each supported database below:
<CardGroup cols={4}>
<Card title="ChromaDB" href="#chromadb"></Card>
<Card title="Elasticsearch" href="#elasticsearch"></Card>
<Card title="OpenSearch" href="#opensearch"></Card>
<Card title="Zilliz" href="#zilliz"></Card>
<Card title="LanceDB" href="#lancedb"></Card>
<Card title="Pinecone" href="#pinecone"></Card>
<Card title="Qdrant" href="#qdrant"></Card>
<Card title="Weaviate" href="#weaviate"></Card>
</CardGroup>
## ChromaDB
<CodeGroup>
```python main.py
from embedchain import App
# load chroma configuration from yaml file
app = App.from_config(yaml_path="config1.yaml")
```
```yaml config1.yaml
vectordb:
provider: chroma
config:
collection_name: 'my-collection'
dir: db
allow_reset: true
```
```yaml config2.yaml
vectordb:
provider: chroma
config:
collection_name: 'my-collection'
host: localhost
port: 5200
allow_reset: true
```
</CodeGroup>
## Elasticsearch
Install related dependencies using the following command:
```bash
pip install --upgrade 'embedchain[elasticsearch]'
```
<CodeGroup>
```python main.py
from embedchain import App
# load elasticsearch configuration from yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
vectordb:
provider: elasticsearch
config:
collection_name: 'es-index'
es_url: http://localhost:9200
allow_reset: true
api_key: xxx
```
</CodeGroup>
## OpenSearch
Install related dependencies using the following command:
```bash
pip install --upgrade 'embedchain[opensearch]'
```
<CodeGroup>
```python main.py
from embedchain import App
# load opensearch configuration from yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
vectordb:
provider: opensearch
config:
opensearch_url: 'https://localhost:9200'
http_auth:
- admin
- admin
vector_dimension: 1536
collection_name: 'my-app'
use_ssl: false
verify_certs: false
```
</CodeGroup>
## Zilliz
Install related dependencies using the following command:
```bash
pip install --upgrade 'embedchain[milvus]'
```
Set the Zilliz environment variables `ZILLIZ_CLOUD_URI` and `ZILLIZ_CLOUD_TOKEN` which you can find it on their [cloud platform](https://cloud.zilliz.com/).
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ['ZILLIZ_CLOUD_URI'] = 'https://xxx.zillizcloud.com'
os.environ['ZILLIZ_CLOUD_TOKEN'] = 'xxx'
# load zilliz configuration from yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
vectordb:
provider: zilliz
config:
collection_name: 'zilliz-app'
uri: https://xxxx.api.gcp-region.zillizcloud.com
token: xxx
vector_dim: 1536
metric_type: L2
```
</CodeGroup>
## LanceDB
_Coming soon_
## Pinecone
Install pinecone related dependencies using the following command:
```bash
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/).
<CodeGroup>
```python main.py
from embedchain import App
# load pinecone configuration from yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
vectordb:
provider: pinecone
config:
metric: cosine
vector_dimension: 1536
collection_name: my-pinecone-index
```
</CodeGroup>
## 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 App
# load qdrant configuration from yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
vectordb:
provider: qdrant
config:
collection_name: my_qdrant_index
```
</CodeGroup>
## Weaviate
In order to use Weaviate as a vector database, set the environment variables `WEAVIATE_ENDPOINT` and `WEAVIATE_API_KEY` which you can find on [Weaviate dashboard](https://console.weaviate.cloud/dashboard).
<CodeGroup>
```python main.py
from embedchain import App
# load weaviate configuration from yaml file
app = App.from_config(yaml_path="config.yaml")
```
```yaml config.yaml
vectordb:
provider: weaviate
config:
collection_name: my_weaviate_index
```
</CodeGroup>
<Snippet file="missing-vector-db-tip.mdx" />
+3 -6
View File
@@ -35,12 +35,9 @@ embedchain is built on the following stack:
## Team
### Author
### Authors
- Taranjeet Singh ([@taranjeetio](https://twitter.com/taranjeetio))
### Maintainer
- Deshraj Yadav ([@deshrajdry](https://twitter.com/taranjeetio))
### Citation
@@ -49,8 +46,8 @@ If you utilize this repository, please consider citing it with:
```
@misc{embedchain,
author = {Taranjeet Singh},
title = {Embechain: Framework to easily create LLM powered bots over any dataset},
author = {Taranjeet Singh, Deshraj Yadav},
title = {Embechain: Data platform for LLMs - Load, index, retrieve and sync any unstructured data},
year = {2023},
publisher = {GitHub},
journal = {GitHub repository},
+11 -6
View File
@@ -1,14 +1,19 @@
---
title: 'CSV'
title: '📊 CSV'
---
### CSV file
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:
```python
app.add('https://example.com/content/sheet.csv', data_type="csv")
app.add('content/sheet.csv', data_type="csv")
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.
```
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: 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.
+5 -7
View File
@@ -1,18 +1,16 @@
---
title: 'Data Type Handling'
title: 'Data type handling'
---
## Automatic data type detection
The add method automatically tries to detect the data_type, based on your input for the source argument. So `app.add('https://www.youtube.com/watch?v=dQw4w9WgXcQ')` is enough to embed a YouTube video.
This detection is implemented for all formats. It is based on factors such as whether it's a URL, a local file, the source data type, etc.
### Debugging automatic detection
Set `log_level=DEBUG` (in [AppConfig](http://localhost:3000/advanced/query_configuration#appconfig)) and make sure it's working as intended.
Otherwise, you will not know when, for instance, an invalid filepath is interpreted as raw text instead.
Set `log_level: DEBUG` in the config yaml to debug if the data type detection is done right or not. Otherwise, you will not know when, for instance, an invalid filepath is interpreted as raw text instead.
### Forcing a data type
@@ -21,7 +19,7 @@ The examples below show you the keyword to force the respective `data_type`.
Forcing can also be used for edge cases, such as interpreting a sitemap as a web_page, for reading its raw text instead of following links.
## Remote Data Types
## Remote data types
<Tip>
**Use local files in remote data types**
@@ -32,7 +30,7 @@ You can pass local files by formatting the path using the `file:` [URI scheme](h
## Reusing a vector database
Default behavior is to create a persistent vector DB in the directory **./db**. You can split your application into two Python scripts: one to create a local vector DB and the other to reuse this local persistent vector DB. This is useful when you want to index hundreds of documents and separately implement a chat interface.
Default behavior is to create a persistent vector db in the directory **./db**. You can split your application into two Python scripts: one to create a local vector db and the other to reuse this local persistent vector db. This is useful when you want to index hundreds of documents and separately implement a chat interface.
Create a local index:
+7 -4
View File
@@ -1,11 +1,14 @@
---
title: 'Code Documentation'
title: '📚🌐 Code documentation'
---
### Code documentation
To add any code documentation website as a loader, use the data_type as `docs_site`. Eg:
```python
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, and COHERE. Embedchain allows users to import and utilize these LLM providers for their applications.'
```
+9 -3
View File
@@ -1,5 +1,5 @@
---
title: 'Docx File'
title: '📄 Docx file'
---
### Docx file
@@ -7,6 +7,12 @@ 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 App
app = App()
app.add('https://example.com/content/intro.docx', data_type="docx")
app.add('content/intro.docx', data_type="docx")
```
# Or add file using the local file path on your system
# app.add('content/intro.docx', data_type="docx")
app.query("Summarize the docx data?")
```
+35
View File
@@ -0,0 +1,35 @@
---
title: '📬 Gmail'
---
To use GmailLoader you must install the extra dependencies with `pip install --upgrade embedchain[gmail]`.
The `source` must be a valid Gmail search query, you can refer `https://support.google.com/mail/answer/7190?hl=en` to build a query.
To load Gmail messages, you MUST use the data_type as `gmail`. Otherwise the source will be detected as simple `text`.
To use this you need to save `credentials.json` in the directory from where you will run the loader. Follow these steps to get the credentials
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. Create an `OAuth Consent Screen` in the project. You may need to select the `external` option.
4. Make sure the consent screen is published.
5. Enable the [Gmail API](https://console.cloud.google.com/apis/api/gmail.googleapis.com)
6. Create credentials from the `Credentials` tab.
7. Select the type `OAuth Client ID`.
8. Choose the application type `Web application`. As a name you can choose `embedchain` or any other name as per your use case.
9. Add an authorized redirect URI for `http://localhost:8080/`.
10. You can leave everything else at default, finish the creation.
11. When you are done, a modal opens where you can download the details in `json` format.
12. Put the `.json` file in your current directory and rename it to `credentials.json`
```python
import os
from embedchain.apps.app import App
from embedchain.models.data_type import DataType
app = App()
query = "to: me label:inbox"
app.add(query, data_type=DataType.GMAIL)
app.query("Summarize my email conversations")
```
-24
View File
@@ -1,24 +0,0 @@
---
title: 'How to add data'
---
## Add Dataset
- This step assumes that you have already created an `App`. We are calling our app instance as `naval_chat_bot` 🤖
- Now use `.add` method to add any dataset.
```python
naval_chat_bot = App()
# Embed Online Resources
naval_chat_bot.add("https://www.youtube.com/watch?v=3qHkcs3kG44")
naval_chat_bot.add("https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf")
naval_chat_bot.add("https://nav.al/feedback")
naval_chat_bot.add("https://nav.al/agi")
# Embed Local Resources
naval_chat_bot.add(("Who is Naval Ravikant?", "Naval Ravikant is an Indian-American entrepreneur and investor."))
```
The possible formats to add data can be found on the [Supported Data Formats](/advanced/data_types) page.
+36
View File
@@ -0,0 +1,36 @@
---
title: '📃 JSON'
---
To add any json file, use the data_type as `json`. `json` 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:
```python
import os
from embedchain.apps.app import App
os.environ["OPENAI_API_KEY"] = "openai_api_key"
app = App()
response = app.query("What is the net worth of Elon Musk as of October 2023?")
print(response)
"I'm sorry, but I don't have access to real-time information or future predictions. Therefore, I don't know the net worth of Elon Musk as of October 2023."
source_id = app.add("temp.json")
response = app.query("What is the net worth of Elon Musk as of October 2023?")
print(response)
"As of October 2023, Elon Musk's net worth is $255.2 billion."
```
```temp.json
{
"question": "What is your net worth, Elon Musk?",
"answer": "As of October 2023, Elon Musk's net worth is $255.2 billion, making him one of the wealthiest individuals in the world."
}
```
+8 -6
View File
@@ -1,12 +1,14 @@
---
title: 'Mdx'
title: '📝 Mdx file'
---
### 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:
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 App
app = App()
app.add('path/to/file.mdx', data_type='mdx')
```
app.query("What are the docs about?")
```
+13 -8
View File
@@ -1,15 +1,20 @@
---
title: 'Notion'
title: '📓 Notion'
---
### Notion
To use notion you must install the extra dependencies with `pip install --upgrade embedchain[notion]`.
To use notion you must install the extra dependencies with `pip install --upgrade embedchain[community]`.
To load a notion page, use the data_type as `notion`. Since it is hard to automatically detect, forcing this is advised.
To load a notion page, use the data_type as `notion`. Since it is hard to automatically detect, it is advised to specify the `data_type` when adding a notion document.
The next argument must **end** with the `notion page id`. The id is a 32-character string. Eg:
```python
app.add("cfbc134ca6464fc980d0391613959196", "notion")
app.add("my-page-cfbc134ca6464fc980d0391613959196", "notion")
app.add("https://www.notion.so/my-page-cfbc134ca6464fc980d0391613959196", "notion")
```
from embedchain import App
app = App()
app.add("cfbc134ca6464fc980d0391613959196", data_type="notion")
app.add("my-page-cfbc134ca6464fc980d0391613959196", data_type="notion")
app.add("https://www.notion.so/my-page-cfbc134ca6464fc980d0391613959196", data_type="notion")
app.query("Summarize the notion doc")
```
+23
View File
@@ -0,0 +1,23 @@
---
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. Headers are included for each line, so if you have an `age` column, `18` will be added as `age: 18`. Eg:
```python
from embedchain.apps.app import App
import os
os.environ["OPENAI_API_KEY"] = "sk-xxx"
app = App()
app.add("https://github.com/openai/openai-openapi/blob/master/openapi.yaml", data_type="openapi")
# Or add using the local file path
# app.add("configs/openai_openapi.yaml", data_type="openapi")
response = app.query("What can OpenAI API endpoint do? Can you list the things it can learn from?")
# Answer: The OpenAI API endpoint allows users to interact with OpenAI's models and perform various tasks such as generating text, answering questions, summarizing documents, translating languages, and more. The specific capabilities and tasks that the API can learn from may vary depending on the models and features provided by OpenAI. For more detailed information, it is recommended to refer to the OpenAI API documentation at https://platform.openai.com/docs/api-reference.
```
NOTE: The yaml file added to the App must have the required OpenAPI fields otherwise the adding OpenAPI spec will fail. Please refer to [OpenAPI Spec Doc](https://spec.openapis.org/oas/v3.1.0)
+27
View File
@@ -0,0 +1,27 @@
---
title: Overview
---
Embedchain comes with built-in support for various data sources. We handle the complexity of loading unstructured data from these data sources, allowing you to easily customize your app through a user-friendly interface.
<CardGroup cols={4}>
<Card title="📊 csv" href="/data-sources/csv"></Card>
<Card title="📃 JSON" href="/data-sources/json"></Card>
<Card title="📚🌐 docs site" href="/data-sources/docs-site"></Card>
<Card title="📄 docx" href="/data-sources/docx"></Card>
<Card title="📝 mdx" href="/data-sources/mdx"></Card>
<Card title="📓 notion" href="/data-sources/notion"></Card>
<Card title="📰 pdf" href="/data-sources/pdf-file"></Card>
<Card title="❓💬 q&a pair" href="/data-sources/qna"></Card>
<Card title="🗺️ sitemap" href="/data-sources/sitemap"></Card>
<Card title="📝 text" href="/data-sources/text"></Card>
<Card title="🌐📄 web page" href="/data-sources/web-page"></Card>
<Card title="🧾 xml" href="/data-sources/xml"></Card>
<Card title="🙌 OpenAPI" href="/data-sources/openapi"></Card>
<Card title="🎥📺 youtube video" href="/data-sources/youtube-video"></Card>
<Card title="📬 Gmail" href="/data-sources/gmail"></Card>
</CardGroup>
<br/ >
<Snippet file="missing-data-source-tip.mdx" />
+8 -5
View File
@@ -1,14 +1,17 @@
---
title: 'PDF File'
title: '📰 PDF file'
---
### PDF File
To add any pdf file, use the data_type as `pdf_file`. Eg:
```python
app.add('a_valid_url_where_pdf_file_can_be_accessed', data_type='pdf_file')
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.
```
Note that we do not support password protected pdfs.
+5 -3
View File
@@ -1,11 +1,13 @@
---
title: 'QnA Pair'
title: '❓💬 Queston and answer pair'
---
### QnA 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 App
app = App()
app.add(("Question", "Answer"), data_type="qna_pair")
```
-4
View File
@@ -1,4 +0,0 @@
---
title: 'Request New Format'
url: https://forms.gle/gB5La14tjgy4p94dA
---
+5 -3
View File
@@ -1,11 +1,13 @@
---
title: 'Sitemap'
title: '🗺️ Sitemap'
---
### Sitemap
Add all web pages from an xml-sitemap. Filters non-text files. Use the data_type as `sitemap`. Eg:
```python
from embedchain import App
app = App()
app.add('https://example.com/sitemap.xml', data_type='sitemap')
```
+6 -2
View File
@@ -1,5 +1,5 @@
---
title: 'Text'
title: '📝 Text'
---
### Text
@@ -7,7 +7,11 @@ 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 App
app = App()
app.add('Seek wealth, not money or status. Wealth is having assets that earn while you sleep. Money is how we transfer time and wealth. Status is your place in the social hierarchy.', data_type='text')
```
Note: This is not used in the examples because in most cases you will supply a whole paragraph or file, which did not fit.
Note: This is not used in the examples because in most cases you will supply a whole paragraph or file, which did not fit.
+6 -4
View File
@@ -1,11 +1,13 @@
---
title: 'Web page'
title: '🌐📄 Web page'
---
### Web page
To add any web page, use the data_type as `web_page`. Eg:
```python
from embedchain import App
app = App()
app.add('a_valid_web_page_url', data_type='web_page')
```
```
+17
View File
@@ -0,0 +1,17 @@
---
title: '🧾 XML file'
---
### XML file
To add any xml file, use the data_type as `xml`. Eg:
```python
from embedchain import App
app = App()
app.add('content/data.xml')
```
Note: Only the text content of the xml file will be added to the app. The tags will be ignored.
+4 -3
View File
@@ -1,12 +1,13 @@
---
title: 'Youtube Video'
title: '🎥📺 Youtube video'
---
### Youtube video
To add any youtube video to your app, use the data_type (first argument to `.add()` method) as `youtube_video`. Eg:
```python
from embedchain import App
app = App()
app.add('a_valid_youtube_url_here', data_type='youtube_video')
```
+3 -1
View File
@@ -2,7 +2,9 @@
title: '🌍 API Server'
---
The API Server based on Flask integrates the `embedchain` package, offering endpoints to add, query, and chat to engage in conversations with a chatbot using JSON requests.
The API server example can be found [here](https://github.com/embedchain/embedchain/tree/main/examples/api_server).
It is a Flask based server that integrates the `embedchain` package, offering endpoints to add, query, and chat to engage in conversations with a chatbot using JSON requests.
### 🐳 Docker Setup
+4
View File
@@ -2,6 +2,10 @@
title: '🌐 Full Stack'
---
The Full Stack app example can be found [here](https://github.com/embedchain/embedchain/tree/main/examples/full_stack).
This guide will help you setup the full stack app on your local machine.
### 🐳 Docker Setup
- To setup full stack app using docker, run the following command inside this folder using your terminal.
-16
View File
@@ -1,16 +0,0 @@
---
title: ❓ Frequently Asked Questions
description: 'Collections of all the frequently asked questions about Embedchain'
---
## How to use GPT-4 as the LLM model
```python
from embedchain import App
from embedchain.config import LlmConfig
app = App()
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
app.query("How many companies does Elon Musk run and name those?", config=LlmConfig(model="gpt-4"))
```
-60
View File
@@ -1,60 +0,0 @@
---
title: 📚 Introduction
description: '📝 Embedchain is a framework to easily create LLM powered bots over any dataset.'
---
## 🤔 What is Embedchain?
Embedchain abstracts the entire process of loading a dataset, chunking it, creating embeddings, and storing it in a vector database.
You can add a single or multiple datasets using the `.add` method. Then, simply use the `.query` method to find answers from the added datasets.
If you want to create a Naval Ravikant bot with a YouTube video, a book in PDF format, two blog posts, and a question and answer pair, all you need to do is add the respective links. Embedchain will take care of the rest, creating a bot for you.
```python
from embedchain import App
naval_chat_bot = App()
# Embed Online Resources
naval_chat_bot.add("https://www.youtube.com/watch?v=3qHkcs3kG44")
naval_chat_bot.add("https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf")
naval_chat_bot.add("https://nav.al/feedback")
naval_chat_bot.add("https://nav.al/agi")
naval_chat_bot.add("The Meanings of Life", 'text', metadata={'chapter': 'philosphy'})
# Embed Local Resources
naval_chat_bot.add(("Who is Naval Ravikant?", "Naval Ravikant is an Indian-American entrepreneur and investor."))
naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?")
# Answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
# with where context filter
naval_chat_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?", where={'chapter': 'philosophy'})
```
## 🚀 How it works?
Creating a chat bot over any dataset involves the following steps:
1. Detect the data type and load the data
2. Create meaningful chunks
3. Create embeddings for each chunk
4. Store the chunks in a vector database
When a user asks a query, the following process happens to find the answer:
1. Create an embedding for the query
2. Find similar documents for the query from the vector database
3. Pass the similar documents as context to LLM to get the final answer.
The process of loading the dataset and querying involves multiple steps, each with its own nuances:
- How should I chunk the data? What is a meaningful chunk size?
- How should I create embeddings for each chunk? Which embedding model should I use?
- How should I store the chunks in a vector database? Which vector database should I use?
- Should I store metadata along with the embeddings?
- How should I find similar documents for a query? Which ranking model should I use?
Embedchain takes care of all these nuances and provides a simple interface to create bots over any dataset.
In the first release, we make it easier for anyone to get a chatbot over any dataset up and running in less than a minute. Just create an app instance, add the datasets using the `.add` method, and use the `.query` method to get the relevant answers.
-35
View File
@@ -1,35 +0,0 @@
---
title: '🚀 Quickstart'
description: '💡 Start building LLM powered bots under 30 seconds'
---
Install embedchain python package:
```bash
pip install --upgrade embedchain
```
Creating a chatbot involves 3 steps:
- ⚙️ Import the App instance
- 🗃️ Add Dataset
- 💬 Query or Chat on the dataset and get answers (Interface Types)
Run your first bot in python using the following code. Make sure to set the `OPENAI_API_KEY` 🔑 environment variable in the code.
```python
import os
from embedchain import App
os.environ["OPENAI_API_KEY"] = "xxx"
elon_musk_bot = App()
# Embed Online Resources
elon_musk_bot.add("https://en.wikipedia.org/wiki/Elon_Musk")
elon_musk_bot.add("https://www.forbes.com/profile/elon-musk")
response = elon_musk_bot.query("How many companies does Elon Musk run and name those?")
print(response)
# Answer: 'Elon Musk currently runs several companies. As of my knowledge, he is the CEO and lead designer of SpaceX, the CEO and product architect of Tesla, Inc., the CEO and founder of Neuralink, and the CEO and founder of The Boring Company. However, please note that this information may change over time, so it's always good to verify the latest updates.'
```
+123
View File
@@ -0,0 +1,123 @@
---
title: 🔎 Examples
description: 'Collection of Google colab notebook and Replit links for users'
---
<table>
<thead>
<tr>
<th>LLM</th>
<th>Google Colab</th>
<th>Replit</th>
</tr>
</thead>
<tbody>
<tr>
<td className="align-middle">OpenAI</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/openai.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/openai#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Anthropic</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/anthropic.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/anthropic#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Azure OpenAI</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/azure-openai.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/azureopenai#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">VertexAI</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/vertex_ai.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/vertexai#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Cohere</td>
<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&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Hugging Face</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/hugging_face_hub.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/huggingface#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">JinaChat</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/jina.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/jina#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">GPT4All</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/gpt4all.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/gpt4all#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Llama2</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/llama2.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/llama2#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Embedding model</th>
<th>Google Colab</th>
<th>Replit</th>
</tr>
</thead>
<tbody>
<tr>
<td className="align-middle">OpenAI</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/openai.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/openai#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">VertexAI</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/vertex_ai.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/vertexai#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">GPT4All</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/gpt4all.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/gpt4all#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Hugging Face</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/hugging_face_hub.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/huggingface#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Vector DB</th>
<th>Google Colab</th>
<th>Replit</th>
</tr>
</thead>
<tbody>
<tr>
<td className="align-middle">ChromaDB</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/chromadb.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/chromadb#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Elasticsearch</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/elasticsearch.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/elasticsearchdb#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Opensearch</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/opensearch.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/opensearchdb#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
<tr>
<td className="align-middle">Pinecone</td>
<td className="align-middle"><a target="_blank" href="https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/pinecone.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/pineconedb#main.py"><img src="https://replit.com/badge?caption=Try%20with%20Replit&amp;variant=small" noZoom alt="Try with Replit Badge"/></a></td>
</tr>
</tbody>
</table>
+68
View File
@@ -0,0 +1,68 @@
---
title: ❓ FAQs
description: 'Collections of all the frequently asked questions'
---
#### How to use GPT-4 as the LLM model?
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
# load llm configuration from gpt4.yaml file
app = App.from_config(yaml_path="gpt4.yaml")
```
```yaml gpt4.yaml
llm:
provider: openai
config:
model: 'gpt-4'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
```
</CodeGroup>
#### I don't have OpenAI credits. How can I use some open source model?
<CodeGroup>
```python main.py
import os
from embedchain import App
os.environ['OPENAI_API_KEY'] = 'xxx'
# load llm configuration from opensource.yaml file
app = App.from_config(yaml_path="opensource.yaml")
```
```yaml opensource.yaml
llm:
provider: gpt4all
config:
model: 'orca-mini-3b.ggmlv3.q4_0.bin'
temperature: 0.5
max_tokens: 1000
top_p: 1
stream: false
embedder:
provider: gpt4all
config:
model: 'all-MiniLM-L6-v2'
```
</CodeGroup>
#### How to contact support?
If docs aren't sufficient, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
+55
View File
@@ -0,0 +1,55 @@
---
title: 📚 Introduction
description: '📝 Embedchain is a Data Platform for LLMs - load, index, retrieve, and sync any unstructured data'
---
## 🤔 What is Embedchain?
Embedchain abstracts the entire process of loading data, chunking it, creating embeddings, and storing it in a vector database.
You can add data from different data sources using the `.add()` method. Then, simply use the `.query()` method to find answers from the added datasets.
If you want to create a Naval Ravikant bot with a YouTube video, a book in PDF format, two blog posts, and a question and answer pair, all you need to do is add the respective links. Embedchain will take care of the rest, creating a bot for you.
```python
from embedchain import App
naval_bot = App()
# Add online data
naval_bot.add("https://www.youtube.com/watch?v=3qHkcs3kG44")
naval_bot.add("https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf")
naval_bot.add("https://nav.al/feedback")
naval_bot.add("https://nav.al/agi")
naval_bot.add("The Meanings of Life", 'text', metadata={'chapter': 'philosphy'})
# Add local resources
naval_bot.add(("Who is Naval Ravikant?", "Naval Ravikant is an Indian-American entrepreneur and investor."))
naval_bot.query("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?")
# Answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
```
## 🚀 How it works?
Embedchain abstracts out the following steps from you to easily create LLM powered apps:
1. Detect the data type and load data
2. Create meaningful chunks
3. Create embeddings for each chunk
4. Store chunks in a vector database
When a user asks a query, the following process happens to find the answer:
1. Create an embedding for the query
2. Find similar documents for the query from the vector database
3. Pass the similar documents as context to LLM to get the final answer
The process of loading the dataset and querying involves multiple steps, each with its own nuances:
- How should I chunk the data? What is a meaningful chunk size?
- How should I create embeddings for each chunk? Which embedding model should I use?
- How should I store the chunks in a vector database? Which vector database should I use?
- Should I store metadata along with the embeddings?
- How should I find similar documents for a query? Which ranking model should I use?
Embedchain takes care of all these nuances and provides a simple interface to create apps on any data.
+58
View File
@@ -0,0 +1,58 @@
---
title: '🚀 Quickstart'
description: '💡 Start building LLM powered apps under 30 seconds'
---
Embedchain is a Data Platform for LLMs - load, index, retrieve, and sync any unstructured data. Using embedchain, you can easily create LLM powered apps over any data.
Install embedchain python package:
```bash
pip install embedchain
```
Creating an app involves 3 steps:
<Steps>
<Step title="⚙️ Import app instance">
```python
from embedchain import App
app = App()
```
</Step>
<Step title="🗃️ Add data sources">
```python
# Add different data sources
elon_bot.add("https://en.wikipedia.org/wiki/Elon_Musk")
elon_bot.add("https://www.forbes.com/profile/elon-musk")
# You can also add local data sources such as pdf, csv files etc.
# elon_bot.add("/path/to/file.pdf")
```
</Step>
<Step title="💬 Query or chat on your data and get answers">
```python
elon_bot.query("What is the net worth of Elon Musk today?")
# Answer: The net worth of Elon Musk today is $258.7 billion.
```
</Step>
</Steps>
Putting it together, you can run your first app using the following code. Make sure to set the `OPENAI_API_KEY` 🔑 environment variable in the code.
```python
import os
from embedchain import App
os.environ["OPENAI_API_KEY"] = "xxx"
elon_bot = App()
# Add different data sources
elon_bot.add("https://en.wikipedia.org/wiki/Elon_Musk")
elon_bot.add("https://www.forbes.com/profile/elon-musk")
# You can also add local data sources such as pdf, csv files etc.
# elon_bot.add("/path/to/file.pdf")
response = elon_bot.query("What is the net worth of Elon Musk today?")
print(response)
# Answer: The net worth of Elon Musk today is $258.7 billion.
```
+31 -21
View File
@@ -16,13 +16,13 @@
"name": "Twitter",
"url": "https://twitter.com/embedchain"
},
{
"name": "Discord",
"url": "https://discord.gg/6PzXDgEjG5"
},
{
"name":"Slack",
"url":"https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw"
},
{
"name": "Discord",
"url": "https://discord.gg/6PzXDgEjG5"
}
],
"topbarCtaButton": {
@@ -32,22 +32,21 @@
"navigation": [
{
"group": "Get started",
"pages": ["get-start/quickstart", "get-start/introduction", "get-start/faq"]
},
{
"group": "Advanced",
"pages": ["advanced/app_types", "advanced/interface_types", "advanced/query_configuration", "advanced/configuration", "advanced/testing", "advanced/vector_database"]
"pages": ["get-started/quickstart", "get-started/introduction", "get-started/faq", "get-started/examples"]
},
{
"group": "Data Sources",
"group": "Components",
"pages": ["components/llms", "components/embedding-models", "components/vector-databases"]
},
{
"group": "Data sources",
"pages": [
"data-sources/how-to-add-data",
"data-sources/data-type-handling",
"data-sources/overview",
{
"group": "Supported Data Sources",
"group": "Supported data sources",
"pages": [
"data-sources/csv",
"data-sources/json",
"data-sources/docs-site",
"data-sources/docx",
"data-sources/mdx",
@@ -57,16 +56,25 @@
"data-sources/sitemap",
"data-sources/text",
"data-sources/web-page",
"data-sources/openapi",
"data-sources/youtube-video"
]
},
"data-sources/request-new-format"
"data-sources/data-type-handling"
]
},
{
"group": "Advanced",
"pages": ["advanced/configuration"]
},
{
"group": "Examples",
"pages": ["examples/full_stack", "examples/api_server", "examples/discord_bot", "examples/slack_bot", "examples/telegram_bot", "examples/whatsapp_bot", "examples/poe_bot"]
},
{
"group": "Pipelines",
"pages": ["pipelines/quickstart"]
},
{
"group": "Community",
"pages": [
@@ -75,7 +83,7 @@
]
},
{
"group": "Integration",
"group": "Integrations",
"pages": ["integration/langsmith"]
},
{
@@ -98,12 +106,14 @@
],
"footerSocials": {
"twitter": "https://twitter.com/embedchain",
"github": "https://github.com/embedchain/embedchain",
"linkedin": "https://www.linkedin.com/company/embedchain",
"website": "https://embedchain.ai",
"slack":"https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw"
"github": "https://github.com/embedchain/embedchain",
"slack":"https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw",
"discord": "https://discord.gg/6PzXDgEjG5",
"twitter": "https://twitter.com/embedchain",
"linkedin": "https://www.linkedin.com/company/embedchain"
},
"backgroundImage": "/background.png",
"isWhiteLabeled": true
"isWhiteLabeled": true,
"feedback.thumbsRating": true
}
+44
View File
@@ -0,0 +1,44 @@
---
title: '🚀 Pipelines'
description: '💡 Start building LLM powered data pipelines in 1 minute'
---
Embedchain lets you build data pipelines on your own data sources and deploy it in production in less than a minute. It can load, index, retrieve, and sync any unstructured data.
Install embedchain python package:
```bash
pip install embedchain
```
Creating a pipeline involves 3 steps:
<Steps>
<Step title="⚙️ Import pipeline instance">
```python
from embedchain import Pipeline
p = Pipeline(name="Elon Musk")
```
</Step>
<Step title="🗃️ Add data sources">
```python
# Add different data sources
p.add("https://en.wikipedia.org/wiki/Elon_Musk")
p.add("https://www.forbes.com/profile/elon-musk")
# You can also add local data sources such as pdf, csv files etc.
# p.add("/path/to/file.pdf")
```
</Step>
<Step title="💬 Deploy your pipeline to Embedchain platform">
```python
p.deploy()
```
</Step>
</Steps>
That's it. Now, head to the [Embedchain platform](https://app.embedchain.ai) and your pipeline is available there. Make sure to set the `OPENAI_API_KEY` 🔑 environment variable in the code.
After you deploy your pipeline to Embedchain platform, you can still add more data sources and update the pipeline multiple times.
Here is a Google Colab notebook for you to get started: [![Open in Colab](https://camo.githubusercontent.com/84f0493939e0c4de4e6dbe113251b4bfb5353e57134ffd9fcab6b8714514d4d1/68747470733a2f2f636f6c61622e72657365617263682e676f6f676c652e636f6d2f6173736574732f636f6c61622d62616467652e737667)](https://colab.research.google.com/drive/1YVXaBO4yqlHZY4ho67GCJ6aD4CHNiScD?usp=sharing)
+2 -5
View File
@@ -3,9 +3,6 @@ import importlib.metadata
__version__ = importlib.metadata.version(__package__ or __name__)
from embedchain.apps.app import App # noqa: F401
from embedchain.apps.custom_app import CustomApp # noqa: F401
from embedchain.apps.Llama2App import Llama2App # noqa: F401
from embedchain.apps.open_source_app import OpenSourceApp # noqa: F401
from embedchain.apps.PersonApp import (PersonApp, # noqa: F401
PersonOpenSourceApp)
from embedchain.client import Client # noqa: F401
from embedchain.pipeline import Pipeline # noqa: F401
from embedchain.vectordb.chroma import ChromaDB # noqa: F401
-38
View File
@@ -1,38 +0,0 @@
import logging
from typing import Optional
from embedchain.apps.app import App
from embedchain.config import CustomAppConfig
from embedchain.helper.json_serializable import register_deserializable
from embedchain.llm.llama2 import Llama2Llm
@register_deserializable
class Llama2App(App):
"""
The EmbedChain Llama2App class.
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.
.. deprecated:: 0.0.64
Use `App` instead.
"""
def __init__(self, config: CustomAppConfig = None, system_prompt: Optional[str] = None):
"""
.. deprecated:: 0.0.64
Use `App` instead.
:param config: CustomAppConfig instance to load as configuration. Optional.
:param system_prompt: System prompt string. Optional.
"""
logging.warning(
"DEPRECATION WARNING: Please use `App` instead of `Llama2App`. "
"`Llama2App` will be removed in a future release. "
"Please refer to https://docs.embedchain.ai/advanced/app_types#llama2app for instructions."
)
super().__init__(config=config, llm=Llama2Llm(), system_prompt=system_prompt)
-94
View File
@@ -1,94 +0,0 @@
from string import Template
from embedchain.apps.app import App
from embedchain.apps.open_source_app import OpenSourceApp
from embedchain.config import BaseLlmConfig
from embedchain.config.apps.base_app_config import BaseAppConfig
from embedchain.config.llm.base_llm_config import (DEFAULT_PROMPT,
DEFAULT_PROMPT_WITH_HISTORY)
from embedchain.helper.json_serializable import register_deserializable
@register_deserializable
class EmbedChainPersonApp:
"""
Base class to create a person bot.
This bot behaves and speaks like a person.
:param person: name of the person, better if its a well known person.
:param config: BaseAppConfig instance to load as configuration.
"""
def __init__(self, person: str, config: BaseAppConfig = None):
"""Initialize a new person app
:param person: Name of the person that's imitated.
:type person: str
:param config: Configuration class instance, defaults to None
:type config: BaseAppConfig, optional
"""
self.person = person
self.person_prompt = f"You are {person}. Whatever you say, you will always say in {person} style." # noqa:E501
super().__init__(config)
def add_person_template_to_config(self, default_prompt: str, config: BaseLlmConfig = None):
"""
This method checks if the config object contains a prompt template
if yes it adds the person prompt to it and return the updated config
else it creates a config object with the default prompt added to the person prompt
:param default_prompt: it is the default prompt for query or chat methods
:type default_prompt: str
:param config: _description_, defaults to None
:type config: BaseLlmConfig, optional
:return: The `ChatConfig` instance to use as configuration options.
:rtype: _type_
"""
template = Template(self.person_prompt + " " + default_prompt)
if config:
if config.template:
# Add person prompt to custom user template
config.template = Template(self.person_prompt + " " + config.template.template)
else:
# If no user template is present, use person prompt with the default template
config.template = template
else:
# if no config is present at all, initialize the config with person prompt and default template
config = BaseLlmConfig(
template=template,
)
return config
@register_deserializable
class PersonApp(EmbedChainPersonApp, App):
"""
The Person app.
Extends functionality from EmbedChainPersonApp and App
"""
def query(self, input_query, config: BaseLlmConfig = None, dry_run=False):
config = self.add_person_template_to_config(DEFAULT_PROMPT, config, where=None)
return super().query(input_query, config, dry_run, where=None)
def chat(self, input_query, config: BaseLlmConfig = None, dry_run=False, where=None):
config = self.add_person_template_to_config(DEFAULT_PROMPT_WITH_HISTORY, config)
return super().chat(input_query, config, dry_run, where)
@register_deserializable
class PersonOpenSourceApp(EmbedChainPersonApp, OpenSourceApp):
"""
The Person app.
Extends functionality from EmbedChainPersonApp and OpenSourceApp
"""
def query(self, input_query, config: BaseLlmConfig = None, dry_run=False):
config = self.add_person_template_to_config(DEFAULT_PROMPT, config)
return super().query(input_query, config, dry_run)
def chat(self, input_query, config: BaseLlmConfig = None, dry_run=False):
config = self.add_person_template_to_config(DEFAULT_PROMPT_WITH_HISTORY, config)
return super().chat(input_query, config, dry_run)
+35 -15
View File
@@ -1,12 +1,13 @@
import logging
from typing import Optional
from embedchain.config import (AppConfig, BaseEmbedderConfig, BaseLlmConfig,
ChromaDbConfig)
import yaml
from embedchain.config import AppConfig, BaseEmbedderConfig, BaseLlmConfig
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.helper.json_serializable import register_deserializable
from embedchain.llm.base import BaseLlm
from embedchain.llm.openai import OpenAILlm
@@ -35,7 +36,6 @@ class App(EmbedChain):
db_config: Optional[BaseVectorDbConfig] = None,
embedder: BaseEmbedder = None,
embedder_config: Optional[BaseEmbedderConfig] = None,
chromadb_config: Optional[ChromaDbConfig] = None,
system_prompt: Optional[str] = None,
):
"""
@@ -46,7 +46,7 @@ class App(EmbedChain):
: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 LlmConfig`, defaults to None
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
@@ -60,20 +60,10 @@ class App(EmbedChain):
: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 chromadb_config: Deprecated alias of `db_config`, defaults to None
:type chromadb_config: Optional[ChromaDbConfig], 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.
"""
# Overwrite deprecated arguments
if chromadb_config:
logging.warning(
"DEPRECATION WARNING: Please use `db_config` argument instead of `chromadb_config`."
"`chromadb_config` will be removed in a future release."
)
db_config = chromadb_config
# Type check configs
if config and not isinstance(config, AppConfig):
raise TypeError(
@@ -123,3 +113,33 @@ class App(EmbedChain):
"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)
app_config_data = config_data.get("app", {})
llm_config_data = config_data.get("llm", {})
db_config_data = config_data.get("vectordb", {})
embedder_config_data = config_data.get("embedder", {})
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 = embedder_config_data.get("provider", "openai")
embedder = EmbedderFactory.create(embedder_provider, embedder_config_data.get("config", {}))
return cls(config=app_config, llm=llm, db=db, embedder=embedder)
-63
View File
@@ -1,63 +0,0 @@
import logging
from typing import Optional
from embedchain.apps.app import App
from embedchain.config import CustomAppConfig
from embedchain.embedder.base import BaseEmbedder
from embedchain.helper.json_serializable import register_deserializable
from embedchain.llm.base import BaseLlm
from embedchain.vectordb.base import BaseVectorDB
@register_deserializable
class CustomApp(App):
"""
Embedchain's custom app allows for most flexibility.
You can craft your own mix of various LLMs, vector databases and embedding model/functions.
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.
.. deprecated:: 0.0.64
Use `App` instead.
"""
def __init__(
self,
config: Optional[CustomAppConfig] = None,
llm: BaseLlm = None,
db: BaseVectorDB = None,
embedder: BaseEmbedder = None,
system_prompt: Optional[str] = None,
):
"""
Initialize a new `CustomApp` instance. You have to choose a LLM, database and embedder.
.. deprecated:: 0.0.64
Use `App` instead.
:param config: Config for the app instance. This is the most basic configuration,
that does not fall into the LLM, database or embedder category, defaults to None
:type config: Optional[CustomAppConfig], optional
:param llm: LLM Class instance. example: `from embedchain.llm.openai import OpenAILlm`, defaults to None
:type llm: BaseLlm
:param db: The database to use for storing and retrieving embeddings,
example: `from embedchain.vectordb.chroma_db import ChromaDb`, defaults to None
:type db: BaseVectorDB
:param embedder: The embedder (embedding model and function) use to calculate embeddings.
example: `from embedchain.embedder.gpt4all_embedder import GPT4AllEmbedder`, defaults to None
:type embedder: BaseEmbedder
:param system_prompt: System prompt that will be provided to the LLM as such, defaults to None
:type system_prompt: Optional[str], optional
:raises ValueError: LLM, database or embedder has not been defined.
:raises TypeError: LLM, database or embedder is not a valid class instance.
"""
logging.warning(
"DEPRECATION WARNING: Please use `App` instead of `CustomApp`. "
"`CustomApp` will be removed in a future release. "
"Please refer to https://docs.embedchain.ai/advanced/app_types#opensourceapp for instructions."
)
super().__init__(config=config, llm=llm, db=db, embedder=embedder, system_prompt=system_prompt)
-71
View File
@@ -1,71 +0,0 @@
import logging
from typing import Optional
from embedchain.apps.app import App
from embedchain.config import (BaseLlmConfig, ChromaDbConfig,
OpenSourceAppConfig)
from embedchain.embedder.gpt4all import GPT4AllEmbedder
from embedchain.helper.json_serializable import register_deserializable
from embedchain.llm.gpt4all import GPT4ALLLlm
from embedchain.vectordb.chroma import ChromaDB
gpt4all_model = None
@register_deserializable
class OpenSourceApp(App):
"""
The embedchain Open Source App.
Comes preconfigured with the best open source LLM, embedding model, database.
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.
.. deprecated:: 0.0.64
Use `App` instead.
"""
def __init__(
self,
config: OpenSourceAppConfig = None,
llm_config: BaseLlmConfig = None,
chromadb_config: Optional[ChromaDbConfig] = None,
system_prompt: Optional[str] = None,
):
"""
Initialize a new `CustomApp` instance.
Since it's opinionated you don't have to choose a LLM, database and embedder.
However, you can configure those.
.. deprecated:: 0.0.64
Use `App` instead.
:param config: Config for the app instance. This is the most basic configuration,
that does not fall into the LLM, database or embedder category, defaults to None
:type config: OpenSourceAppConfig, optional
:param llm_config: Allows you to configure the LLM, e.g. how many documents to return.
example: `from embedchain.config import LlmConfig`, defaults to None
:type llm_config: BaseLlmConfig, optional
:param chromadb_config: Allows you to configure the open source database,
example: `from embedchain.config import ChromaDbConfig`, defaults to None
:type chromadb_config: Optional[ChromaDbConfig], optional
:param system_prompt: System prompt that will be provided to the LLM as such.
Please don't use for the time being, as it's not supported., defaults to None
:type system_prompt: Optional[str], optional
:raises TypeError: `OpenSourceAppConfig` or `LlmConfig` invalid.
"""
logging.warning(
"DEPRECATION WARNING: Please use `App` instead of `OpenSourceApp`."
"`OpenSourceApp` will be removed in a future release."
"Please refer to https://docs.embedchain.ai/advanced/app_types#customapp for instructions."
)
super().__init__(
config=config,
llm=GPT4ALLLlm(config=llm_config),
db=ChromaDB(config=chromadb_config),
embedder=GPT4AllEmbedder(),
system_prompt=system_prompt,
)
+5 -5
View File
@@ -1,7 +1,7 @@
from typing import Any
from embedchain import CustomApp
from embedchain.config import AddConfig, CustomAppConfig, LlmConfig
from embedchain import App
from embedchain.config import AddConfig, AppConfig, BaseLlmConfig
from embedchain.embedder.openai import OpenAIEmbedder
from embedchain.helper.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 = CustomApp(config=CustomAppConfig(), llm=OpenAILlm(), db=ChromaDB(), embedder=OpenAIEmbedder())
self.app = App(config=AppConfig(), llm=OpenAILlm(), db=ChromaDB(), embedder=OpenAIEmbedder())
def add(self, data: Any, config: AddConfig = None):
"""
@@ -27,14 +27,14 @@ class BaseBot(JSONSerializable):
config = config if config else AddConfig()
self.app.add(data, config=config)
def query(self, query: str, config: LlmConfig = None) -> str:
def query(self, query: str, config: BaseLlmConfig = None) -> str:
"""
Query the bot
:param query: the user query
:type query: str
:param config: configuration class instance, defaults to None
:type config: LlmConfig, optional
:type config: BaseLlmConfig, optional
:return: Answer
:rtype: str
"""
+13 -4
View File
@@ -10,7 +10,7 @@ class BaseChunker(JSONSerializable):
self.text_splitter = text_splitter
self.data_type = None
def create_chunks(self, loader, src):
def create_chunks(self, loader, src, app_id=None):
"""
Loads data and chunks it.
@@ -18,13 +18,18 @@ class BaseChunker(JSONSerializable):
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.
:param app_id: App id used to generate the doc_id.
"""
documents = []
ids = []
chunk_ids = []
idMap = {}
data_result = loader.load_data(src)
data_records = data_result["data"]
doc_id = data_result["doc_id"]
# Prefix app_id in the document id if app_id is not None to
# distinguish between different documents stored in the same
# elasticsearch or opensearch index
doc_id = f"{app_id}--{doc_id}" if app_id is not None else doc_id
metadatas = []
for data in data_records:
content = data["content"]
@@ -39,14 +44,15 @@ class BaseChunker(JSONSerializable):
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:
idMap[chunk_id] = True
ids.append(chunk_id)
chunk_ids.append(chunk_id)
documents.append(chunk)
metadatas.append(meta_data)
return {
"documents": documents,
"ids": ids,
"ids": chunk_ids,
"metadatas": metadatas,
"doc_id": doc_id,
}
@@ -66,3 +72,6 @@ class BaseChunker(JSONSerializable):
self.data_type = data_type
# TODO: This should be done during initialization. This means it has to be done in the child classes.
def get_word_count(self, documents):
return sum([len(document.split(" ")) for document in documents])
+22
View File
@@ -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.helper.json_serializable import register_deserializable
@register_deserializable
class GmailChunker(BaseChunker):
"""Chunker for gmail."""
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)
+64
View File
@@ -0,0 +1,64 @@
import hashlib
from typing import Optional
from langchain.text_splitter import RecursiveCharacterTextSplitter
from embedchain.chunkers.base_chunker import BaseChunker
from embedchain.config.add_config import ChunkerConfig
class ImagesChunker(BaseChunker):
"""Chunker for an Image."""
def __init__(self, config: Optional[ChunkerConfig] = None):
if config is None:
config = ChunkerConfig(chunk_size=300, chunk_overlap=0, length_function=len)
image_splitter = RecursiveCharacterTextSplitter(
chunk_size=config.chunk_size,
chunk_overlap=config.chunk_overlap,
length_function=config.length_function,
)
super().__init__(image_splitter)
def create_chunks(self, loader, src, app_id=None):
"""
Loads the image(s), and creates their corresponding embedding. This creates one chunk for each image
: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.
"""
documents = []
embeddings = []
ids = []
data_result = loader.load_data(src)
data_records = data_result["data"]
doc_id = data_result["doc_id"]
doc_id = f"{app_id}--{doc_id}" if app_id is not None else doc_id
metadatas = []
for data in data_records:
meta_data = data["meta_data"]
# add data type to meta data to allow query using data type
meta_data["data_type"] = self.data_type.value
chunk_id = hashlib.sha256(meta_data["url"].encode()).hexdigest()
ids.append(chunk_id)
documents.append(data["content"])
embeddings.append(data["embedding"])
meta_data["doc_id"] = doc_id
metadatas.append(meta_data)
return {
"documents": documents,
"embeddings": embeddings,
"ids": ids,
"metadatas": metadatas,
"doc_id": doc_id,
}
def get_word_count(self, documents):
"""
The number of chunks and the corresponding word count for an image is fixed to 1, as 1 embedding is created for
each image
"""
return 1
+22
View File
@@ -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.helper.json_serializable import register_deserializable
@register_deserializable
class JSONChunker(BaseChunker):
"""Chunker for json."""
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)
+18
View File
@@ -0,0 +1,18 @@
from typing import Optional
from langchain.text_splitter import RecursiveCharacterTextSplitter
from embedchain.chunkers.base_chunker import BaseChunker
from embedchain.config.add_config import ChunkerConfig
class OpenAPIChunker(BaseChunker):
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)
+22
View File
@@ -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.helper.json_serializable import register_deserializable
@register_deserializable
class SitemapChunker(BaseChunker):
"""Chunker for sitemap."""
def __init__(self, config: Optional[ChunkerConfig] = None):
if config is None:
config = ChunkerConfig(chunk_size=500, 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)
+22
View File
@@ -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.helper.json_serializable import register_deserializable
@register_deserializable
class UnstructuredFileChunker(BaseChunker):
"""Chunker for Unstructured file."""
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)
+22
View File
@@ -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.helper.json_serializable import register_deserializable
@register_deserializable
class XmlChunker(BaseChunker):
"""Chunker for XML files."""
def __init__(self, config: Optional[ChunkerConfig] = None):
if config is None:
config = ChunkerConfig(chunk_size=500, chunk_overlap=50, 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)
+102
View File
@@ -0,0 +1,102 @@
import json
import logging
import os
import uuid
import requests
from embedchain.embedchain import CONFIG_DIR, CONFIG_FILE
class Client:
def __init__(self, api_key=None, host="https://apiv2.embedchain.ai"):
self.config_data = self.load_config()
self.host = host
if api_key:
if self.check(api_key):
self.api_key = api_key
self.save()
else:
raise ValueError(
"Invalid API key provided. You can find your API key on https://app.embedchain.ai/settings/keys."
)
else:
if "api_key" in self.config_data:
self.api_key = self.config_data["api_key"]
logging.info("API key loaded successfully!")
else:
raise ValueError(
"You are not logged in. Please obtain an API key from https://app.embedchain.ai/settings/keys/"
)
@classmethod
def setup_dir(self):
"""
Loads the user id from the config file if it exists, otherwise generates a new
one and saves it to the config file.
:return: user id
:rtype: str
"""
if not os.path.exists(CONFIG_DIR):
os.makedirs(CONFIG_DIR)
if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, "r") as f:
data = json.load(f)
if "user_id" in data:
return data["user_id"]
u_id = str(uuid.uuid4())
with open(CONFIG_FILE, "w") as f:
json.dump({"user_id": u_id}, f)
@classmethod
def load_config(cls):
if not os.path.exists(CONFIG_FILE):
cls.setup_dir()
with open(CONFIG_FILE, "r") as config_file:
return json.load(config_file)
def save(self):
self.config_data["api_key"] = self.api_key
with open(CONFIG_FILE, "w") as config_file:
json.dump(self.config_data, config_file, indent=4)
logging.info("API key saved successfully!")
def clear(self):
if "api_key" in self.config_data:
del self.config_data["api_key"]
with open(CONFIG_FILE, "w") as config_file:
json.dump(self.config_data, config_file, indent=4)
self.api_key = None
logging.info("API key deleted successfully!")
else:
logging.warning("API key not found in the configuration file.")
def update(self, api_key):
if self.check(api_key):
self.api_key = api_key
self.save()
logging.info("API key updated successfully!")
else:
logging.warning("Invalid API key provided. API key not updated.")
def check(self, api_key):
validation_url = f"{self.host}/api/v1/accounts/api_keys/validate/"
response = requests.post(validation_url, headers={"Authorization": f"Token {api_key}"})
if response.status_code == 200:
return True
else:
logging.warning(f"Response from API: {response.text}")
logging.warning("Invalid API key. Unable to validate.")
return False
def get(self):
return self.api_key
def __str__(self):
return self.api_key
+3 -4
View File
@@ -2,13 +2,12 @@
from .add_config import AddConfig, ChunkerConfig
from .apps.app_config import AppConfig
from .apps.custom_app_config import CustomAppConfig
from .apps.open_source_app_config import OpenSourceAppConfig
from .base_config import BaseConfig
from .embedder.base import BaseEmbedderConfig
from .embedder.base import BaseEmbedderConfig as EmbedderConfig
from .llm.base_llm_config import BaseLlmConfig
from .llm.base_llm_config import BaseLlmConfig as LlmConfig
from .llm.base import BaseLlmConfig
from .pipeline_config import PipelineConfig
from .vectordb.chroma import ChromaDbConfig
from .vectordb.elasticsearch import ElasticsearchDBConfig
from .vectordb.opensearch import OpenSearchDBConfig
from .vectordb.zilliz import ZillizDBConfig
+1 -1
View File
@@ -8,7 +8,7 @@ from embedchain.vectordb.base import BaseVectorDB
class BaseAppConfig(BaseConfig, JSONSerializable):
"""
Parent config to initialize an instance of `App`, `OpenSourceApp` or `CustomApp`.
Parent config to initialize an instance of `App`.
"""
def __init__(
@@ -1,40 +0,0 @@
from typing import Optional
from embedchain.helper.json_serializable import register_deserializable
from .base_app_config import BaseAppConfig
@register_deserializable
class OpenSourceAppConfig(BaseAppConfig):
"""
Config to initialize an embedchain custom `OpenSourceApp` instance, with extra config options.
"""
def __init__(
self,
log_level: str = "WARNING",
id: Optional[str] = None,
collect_metrics: Optional[bool] = None,
model: str = "orca-mini-3b.ggmlv3.q4_0.bin",
collection_name: Optional[str] = None,
):
"""
Initializes a configuration class instance for an Open Source App.
:param log_level: Debug level ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], defaults to "WARNING"
:type log_level: str, optional
:param id: ID of the app. Document metadata will have this id., defaults to None
:type id: Optional[str], optional
:param collect_metrics: Send anonymous telemetry to improve embedchain, defaults to True
:type collect_metrics: Optional[bool], optional
:param model: GPT4ALL uses the model to instantiate the class.
Unlike `App`, it has to be provided before querying, defaults to "orca-mini-3b.ggmlv3.q4_0.bin"
:type model: str, optional
:param collection_name: Default collection name. It's recommended to use app.db.set_collection_name() instead,
defaults to None
:type collection_name: Optional[str], optional
"""
self.model = model or "orca-mini-3b.ggmlv3.q4_0.bin"
super().__init__(log_level=log_level, id=id, collect_metrics=collect_metrics, collection_name=collection_name)
@@ -67,12 +67,12 @@ class BaseLlmConfig(BaseConfig):
deployment_name: Optional[str] = None,
system_prompt: Optional[str] = None,
where: Dict[str, Any] = None,
query_type: Optional[str] = None,
):
"""
Initializes a configuration class instance for the LLM.
Takes the place of the former `QueryConfig` or `ChatConfig`.
Use `LlmConfig` as an alias to `BaseLlmConfig`.
:param number_documents: Number of documents to pull from the database as
context, defaults to 1
@@ -112,6 +112,10 @@ class BaseLlmConfig(BaseConfig):
self.top_p = top_p
self.deployment_name = deployment_name
self.system_prompt = system_prompt
self.query_type = query_type
if type(template) is str:
template = Template(template)
if self.validate_template(template):
self.template = template
@@ -1,17 +1,12 @@
from typing import Optional
from dotenv import load_dotenv
from embedchain.helper.json_serializable import register_deserializable
from embedchain.vectordb.base import BaseVectorDB
from .base_app_config import BaseAppConfig
load_dotenv()
from .apps.base_app_config import BaseAppConfig
@register_deserializable
class CustomAppConfig(BaseAppConfig):
class PipelineConfig(BaseAppConfig):
"""
Config to initialize an embedchain custom `App` instance, with extra config options.
"""
@@ -19,20 +14,16 @@ class CustomAppConfig(BaseAppConfig):
def __init__(
self,
log_level: str = "WARNING",
db: Optional[BaseVectorDB] = None,
id: Optional[str] = None,
collect_metrics: Optional[bool] = None,
collection_name: Optional[str] = None,
name: Optional[str] = None,
collect_metrics: Optional[bool] = False,
):
"""
Initializes a configuration class instance for an Custom App.
Most of the configuration is done in the `CustomApp` class itself.
Initializes a configuration class instance for an App. This is the simplest form of an embedchain app.
Most of the configuration is done in the `App` class itself.
:param log_level: Debug level ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], defaults to "WARNING"
:type log_level: str, optional
:param db: A database class. It is recommended to set this directly in the `CustomApp` class, not this config,
defaults to None
:type db: Optional[BaseVectorDB], optional
:param id: ID of the app. Document metadata will have this id., defaults to None
:type id: Optional[str], optional
:param collect_metrics: Send anonymous telemetry to improve embedchain, defaults to True
@@ -41,6 +32,7 @@ class CustomAppConfig(BaseAppConfig):
defaults to None
:type collection_name: Optional[str], optional
"""
super().__init__(
log_level=log_level, db=db, id=id, collect_metrics=collect_metrics, collection_name=collection_name
)
self._setup_logging(log_level)
self.id = id
self.name = name
self.collect_metrics = collect_metrics
+7
View File
@@ -10,6 +10,7 @@ class BaseVectorDbConfig(BaseConfig):
dir: str = "db",
host: Optional[str] = None,
port: Optional[str] = None,
**kwargs,
):
"""
Initializes a configuration class instance for the vector database.
@@ -22,8 +23,14 @@ class BaseVectorDbConfig(BaseConfig):
:type host: Optional[str], optional
:param host: Database connection remote port. Use this if you run Embedchain as a client, defaults to None
:type port: Optional[str], optional
:param kwargs: Additional keyword arguments
:type kwargs: dict
"""
self.collection_name = collection_name or "embedchain_store"
self.dir = dir
self.host = host
self.port = port
# Assign additional keyword arguments
if kwargs:
for key, value in kwargs.items():
setattr(self, key, value)
+20
View File
@@ -0,0 +1,20 @@
from typing import Dict, Optional
from embedchain.config.vectordb.base import BaseVectorDbConfig
from embedchain.helper.json_serializable import register_deserializable
@register_deserializable
class PineconeDBConfig(BaseVectorDbConfig):
def __init__(
self,
collection_name: Optional[str] = None,
dir: Optional[str] = None,
vector_dimension: int = 1536,
metric: Optional[str] = "cosine",
**extra_params: Dict[str, any],
):
self.metric = metric
self.vector_dimension = vector_dimension
self.extra_params = extra_params
super().__init__(collection_name=collection_name, dir=dir)
+44
View File
@@ -0,0 +1,44 @@
from typing import Dict, Optional
from embedchain.config.vectordb.base import BaseVectorDbConfig
from embedchain.helper.json_serializable import register_deserializable
@register_deserializable
class QdrantDBConfig(BaseVectorDbConfig):
"""
Config to initialize an qdrant client.
:param url. qdrant url or list of nodes url to be used for connection
"""
def __init__(
self,
collection_name: Optional[str] = None,
dir: Optional[str] = None,
hnsw_config: Optional[Dict[str, any]] = None,
quantization_config: Optional[Dict[str, any]] = None,
on_disk: Optional[bool] = None,
**extra_params: Dict[str, any],
):
"""
Initializes a configuration class instance for a qdrant client.
:param collection_name: Default name for the collection, defaults to None
:type collection_name: Optional[str], optional
:param dir: Path to the database directory, where the database is stored, defaults to None
:type dir: Optional[str], optional
:param hnsw_config: Params for HNSW index
:type hnsw_config: Optional[Dict[str, any]], defaults to None
:param quantization_config: Params for quantization, if None - quantization will be disabled
:type quantization_config: Optional[Dict[str, any]], defaults to None
:param on_disk: If true - point`s payload will not be stored in memory.
It will be read from the disk every time it is requested.
This setting saves RAM by (slightly) increasing the response time.
Note: those payload values that are involved in filtering and are indexed - remain in RAM.
:type on_disk: bool, optional, defaults to None
"""
self.hnsw_config = hnsw_config
self.quantization_config = quantization_config
self.on_disk = on_disk
self.extra_params = extra_params
super().__init__(collection_name=collection_name, dir=dir)
+16
View File
@@ -0,0 +1,16 @@
from typing import Dict, Optional
from embedchain.config.vectordb.base import BaseVectorDbConfig
from embedchain.helper.json_serializable import register_deserializable
@register_deserializable
class WeaviateDBConfig(BaseVectorDbConfig):
def __init__(
self,
collection_name: Optional[str] = None,
dir: Optional[str] = None,
**extra_params: Dict[str, any],
):
self.extra_params = extra_params
super().__init__(collection_name=collection_name, dir=dir)
+49
View File
@@ -0,0 +1,49 @@
import os
from typing import Optional
from embedchain.config.vectordb.base import BaseVectorDbConfig
from embedchain.helper.json_serializable import register_deserializable
@register_deserializable
class ZillizDBConfig(BaseVectorDbConfig):
def __init__(
self,
collection_name: Optional[str] = None,
dir: Optional[str] = None,
uri: Optional[str] = None,
token: Optional[str] = None,
vector_dim: Optional[str] = None,
metric_type: Optional[str] = None,
):
"""
Initializes a configuration class instance for the vector database.
:param collection_name: Default name for the collection, defaults to None
:type collection_name: Optional[str], optional
:param dir: Path to the database directory, where the database is stored, defaults to "db"
:type dir: str, optional
:param uri: Cluster endpoint obtained from the Zilliz Console, defaults to None
:type uri: Optional[str], optional
:param token: API Key, if a Serverless Cluster, username:password, if a Dedicated Cluster, defaults to None
:type port: Optional[str], optional
"""
self.uri = uri or os.environ.get("ZILLIZ_CLOUD_URI")
if not self.uri:
raise AttributeError(
"Zilliz needs a URI attribute, "
"this can either be passed to `ZILLIZ_CLOUD_URI` or as `ZILLIZ_CLOUD_URI` in `.env`"
)
self.token = token or os.environ.get("ZILLIZ_CLOUD_TOKEN")
if not self.token:
raise AttributeError(
"Zilliz needs a token attribute, "
"this can either be passed to `ZILLIZ_CLOUD_TOKEN` or as `ZILLIZ_CLOUD_TOKEN` in `.env`,"
"if having a username and password, pass it in the form 'username:password' to `ZILLIZ_CLOUD_TOKEN`"
)
self.metric_type = metric_type if metric_type else "L2"
self.vector_dim = vector_dim
super().__init__(collection_name=collection_name, dir=dir)
+26 -1
View File
@@ -1,13 +1,20 @@
from embedchain.chunkers.base_chunker import BaseChunker
from embedchain.chunkers.docs_site import DocsSiteChunker
from embedchain.chunkers.docx_file import DocxFileChunker
from embedchain.chunkers.gmail import GmailChunker
from embedchain.chunkers.images import ImagesChunker
from embedchain.chunkers.json import JSONChunker
from embedchain.chunkers.mdx import MdxChunker
from embedchain.chunkers.notion import NotionChunker
from embedchain.chunkers.openapi import OpenAPIChunker
from embedchain.chunkers.pdf_file import PdfFileChunker
from embedchain.chunkers.qna_pair import QnaPairChunker
from embedchain.chunkers.sitemap import SitemapChunker
from embedchain.chunkers.table import TableChunker
from embedchain.chunkers.text import TextChunker
from embedchain.chunkers.unstructured_file import UnstructuredFileChunker
from embedchain.chunkers.web_page import WebPageChunker
from embedchain.chunkers.xml import XmlChunker
from embedchain.chunkers.youtube_video import YoutubeVideoChunker
from embedchain.config import AddConfig
from embedchain.config.add_config import ChunkerConfig, LoaderConfig
@@ -16,12 +23,18 @@ from embedchain.loaders.base_loader import BaseLoader
from embedchain.loaders.csv import CsvLoader
from embedchain.loaders.docs_site_loader import DocsSiteLoader
from embedchain.loaders.docx_file import DocxFileLoader
from embedchain.loaders.gmail import GmailLoader
from embedchain.loaders.images import ImagesLoader
from embedchain.loaders.json import JSONLoader
from embedchain.loaders.local_qna_pair import LocalQnaPairLoader
from embedchain.loaders.local_text import LocalTextLoader
from embedchain.loaders.mdx import MdxLoader
from embedchain.loaders.openapi import OpenAPILoader
from embedchain.loaders.pdf_file import PdfFileLoader
from embedchain.loaders.sitemap import SitemapLoader
from embedchain.loaders.unstructured_file import UnstructuredLoader
from embedchain.loaders.web_page import WebPageLoader
from embedchain.loaders.xml import XmlLoader
from embedchain.loaders.youtube_video import YoutubeVideoLoader
from embedchain.models.data_type import DataType
@@ -65,9 +78,15 @@ class DataFormatter(JSONSerializable):
DataType.TEXT: LocalTextLoader,
DataType.DOCX: DocxFileLoader,
DataType.SITEMAP: SitemapLoader,
DataType.XML: XmlLoader,
DataType.DOCS_SITE: DocsSiteLoader,
DataType.CSV: CsvLoader,
DataType.MDX: MdxLoader,
DataType.IMAGES: ImagesLoader,
DataType.UNSTRUCTURED: UnstructuredLoader,
DataType.JSON: JSONLoader,
DataType.OPENAPI: OpenAPILoader,
DataType.GMAIL: GmailLoader,
}
lazy_loaders = {DataType.NOTION}
if data_type in loaders:
@@ -102,11 +121,17 @@ class DataFormatter(JSONSerializable):
DataType.QNA_PAIR: QnaPairChunker,
DataType.TEXT: TextChunker,
DataType.DOCX: DocxFileChunker,
DataType.WEB_PAGE: WebPageChunker,
DataType.DOCS_SITE: DocsSiteChunker,
DataType.SITEMAP: SitemapChunker,
DataType.NOTION: NotionChunker,
DataType.CSV: TableChunker,
DataType.MDX: MdxChunker,
DataType.IMAGES: ImagesChunker,
DataType.XML: XmlChunker,
DataType.UNSTRUCTURED: UnstructuredFileChunker,
DataType.JSON: JSONChunker,
DataType.OPENAPI: OpenAPIChunker,
DataType.GMAIL: GmailChunker,
}
if data_type in chunker_classes:
chunker_class: type = chunker_classes[data_type]
+111 -42
View File
@@ -3,6 +3,7 @@ import importlib.metadata
import json
import logging
import os
import sqlite3
import threading
import uuid
from pathlib import Path
@@ -32,6 +33,7 @@ ABS_PATH = os.getcwd()
HOME_DIR = str(Path.home())
CONFIG_DIR = os.path.join(HOME_DIR, ".embedchain")
CONFIG_FILE = os.path.join(CONFIG_DIR, "config.json")
SQLITE_PATH = os.path.join(CONFIG_DIR, "embedchain.db")
class EmbedChain(JSONSerializable):
@@ -89,6 +91,27 @@ class EmbedChain(JSONSerializable):
# Send anonymous telemetry
self.s_id = self.config.id if self.config.id else str(uuid.uuid4())
self.u_id = self._load_or_generate_user_id()
# Establish a connection to the SQLite database
self.connection = sqlite3.connect(SQLITE_PATH)
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()
# NOTE: Uncomment the next two lines when running tests to see if any test fires a telemetry event.
# if (self.config.collect_metrics):
# raise ConnectionRefusedError("Collection of metrics should not be allowed.")
@@ -163,7 +186,7 @@ class EmbedChain(JSONSerializable):
:raises ValueError: Invalid data type
:param dry_run: Optional. A dry run displays the chunks to ensure that the loader and chunker work as intended.
deafaults to False
:return: source_id, a md5-hash of the source, in hexadecimal representation.
:return: source_hash, a md5-hash of the source, in hexadecimal representation.
:rtype: str
"""
if config is None:
@@ -192,18 +215,40 @@ class EmbedChain(JSONSerializable):
if not data_type:
data_type = detect_datatype(source)
# `source_id` is the hash of the source argument
# `source_hash` is the md5 hash of the source argument
hash_object = hashlib.md5(str(source).encode("utf-8"))
source_id = hash_object.hexdigest()
source_hash = hash_object.hexdigest()
# Check if the data hash already exists, if so, skip the addition
self.cursor.execute(
"SELECT 1 FROM data_sources WHERE hash = ? AND pipeline_id = ?", (source_hash, self.config.id)
)
existing_data = self.cursor.fetchone()
if existing_data:
print(f"Data with hash {source_hash} already exists. Skipping addition.")
return source_hash
data_formatter = DataFormatter(data_type, config)
self.user_asks.append([source, data_type.value, metadata])
documents, metadatas, _ids, new_chunks = self.load_and_embed(
data_formatter.loader, data_formatter.chunker, source, metadata, source_id, dry_run
data_formatter.loader, data_formatter.chunker, source, metadata, source_hash, dry_run
)
if data_type in {DataType.DOCS_SITE}:
self.is_docs_site_instance = True
# Insert the data into the 'data' table
self.cursor.execute(
"""
INSERT INTO data_sources (hash, pipeline_id, type, value, metadata)
VALUES (?, ?, ?, ?, ?)
""",
(source_hash, self.config.id, data_type.value, str(source), json.dumps(metadata)),
)
# Commit the transaction
self.connection.commit()
if dry_run:
data_chunks_info = {"chunks": documents, "metadata": metadatas, "count": len(documents), "type": data_type}
logging.debug(f"Dry run info : {data_chunks_info}")
@@ -212,13 +257,13 @@ class EmbedChain(JSONSerializable):
# Send anonymous telemetry
if self.config.collect_metrics:
# it's quicker to check the variable twice than to count words when they won't be submitted.
word_count = sum([len(document.split(" ")) for document in documents])
word_count = data_formatter.chunker.get_word_count(documents)
extra_metadata = {"data_type": data_type.value, "word_count": word_count, "chunks_count": new_chunks}
thread_telemetry = threading.Thread(target=self._send_telemetry_event, args=("add", extra_metadata))
thread_telemetry.start()
return source_id
return source_hash
def add_local(
self,
@@ -245,7 +290,7 @@ class EmbedChain(JSONSerializable):
:param config: The `AddConfig` instance to use as configuration options., defaults to None
:type config: Optional[AddConfig], optional
:raises ValueError: Invalid data type
:return: source_id, a md5-hash of the source, in hexadecimal representation.
:return: source_hash, a md5-hash of the source, in hexadecimal representation.
:rtype: str
"""
logging.warning(
@@ -268,14 +313,16 @@ class EmbedChain(JSONSerializable):
elif chunker.data_type.value in [item.value for item in IndirectDataType]:
# These types have a indirect source reference
# As long as the reference is the same, they can be updated.
existing_embeddings_data = self.db.get(
where={
"url": src,
},
where = {"url": src}
if self.config.id is not None:
where.update({"app_id": self.config.id})
existing_embeddings = self.db.get(
where=where,
limit=1,
)
if len(existing_embeddings_data.get("metadatas", [])) > 0:
return existing_embeddings_data["metadatas"][0]["doc_id"]
if len(existing_embeddings.get("metadatas", [])) > 0:
return existing_embeddings["metadatas"][0]["doc_id"]
else:
return None
elif chunker.data_type.value in [item.value for item in SpecialDataType]:
@@ -283,14 +330,16 @@ class EmbedChain(JSONSerializable):
# Through custom logic, they can be attributed to a source and be updated.
if chunker.data_type == DataType.QNA_PAIR:
# QNA_PAIRs update the answer if the question already exists.
existing_embeddings_data = self.db.get(
where={
"question": src[0],
},
where = {"question": src[0]}
if self.config.id is not None:
where.update({"app_id": self.config.id})
existing_embeddings = self.db.get(
where=where,
limit=1,
)
if len(existing_embeddings_data.get("metadatas", [])) > 0:
return existing_embeddings_data["metadatas"][0]["doc_id"]
if len(existing_embeddings.get("metadatas", [])) > 0:
return existing_embeddings["metadatas"][0]["doc_id"]
else:
return None
else:
@@ -309,7 +358,7 @@ class EmbedChain(JSONSerializable):
chunker: BaseChunker,
src: Any,
metadata: Optional[Dict[str, Any]] = None,
source_id: Optional[str] = None,
source_hash: Optional[str] = None,
dry_run=False,
):
"""
@@ -320,22 +369,21 @@ class EmbedChain(JSONSerializable):
:param src: The data to be handled by the loader. Can be a URL for
remote sources or local content for local loaders.
:param metadata: Optional. Metadata associated with the data source.
:param source_id: Hexadecimal hash of the source.
:param source_hash: Hexadecimal hash of the source.
:param dry_run: Optional. A dry run returns chunks and doesn't update DB.
:type dry_run: bool, defaults to False
:return: (List) documents (embedded text), (List) metadata, (list) ids, (int) number of chunks
"""
existing_doc_id = self._get_existing_doc_id(chunker=chunker, src=src)
app_id = self.config.id if self.config is not None else None
# Create chunks
embeddings_data = chunker.create_chunks(loader, src)
embeddings_data = chunker.create_chunks(loader, src, app_id=app_id)
# spread chunking results
documents = embeddings_data["documents"]
metadatas = embeddings_data["metadatas"]
ids = embeddings_data["ids"]
new_doc_id = embeddings_data["doc_id"]
if existing_doc_id and existing_doc_id == new_doc_id:
print("Doc content has not changed. Skipping creating chunks and embeddings")
return [], [], [], 0
@@ -346,14 +394,16 @@ class EmbedChain(JSONSerializable):
self.db.delete({"doc_id": existing_doc_id})
# get existing ids, and discard doc if any common id exist.
where = {"app_id": self.config.id} if self.config.id is not None else {}
# where={"url": src}
db_result = self.db.get(
ids=ids,
where=where, # optional filter
)
existing_ids = set(db_result["ids"])
where = {"url": src}
# if data type is qna_pair, we check for question
if chunker.data_type == DataType.QNA_PAIR:
where = {"question": src[0]}
if self.config.id is not None:
where["app_id"] = self.config.id
db_result = self.db.get(ids=ids, where=where) # optional filter
existing_ids = set(db_result["ids"])
if len(existing_ids):
data_dict = {id: (doc, meta) for id, doc, meta in zip(ids, documents, metadatas)}
data_dict = {id: value for id, value in data_dict.items() if id not in existing_ids}
@@ -377,7 +427,7 @@ class EmbedChain(JSONSerializable):
m["app_id"] = self.config.id
# Add hashed source
m["hash"] = source_id
m["hash"] = source_hash
# Note: Metadata is the function argument
if metadata:
@@ -393,8 +443,15 @@ class EmbedChain(JSONSerializable):
# Count before, to calculate a delta in the end.
chunks_before_addition = self.db.count()
self.db.add(documents=documents, metadatas=metadatas, ids=ids)
self.db.add(
embeddings=embeddings_data.get("embeddings", None),
documents=documents,
metadatas=metadatas,
ids=ids,
skip_embedding=(chunker.data_type == DataType.IMAGES),
)
count_new_chunks = self.db.count() - chunks_before_addition
print((f"Successfully saved {src} ({chunker.data_type}). New chunks count: {count_new_chunks}"))
return list(documents), metadatas, ids, count_new_chunks
@@ -423,7 +480,6 @@ class EmbedChain(JSONSerializable):
:rtype: List[str]
"""
query_config = config or self.llm.config
if where is not None:
where = where
elif query_config is not None and query_config.where is not None:
@@ -434,13 +490,27 @@ class EmbedChain(JSONSerializable):
if self.config.id is not None:
where.update({"app_id": self.config.id})
contents = self.db.query(
input_query=input_query,
# We cannot query the database with the input query in case of an image search. This is because we need
# to bring down both the image and text to the same dimension to be able to compare them.
db_query = input_query
if hasattr(config, "query_type") and config.query_type == "Images":
# We import the clip processor here to make sure the package is not dependent on clip dependency even if the
# image dataset is not being used
from embedchain.models.clip_processor import ClipProcessor
db_query = ClipProcessor.get_text_features(query=input_query)
contexts = self.db.query(
input_query=db_query,
n_results=query_config.number_documents,
where=where,
skip_embedding=(hasattr(config, "query_type") and config.query_type == "Images"),
)
return contents
if len(contexts) > 0 and isinstance(contexts[0], tuple):
contexts = list(map(lambda x: x[0], contexts))
return contexts
def query(self, input_query: str, config: BaseLlmConfig = None, dry_run=False, where: Optional[Dict] = None) -> str:
"""
@@ -450,7 +520,7 @@ class EmbedChain(JSONSerializable):
:param input_query: The query to use.
:type input_query: str
:param config: The `LlmConfig` instance to use as configuration options. This is used for one method call.
:param config: The `BaseLlmConfig` instance to use as configuration options. This is used for one method call.
To persistently use a config, declare it during app init., defaults to None
:type config: Optional[BaseLlmConfig], optional
:param dry_run: A dry run does everything except send the resulting prompt to
@@ -486,7 +556,7 @@ class EmbedChain(JSONSerializable):
:param input_query: The query to use.
:type input_query: str
:param config: The `LlmConfig` instance to use as configuration options. This is used for one method call.
:param config: The `BaseLlmConfig` instance to use as configuration options. This is used for one method call.
To persistently use a config, declare it during app init., defaults to None
:type config: Optional[BaseLlmConfig], optional
:param dry_run: A dry run does everything except send the resulting prompt to
@@ -537,15 +607,14 @@ class EmbedChain(JSONSerializable):
"""
Resets the database. Deletes all embeddings irreversibly.
`App` does not have to be reinitialized after using this method.
DEPRECATED IN FAVOR OF `db.reset()`
"""
# Send anonymous telemetry
thread_telemetry = threading.Thread(target=self._send_telemetry_event, args=("reset",))
thread_telemetry.start()
logging.warning("DEPRECATION WARNING: Please use `app.db.reset()` instead of `App.reset()`.")
self.db.reset()
self.cursor.execute("DELETE FROM data_sources WHERE pipeline_id = ?", (self.config.id,))
self.connection.commit()
@retry(stop=stop_after_attempt(3), wait=wait_fixed(1))
def _send_telemetry_event(self, method: str, extra_metadata: Optional[dict] = None):
+5 -6
View File
@@ -1,7 +1,5 @@
from typing import Optional
from chromadb.utils import embedding_functions
from embedchain.config import BaseEmbedderConfig
from embedchain.embedder.base import BaseEmbedder
from embedchain.models import VectorDimensions
@@ -9,12 +7,13 @@ from embedchain.models import VectorDimensions
class GPT4AllEmbedder(BaseEmbedder):
def __init__(self, config: Optional[BaseEmbedderConfig] = None):
# Note: We could use langchains GPT4ALL embedding, but it's not available in all versions.
super().__init__(config=config)
if self.config.model is None:
self.config.model = "all-MiniLM-L6-v2"
embedding_fn = embedding_functions.SentenceTransformerEmbeddingFunction(model_name=self.config.model)
from langchain.embeddings import \
GPT4AllEmbeddings as LangchainGPT4AllEmbeddings
embeddings = LangchainGPT4AllEmbeddings()
embedding_fn = BaseEmbedder._langchain_default_concept(embeddings)
self.set_embedding_fn(embedding_fn=embedding_fn)
vector_dimension = VectorDimensions.GPT4ALL.value
+1 -1
View File
@@ -7,7 +7,7 @@ from embedchain.embedder.base import BaseEmbedder
from embedchain.models import VectorDimensions
class VertexAiEmbedder(BaseEmbedder):
class VertexAIEmbedder(BaseEmbedder):
def __init__(self, config: Optional[BaseEmbedderConfig] = None):
super().__init__(config=config)
+99
View File
@@ -0,0 +1,99 @@
import importlib
def load_class(class_type):
module_path, class_name = class_type.rsplit(".", 1)
module = importlib.import_module(module_path)
return getattr(module, class_name)
class LlmFactory:
provider_to_class = {
"anthropic": "embedchain.llm.anthropic.AnthropicLlm",
"azure_openai": "embedchain.llm.azure_openai.AzureOpenAILlm",
"cohere": "embedchain.llm.cohere.CohereLlm",
"gpt4all": "embedchain.llm.gpt4all.GPT4ALLLlm",
"huggingface": "embedchain.llm.huggingface.HuggingFaceLlm",
"jina": "embedchain.llm.jina.JinaLlm",
"llama2": "embedchain.llm.llama2.Llama2Llm",
"openai": "embedchain.llm.openai.OpenAILlm",
"vertexai": "embedchain.llm.vertex_ai.VertexAILlm",
}
provider_to_config_class = {
"embedchain": "embedchain.config.llm.base.BaseLlmConfig",
"openai": "embedchain.config.llm.base.BaseLlmConfig",
"anthropic": "embedchain.config.llm.base.BaseLlmConfig",
}
@classmethod
def create(cls, provider_name, config_data):
class_type = cls.provider_to_class.get(provider_name)
# Default to embedchain base config if the provider is not in the config map
config_name = "embedchain" if provider_name not in cls.provider_to_config_class else provider_name
config_class_type = cls.provider_to_config_class.get(config_name)
if class_type:
llm_class = load_class(class_type)
llm_config_class = load_class(config_class_type)
return llm_class(config=llm_config_class(**config_data))
else:
raise ValueError(f"Unsupported Llm provider: {provider_name}")
class EmbedderFactory:
provider_to_class = {
"azure_openai": "embedchain.embedder.openai.OpenAIEmbedder",
"gpt4all": "embedchain.embedder.gpt4all.GPT4AllEmbedder",
"huggingface": "embedchain.embedder.huggingface.HuggingFaceEmbedder",
"openai": "embedchain.embedder.openai.OpenAIEmbedder",
"vertexai": "embedchain.embedder.vertexai.VertexAIEmbedder",
}
provider_to_config_class = {
"azure_openai": "embedchain.config.embedder.base.BaseEmbedderConfig",
"openai": "embedchain.config.embedder.base.BaseEmbedderConfig",
"gpt4all": "embedchain.config.embedder.base.BaseEmbedderConfig",
}
@classmethod
def create(cls, provider_name, config_data):
class_type = cls.provider_to_class.get(provider_name)
# Default to openai config if the provider is not in the config map
config_name = "openai" if provider_name not in cls.provider_to_config_class else provider_name
config_class_type = cls.provider_to_config_class.get(config_name)
if class_type:
embedder_class = load_class(class_type)
embedder_config_class = load_class(config_class_type)
return embedder_class(config=embedder_config_class(**config_data))
else:
raise ValueError(f"Unsupported Embedder provider: {provider_name}")
class VectorDBFactory:
provider_to_class = {
"chroma": "embedchain.vectordb.chroma.ChromaDB",
"elasticsearch": "embedchain.vectordb.elasticsearch.ElasticsearchDB",
"opensearch": "embedchain.vectordb.opensearch.OpenSearchDB",
"pinecone": "embedchain.vectordb.pinecone.PineconeDB",
"qdrant": "embedchain.vectordb.qdrant.QdrantDB",
"weaviate": "embedchain.vectordb.weaviate.WeaviateDB",
"zilliz": "embedchain.vectordb.zilliz.ZillizVectorDB",
}
provider_to_config_class = {
"chroma": "embedchain.config.vectordb.chroma.ChromaDbConfig",
"elasticsearch": "embedchain.config.vectordb.elasticsearch.ElasticsearchDBConfig",
"opensearch": "embedchain.config.vectordb.opensearch.OpenSearchDBConfig",
"pinecone": "embedchain.config.vectordb.pinecone.PineconeDBConfig",
"qdrant": "embedchain.config.vectordb.qdrant.QdrantDBConfig",
"weaviate": "embedchain.config.vectordb.weaviate.WeaviateDBConfig",
"zilliz": "embedchain.config.vectordb.zilliz.ZillizDBConfig",
}
@classmethod
def create(cls, provider_name, config_data):
class_type = cls.provider_to_class.get(provider_name)
config_class_type = cls.provider_to_config_class.get(provider_name)
if class_type:
embedder_class = load_class(class_type)
embedder_config_class = load_class(config_class_type)
return embedder_class(config=embedder_config_class(**config_data))
else:
raise ValueError(f"Unsupported Embedder provider: {provider_name}")
@@ -1,4 +1,5 @@
import logging
import os
from typing import Optional
from embedchain.config import BaseLlmConfig
@@ -7,18 +8,22 @@ from embedchain.llm.base import BaseLlm
@register_deserializable
class AntrophicLlm(BaseLlm):
class AnthropicLlm(BaseLlm):
def __init__(self, config: Optional[BaseLlmConfig] = None):
if "ANTHROPIC_API_KEY" not in os.environ:
raise ValueError("Please set the ANTHROPIC_API_KEY environment variable.")
super().__init__(config=config)
def get_llm_model_answer(self, prompt):
return AntrophicLlm._get_answer(prompt=prompt, config=self.config)
return AnthropicLlm._get_answer(prompt=prompt, config=self.config)
@staticmethod
def _get_answer(prompt: str, config: BaseLlmConfig) -> str:
from langchain.chat_models import ChatAnthropic
chat = ChatAnthropic(temperature=config.temperature, model=config.model)
chat = ChatAnthropic(
anthropic_api_key=os.environ["ANTHROPIC_API_KEY"], temperature=config.temperature, model=config.model
)
if config.max_tokens and config.max_tokens != 1000:
logging.warning("Config option `max_tokens` is not supported by this model.")

Some files were not shown because too many files have changed in this diff Show More