Compare commits
409 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb5a3bfd95 | |||
| 7441f1462d | |||
| c9240e7ca6 | |||
| 1e7618dfa4 | |||
| 4e5d34103f | |||
| da435bc025 | |||
| 2a43aa6902 | |||
| b620f8fae3 | |||
| 03f787d5cb | |||
| 19637804b3 | |||
| 80f145fceb | |||
| 34477d4936 | |||
| 4ec51f2dd6 | |||
| f842a92e25 | |||
| 83e8c97295 | |||
| 1a5d0d236a | |||
| ebbf90f4aa | |||
| 4f119692f1 | |||
| bbe56107fb | |||
| bd654e7aac | |||
| 33500a7ce2 | |||
| 4880557d51 | |||
| ea09b5f7f0 | |||
| 5258fd91ea | |||
| b305d674de | |||
| 7c24601d0f | |||
| 50c0285cb2 | |||
| 0a78198bb5 | |||
| edaeb78ccf | |||
| f80be2d2ea | |||
| 8700165b42 | |||
| 18fb92f1f8 | |||
| 14fc6bbadd | |||
| 5070a1d83e | |||
| 8a9088ea9d | |||
| 48b24f6f12 | |||
| f6ddd5ffc5 | |||
| b43a116b3c | |||
| 50512a5f03 | |||
| e3e107b31d | |||
| 21a04541ea | |||
| cdd5d8ac76 | |||
| 11094f504e | |||
| 5acaae5f56 | |||
| 4547d870af | |||
| dc0d8e0932 | |||
| c558eae9ce | |||
| abb9af66a6 | |||
| 4800e0344c | |||
| 439b425c61 | |||
| 2855f1635b | |||
| 08b67b4a78 | |||
| 1bddd46ed2 | |||
| 6ecdadfd97 | |||
| 4119040005 | |||
| 873eef6ef8 | |||
| 445fed4d3f | |||
| 52fd3e0dd4 | |||
| 8fd0e1f3b0 | |||
| 11fc4a8451 | |||
| e22293294e | |||
| 73e53aaff1 | |||
| 6fa946557f | |||
| fb0852f585 | |||
| 4070fc1bf0 | |||
| 00c1fa1ec7 | |||
| 04e77ef34e | |||
| 827d63d115 | |||
| e0d0f6e94c | |||
| fd07513004 | |||
| b0e436d9c4 | |||
| a4bfd9cfc6 | |||
| 8ca01918e5 | |||
| a5b2381458 | |||
| 26c771503b | |||
| 622ed4a7c9 | |||
| 940f0128d5 | |||
| 1354747ca8 | |||
| 9544c69c55 | |||
| 9ba445e623 | |||
| ebc5e25f98 | |||
| 78301ee63d | |||
| 797dea1dca | |||
| a0ff764f0a | |||
| a795798156 | |||
| 1a66f961f4 | |||
| 6fb2048af0 | |||
| ba9f186fc5 | |||
| 6c32d287b5 | |||
| 536f85b78a | |||
| f8619870ad | |||
| d00a2085d5 | |||
| 85ec61335a | |||
| 9b48a12c27 | |||
| c181ccbe42 | |||
| 8520033d44 | |||
| ebdce87fde | |||
| f2122ed696 | |||
| 3616eaadb4 | |||
| ef69c91b60 | |||
| 117824b32c | |||
| f77f5b996e | |||
| a4d32aec24 | |||
| 9111495fae | |||
| ee1e3f0957 | |||
| 4dc5c7348f | |||
| 4428768eaa | |||
| 11f4ce8fb6 | |||
| 6078738d34 | |||
| faacfeb891 | |||
| 8d7e8b6fb9 | |||
| 7e1d2ffdd7 | |||
| 91044ec591 | |||
| c77a75dfb5 | |||
| 6518c0c06b | |||
| 09cdaff9a2 | |||
| 56bf33ab7f | |||
| 752f638cfc | |||
| 92dd7edb57 | |||
| b4bb4cf053 | |||
| f0400e928a | |||
| aa5ad625af | |||
| f8f69eab03 | |||
| 2b2263acaa | |||
| 5e2e7fb639 | |||
| 6c12bc9044 | |||
| 9a11683003 | |||
| 38b4e06963 | |||
| 0766a44ccf | |||
| 036bf3a161 | |||
| 41bd258b93 | |||
| 38e212c721 | |||
| 2f285ea00a | |||
| d38120c839 | |||
| d94aee812b | |||
| 68d650ec40 | |||
| 769d926f5a | |||
| 9478bab04e | |||
| 7ad4af250f | |||
| 9fa368b114 | |||
| 4afef04f26 | |||
| 8fe2c3effc | |||
| fa78c972be | |||
| 0e66261644 | |||
| 819650a254 | |||
| 34c41c87dc | |||
| 2985b667b0 | |||
| 31bb0e7f0f | |||
| 8f28264aec | |||
| ec4fb11aa5 | |||
| b210723de1 | |||
| 433f99dd78 | |||
| e75c05112e | |||
| d2a5b50ff8 | |||
| 120690afd4 | |||
| 344dbeee42 | |||
| 3fe3b0320a | |||
| 75896b647f | |||
| 446d0975aa | |||
| b7d365119c | |||
| 2d9fbd4e49 | |||
| 22e14b5e65 | |||
| 1a654beea4 | |||
| f50f8a444a | |||
| 3cc3a0058d | |||
| ae473b5e3c | |||
| efb7e31565 | |||
| 069d265338 | |||
| 751a3a4bd1 | |||
| cb0499407e | |||
| 9afc6878c8 | |||
| 0b5b12575a | |||
| d79d30bf0c | |||
| 59600e2a5b | |||
| e572b5a3dc | |||
| 5b46daaee4 | |||
| 2784bae772 | |||
| 325e11f0de | |||
| 7444f59e3c | |||
| affe319460 | |||
| 862ff6cca6 | |||
| c020e65a50 | |||
| f582c1fe25 | |||
| 785929c502 | |||
| 68ec6615b1 | |||
| e2cca61cd3 | |||
| 69e83adae0 | |||
| 9e24aee40d | |||
| 3cff5e9898 | |||
| f3553040bc | |||
| 2b13984e11 | |||
| 0de9491c61 | |||
| c9df7a2020 | |||
| a7222e8c50 | |||
| 0373fa231c | |||
| 5f653e69ae | |||
| 2496ed133e | |||
| 62c0c52e31 | |||
| e36198dcc2 | |||
| 5fa6221f91 | |||
| f7696d1dc1 | |||
| 1878f8d4fc | |||
| 6c69ddef9b | |||
| 0c45020d81 | |||
| 4dfce44c1a | |||
| 1b661bb2fd | |||
| 73e726f6e3 | |||
| f58bbeffce | |||
| 99261e5fb5 | |||
| b4a59d1bd5 | |||
| 5c1f78879f | |||
| 94ba82f2a2 | |||
| b4ec14382b | |||
| 38ad57a22c | |||
| 60bbc180ba | |||
| a67d902b85 | |||
| ae2e9cb890 | |||
| 1976d38b25 | |||
| f5e3410e9a | |||
| 2f6ba642c7 | |||
| dd9b72dc62 | |||
| dd258c14b5 | |||
| 295cd3fac6 | |||
| c62663f2e4 | |||
| 367d6b70e2 | |||
| 27236bd1b2 | |||
| 6a82eb4287 | |||
| bd88fe3980 | |||
| 4f70fea6df | |||
| aee5bbb44b | |||
| a304ded500 | |||
| a54dde0509 | |||
| 52b4577d3b | |||
| e199f57279 | |||
| dec12b33a6 | |||
| 04daa1b206 | |||
| a7e1520d08 | |||
| 9e2b232c13 | |||
| 404e73af77 | |||
| a544b4d3ff | |||
| 6df63d9ca7 | |||
| 904baac153 | |||
| a926bcc640 | |||
| c0aafd38c9 | |||
| 19d80914df | |||
| d9d529987e | |||
| 12e6eaf802 | |||
| 7a026ea282 | |||
| 97dc90169b | |||
| 64c02f374a | |||
| 6c1ea7799e | |||
| 6be29f5bed | |||
| 68737da7a2 | |||
| da388b679f | |||
| 11f0d719f5 | |||
| e90673ae5b | |||
| f055028c6b | |||
| 106a338371 | |||
| 9fe80c5cca | |||
| 050706e95e | |||
| 6d2389de1c | |||
| dd97fad5a4 | |||
| 0f73ba9677 | |||
| 210fe9bb80 | |||
| ec8549d0e1 | |||
| b77d9d750f | |||
| a10823d309 | |||
| 3a09c2bd62 | |||
| a1394ce32e | |||
| 1020a4121f | |||
| 737837ae0b | |||
| 7ee2d0653b | |||
| 43926fb527 | |||
| 7bcc9e35dd | |||
| 6437661837 | |||
| b5f84f27ff | |||
| 48c38b5dc3 | |||
| b4f3bbbbc9 | |||
| 3cd50c4cd9 | |||
| cd2c40a9c4 | |||
| 33dcfe42b5 | |||
| db37b2ac15 | |||
| bee4e834b1 | |||
| 0272459435 | |||
| c0b5e93967 | |||
| 6983ebba49 | |||
| 9943d1e015 | |||
| b348251484 | |||
| e719b5bac3 | |||
| 54f43215cd | |||
| b246d9823e | |||
| 65c8dd445b | |||
| 0efbc80ac9 | |||
| 151746beec | |||
| c0ee680546 | |||
| 9303a1bf81 | |||
| d54cdc5b00 | |||
| b7a44ef472 | |||
| ae6f866901 | |||
| 7910cee259 | |||
| d66e647f99 | |||
| ff4a333be7 | |||
| 111749a95d | |||
| adde398b65 | |||
| d8897ce356 | |||
| 0ea8ab228c | |||
| d62a23edf6 | |||
| 51ebf3439b | |||
| 4a5ed1dd8d | |||
| e84b5034ea | |||
| a4831d6ed9 | |||
| 51b4966801 | |||
| 1d4e00ccef | |||
| c9fbc2e7d6 | |||
| fa34788df6 | |||
| 0f4f220119 | |||
| 512cfc9466 | |||
| 541b1cb7c7 | |||
| 36af1a7615 | |||
| b02e8feeda | |||
| 406c46e7f4 | |||
| e35eaf1bfc | |||
| 38426a7af1 | |||
| 141a23fb1e | |||
| bb28569abf | |||
| 1df46b2bb3 | |||
| 58f72e1ffe | |||
| 33409140b4 | |||
| f6b80e01a1 | |||
| 798d3fcc5a | |||
| 85f3ac428b | |||
| 9fcf2130b5 | |||
| 51df00729e | |||
| 023a61446f | |||
| e0b73e6a5a | |||
| 28460f725c | |||
| c93e49d2b8 | |||
| 07fb6bee54 | |||
| 3fa7db8420 | |||
| c14bd7b73b | |||
| 5201beaab0 | |||
| 122313d8a5 | |||
| 82fd595306 | |||
| 95c0d47236 | |||
| 919cc74e94 | |||
| d839991acb | |||
| 539286aafd | |||
| 23522b7b55 | |||
| bf3fac56e4 | |||
| a5bf8e9075 | |||
| 1d31b8f7e4 | |||
| b144c7dccc | |||
| 1364975396 | |||
| deaa7f50f8 | |||
| 744ab5156f | |||
| c45413969a | |||
| b314e5e080 | |||
| 17129e2eaa | |||
| 654fd8d74c | |||
| 9d3568ef75 | |||
| 14712cac88 | |||
| 0d568c758b | |||
| 7c6b88c7c5 | |||
| 32c93be46e | |||
| 7de8d85199 | |||
| f7dd65a3de | |||
| d8cdbe0041 | |||
| 2b8b6d3ea9 | |||
| 936c7e389f | |||
| 6864b4207b | |||
| 98eb5b54be | |||
| 3332e6e236 | |||
| 0533da72d7 | |||
| a1de238716 | |||
| f0d112254b | |||
| 830a7397ef | |||
| 5428765329 | |||
| 23c912f2b7 | |||
| 9c4b023297 | |||
| 53037b5ed8 | |||
| e2546a653d | |||
| 4b8cada873 | |||
| fa3ca1d08a | |||
| 8dd5cb9602 | |||
| a054f7be9c | |||
| df314dc6d1 | |||
| 930280f4ce | |||
| 5022c1ae29 | |||
| 6ced756a6b | |||
| b17268db50 | |||
| 476da37009 | |||
| 455f059c6f | |||
| 5255a37c93 | |||
| 68dc274f72 | |||
| 30228f7f8e | |||
| e15ef79ca9 | |||
| bc012a7518 | |||
| 3b4409cfad | |||
| d3726134b2 | |||
| 5acb7f1c55 | |||
| 81336668b3 | |||
| 35c2b83015 | |||
| cc1ee1deaa | |||
| 29bd038579 | |||
| f6c4f86986 | |||
| 68183e9dce | |||
| 78ec91a3a9 | |||
| c95d458e52 | |||
| 191ae3ec1e |
@@ -1 +0,0 @@
|
||||
OPENAI_API_KEY="your-openai-api-key"
|
||||
@@ -5,7 +5,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: >
|
||||
#### Before submitting a bug, please make sure the issue hasn't been already addressed by searching through [the existing and past issues](https://github.com/gventuri/pandas-ai/issues?q=is%3Aissue+sort%3Acreated-desc+).
|
||||
#### Before submitting a bug, please make sure the issue hasn't been already addressed by searching through [the existing and past issues](https://github.com/embedchain/embedchain/issues?q=is%3Aissue+sort%3Acreated-desc+).
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 🐛 Describe the bug
|
||||
|
||||
@@ -2,14 +2,13 @@ name: Publish Python 🐍 distributions 📦 to PyPI and TestPyPI
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published] # This will trigger the workflow when you create a new release
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build-n-publish:
|
||||
name: Build and publish Python 🐍 distributions 📦 to PyPI and TestPyPI
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# IMPORTANT: this permission is mandatory for trusted publishing
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -25,16 +24,23 @@ jobs:
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
- name: Install dependencies
|
||||
run: poetry install
|
||||
run: |
|
||||
cd embedchain
|
||||
poetry install
|
||||
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: poetry build
|
||||
run: |
|
||||
cd embedchain
|
||||
poetry build
|
||||
|
||||
- name: Publish distribution 📦 to Test PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
repository_url: https://test.pypi.org/legacy/
|
||||
packages_dir: embedchain/dist/
|
||||
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages_dir: embedchain/dist/
|
||||
@@ -3,7 +3,15 @@ name: ci
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'embedchain/**'
|
||||
- 'embedchain/tests/**'
|
||||
- 'embedchain/examples/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'embedchain/embedchain/**'
|
||||
- 'embedchain/tests/**'
|
||||
- 'embedchain/examples/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -31,12 +39,12 @@ jobs:
|
||||
path: .venv
|
||||
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
|
||||
- name: Install dependencies
|
||||
run: poetry install --all-extras
|
||||
run: cd embedchain && make install_all
|
||||
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
|
||||
- name: Lint with ruff
|
||||
run: make lint
|
||||
run: cd embedchain && make lint
|
||||
- name: Run tests and generate coverage report
|
||||
run: make coverage
|
||||
run: cd embedchain && make coverage
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
|
||||
@@ -76,7 +76,6 @@ docs/_build/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
*.yaml
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
@@ -166,6 +165,7 @@ cython_debug/
|
||||
# Database
|
||||
db
|
||||
test-db
|
||||
!embedchain/embedchain/core/db/
|
||||
|
||||
.vscode
|
||||
.idea/
|
||||
@@ -176,3 +176,11 @@ notebooks/*.yaml
|
||||
.ipynb_checkpoints/
|
||||
|
||||
!configs/*.yaml
|
||||
|
||||
# cache db
|
||||
*.db
|
||||
|
||||
# local directories for testing
|
||||
eval/
|
||||
qdrant_storage/
|
||||
.crossnote
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 23.3.0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: 'v0.0.220'
|
||||
hooks:
|
||||
- id: ruff
|
||||
name: ruff
|
||||
# Respect `exclude` and `extend-exclude` settings.
|
||||
args: ["--force-exclude"]
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: pytest-check
|
||||
name: pytest-check
|
||||
entry: poetry run pytest
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
@@ -1,44 +1,32 @@
|
||||
.PHONY: format sort lint
|
||||
|
||||
# Variables
|
||||
PYTHON := python3
|
||||
PIP := $(PYTHON) -m pip
|
||||
PROJECT_NAME := embedchain
|
||||
RUFF_OPTIONS = --line-length 120
|
||||
ISORT_OPTIONS = --profile black
|
||||
|
||||
# Targets
|
||||
.PHONY: install format lint clean test ci_lint ci_test coverage
|
||||
|
||||
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
|
||||
|
||||
py_shell:
|
||||
poetry run python
|
||||
# Default target
|
||||
all: format sort lint
|
||||
|
||||
# Format code with ruff
|
||||
format:
|
||||
$(PYTHON) -m black .
|
||||
$(PYTHON) -m isort .
|
||||
poetry run ruff check . --fix $(RUFF_OPTIONS)
|
||||
|
||||
# Sort imports with isort
|
||||
sort:
|
||||
poetry run isort . $(ISORT_OPTIONS)
|
||||
|
||||
# Lint code with ruff
|
||||
lint:
|
||||
poetry run ruff check . $(RUFF_OPTIONS)
|
||||
|
||||
docs:
|
||||
cd docs && mintlify dev
|
||||
|
||||
build:
|
||||
poetry build
|
||||
|
||||
publish:
|
||||
poetry publish
|
||||
|
||||
clean:
|
||||
rm -rf dist build *.egg-info
|
||||
|
||||
lint:
|
||||
poetry run ruff .
|
||||
|
||||
test:
|
||||
poetry run pytest $(file)
|
||||
|
||||
coverage:
|
||||
poetry run pytest --cov=$(PROJECT_NAME) --cov-report=xml
|
||||
poetry run rm -rf dist
|
||||
|
||||
@@ -1,134 +1,107 @@
|
||||
# embedchain
|
||||
<p align="center">
|
||||
<img src="docs/images/mem0-bg.png" width="500px" alt="Mem0 Logo">
|
||||
</p>
|
||||
|
||||
[](https://pypi.org/project/embedchain/)
|
||||
[](https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw)
|
||||
[](https://discord.gg/CUU9FPhRNt)
|
||||
[](https://twitter.com/embedchain)
|
||||
[](https://embedchain.substack.com/)
|
||||
[](https://colab.research.google.com/drive/138lMWhENGeEu7Q1-6lNbNTHGLZXBBz_B?usp=sharing)
|
||||
[](https://codecov.io/gh/embedchain/embedchain)
|
||||
<p align="center">
|
||||
<a href="https://embedchain.ai/slack">
|
||||
<img src="https://img.shields.io/badge/slack-embedchain-brightgreen.svg?logo=slack" alt="Slack">
|
||||
</a>
|
||||
<a href="https://embedchain.ai/discord">
|
||||
<img src="https://dcbadge.vercel.app/api/server/6PzXDgEjG5?style=flat" alt="Discord">
|
||||
</a>
|
||||
<a href="https://twitter.com/mem0ai">
|
||||
<img src="https://img.shields.io/twitter/follow/mem0ai" alt="Twitter">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
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)
|
||||
# Mem0: The Memory Layer for Personalized AI
|
||||
|
||||
## Community
|
||||
Mem0 provides a smart, self-improving memory layer for Large Language Models, enabling personalized AI experiences across applications.
|
||||
|
||||
* Join embedchain community on slack by accepting [this invite](https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw)
|
||||
> Note: The Mem0 repository now also includes the Embedchain project. We continue to maintain and support Embedchain ❤️. You can find the Embedchain codebase in the [embedchain](https://github.com/mem0ai/mem0/tree/main/embedchain) directory.
|
||||
## 🚀 Quick Start
|
||||
|
||||
## 🤝 Schedule a 1-on-1 Session
|
||||
|
||||
Book a [1-on-1 Session](https://cal.com/taranjeetio/ec) with Taranjeet, the founder, to discuss any issues, provide feedback, or explore how we can improve Embedchain for you.
|
||||
|
||||
## 🔧 Quick install
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
pip install --upgrade embedchain
|
||||
pip install mem0ai
|
||||
```
|
||||
|
||||
## 🔍 Demo
|
||||
### Basic Usage
|
||||
|
||||
Try out embedchain in your browser:
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
[](https://colab.research.google.com/drive/17ON1LPonnXAtLaZEebnOktstB_1cJJmh?usp=sharing)
|
||||
# Initialize Mem0
|
||||
m = Memory()
|
||||
|
||||
# Store a memory from any unstructured text
|
||||
result = m.add("I am working on improving my tennis skills. Suggest some online courses.", user_id="alice", metadata={"category": "hobbies"})
|
||||
print(result)
|
||||
# Created memory: Improving her tennis skills. Looking for online suggestions.
|
||||
|
||||
# Retrieve memories
|
||||
all_memories = m.get_all()
|
||||
print(all_memories)
|
||||
|
||||
# Search memories
|
||||
related_memories = m.search(query="What are Alice's hobbies?", user_id="alice")
|
||||
print(related_memories)
|
||||
|
||||
# Update a memory
|
||||
result = m.update(memory_id="m1", data="Likes to play tennis on weekends")
|
||||
print(result)
|
||||
|
||||
# Get memory history
|
||||
history = m.history(memory_id="m1")
|
||||
print(history)
|
||||
```
|
||||
|
||||
## 🔑 Core Features
|
||||
|
||||
- **Multi-Level Memory**: User, Session, and AI Agent memory retention
|
||||
- **Adaptive Personalization**: Continuous improvement based on interactions
|
||||
- **Developer-Friendly API**: Simple integration into various applications
|
||||
- **Cross-Platform Consistency**: Uniform behavior across devices
|
||||
- **Managed Service**: Hassle-free hosted solution
|
||||
|
||||
## 📖 Documentation
|
||||
|
||||
The documentation for embedchain can be found at [docs.embedchain.ai](https://docs.embedchain.ai).
|
||||
For detailed usage instructions and API reference, visit our documentation at [docs.mem0.ai](https://docs.mem0.ai).
|
||||
|
||||
## 💻 Usage
|
||||
## 🔧 Advanced Usage
|
||||
|
||||
Embedchain empowers you to create ChatGPT like apps, on your own dynamic dataset.
|
||||
|
||||
### Data Types Supported
|
||||
|
||||
* Youtube video
|
||||
* PDF file
|
||||
* Web page
|
||||
* Sitemap
|
||||
* Doc file
|
||||
* JSON file
|
||||
* Code documentation website loader
|
||||
* OpenAPI specs
|
||||
* Notion
|
||||
* Unstructured file loader and many more
|
||||
|
||||
You can find the full list of data types on [our documentation](https://docs.embedchain.ai/data-sources/csv).
|
||||
|
||||
### Queries
|
||||
|
||||
For example, you can use Embedchain to create an Elon Musk bot using the following code:
|
||||
For production environments, you can use Qdrant as a vector store:
|
||||
|
||||
```python
|
||||
import os
|
||||
from embedchain import App
|
||||
from mem0 import Memory
|
||||
|
||||
# Create a bot instance
|
||||
os.environ["OPENAI_API_KEY"] = "YOUR API KEY"
|
||||
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=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 | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/openai.ipynb) | [](https://replit.com/@taranjeetio/openai#main.py) |
|
||||
| Anthropic | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/anthropic.ipynb) | [](https://replit.com/@taranjeetio/anthropic#main.py) |
|
||||
| Azure OpenAI | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/azure-openai.ipynb) | [](https://replit.com/@taranjeetio/azureopenai#main.py) |
|
||||
| VertexAI | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/vertex_ai.ipynb) | [](https://replit.com/@taranjeetio/vertexai#main.py) |
|
||||
| Cohere | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/cohere.ipynb) | [](https://replit.com/@taranjeetio/cohere#main.py) |
|
||||
| Hugging Face | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/hugging_face_hub.ipynb) | [](https://replit.com/@taranjeetio/huggingface#main.py) |
|
||||
| JinaChat | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/jina.ipynb) | [](https://replit.com/@taranjeetio/jina#main.py) |
|
||||
| GPT4All | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/gpt4all.ipynb) | [](https://replit.com/@taranjeetio/gpt4all#main.py) |
|
||||
| Llama2 | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/llama2.ipynb) | [](https://replit.com/@taranjeetio/llama2#main.py) |
|
||||
|
||||
| Embedding model | Google Colab | Replit |
|
||||
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
||||
| OpenAI | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/openai.ipynb) | [](https://replit.com/@taranjeetio/openai#main.py) |
|
||||
| VertexAI | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/vertex_ai.ipynb) | [](https://replit.com/@taranjeetio/vertexai#main.py) |
|
||||
| GPT4All | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/gpt4all.ipynb) | [](https://replit.com/@taranjeetio/gpt4all#main.py) |
|
||||
| Hugging Face | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/hugging_face_hub.ipynb) | [](https://replit.com/@taranjeetio/huggingface#main.py) |
|
||||
|
||||
| Vector DB | Google Colab | Replit |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| ChromaDB | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/chromadb.ipynb) | [](https://replit.com/@taranjeetio/chromadb#main.py) |
|
||||
| Elasticsearch | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/elasticsearch.ipynb) | [](https://replit.com/@taranjeetio/elasticsearchdb#main.py) |
|
||||
| Opensearch | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/opensearch.ipynb) | [](https://replit.com/@taranjeetio/opensearchdb#main.py) |
|
||||
| Pinecone | [](https://colab.research.google.com/github/embedchain/embedchain/blob/main/notebooks/pinecone.ipynb) | [](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.
|
||||
For more information, please see the [contributing guidelines](CONTRIBUTING.md).
|
||||
|
||||
For more reference, please go through [Development Guide](https://docs.embedchain.ai/contribution/dev) and [Documentation Guide](https://docs.embedchain.ai/contribution/docs).
|
||||
|
||||
<a href="https://github.com/embedchain/embedchain/graphs/contributors">
|
||||
<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, Deshraj Yadav},
|
||||
title = {Embedchain: Data platform for LLMs - load, index, retrieve, and sync any unstructured data},
|
||||
year = {2023},
|
||||
publisher = {GitHub},
|
||||
journal = {GitHub repository},
|
||||
howpublished = {\url{https://github.com/embedchain/embedchain}},
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
## 🗺️ Roadmap
|
||||
|
||||
- Integration with various LLM providers
|
||||
- Support for LLM frameworks
|
||||
- Integration with AI Agents frameworks
|
||||
- Customizable memory creation/update rules
|
||||
- Hosted platform support
|
||||
|
||||
## 🙋♂️ Support
|
||||
Join our Slack or Discord community for support and discussions.
|
||||
If you have any questions, feel free to reach out to us using one of the following methods:
|
||||
|
||||
- [Join our Discord](https://embedchain.ai/discord)
|
||||
- [Join our Slack](https://embedchain.ai/slack)
|
||||
- [Follow us on Twitter](https://twitter.com/mem0ai)
|
||||
- [Email us](mailto:founders@mem0.ai)
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
# Contributing to embedchain docs
|
||||
# Mintlify Starter Kit
|
||||
|
||||
Click on `Use this template` to copy the Mintlify starter kit. The starter kit contains examples including
|
||||
|
||||
### 👩💻 Development
|
||||
- Guide pages
|
||||
- Navigation
|
||||
- Customizations
|
||||
- API Reference pages
|
||||
- Use of popular components
|
||||
|
||||
### Development
|
||||
|
||||
Install the [Mintlify CLI](https://www.npmjs.com/package/mintlify) to preview the documentation changes locally. To install, use the following command
|
||||
|
||||
@@ -15,9 +22,9 @@ Run the following command at the root of your documentation (where mint.json is)
|
||||
mintlify dev
|
||||
```
|
||||
|
||||
### 😎 Publishing Changes
|
||||
### Publishing Changes
|
||||
|
||||
Changes will be deployed to production automatically after your PR is merged to the main branch.
|
||||
Install our Github App to auto propagate changes from your repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
|
||||
@@ -1,11 +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">
|
||||
<Card title="Talk to founders" icon="calendar" href="https://cal.com/taranjeetio/meet">
|
||||
Talk to founders
|
||||
</Card>
|
||||
<Card title="Slack" icon="slack" href="https://embedchain.ai/slack" color="#4A154B">
|
||||
Join our slack community
|
||||
</Card>
|
||||
<Card title="Discord" icon="discord" href="https://discord.gg/6PzXDgEjG5" color="#7289DA">
|
||||
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>
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
---
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
```yaml
|
||||
app:
|
||||
config:
|
||||
id: 'full-stack-app'
|
||||
|
||||
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.
|
||||
|
||||
$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: 'full-stack-app'
|
||||
dir: db
|
||||
allow_reset: true
|
||||
|
||||
embedder:
|
||||
provider: openai
|
||||
config:
|
||||
model: 'text-embedding-ada-002'
|
||||
```
|
||||
|
||||
Alright, let's dive into what each key means in the yaml config above:
|
||||
|
||||
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'.
|
||||
|
||||
If you have questions about the configuration above, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -1,173 +0,0 @@
|
||||
---
|
||||
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>
|
||||
@@ -1,325 +0,0 @@
|
||||
---
|
||||
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" />
|
||||
@@ -1,224 +0,0 @@
|
||||
---
|
||||
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" />
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
title: ' 🟨 Javascript'
|
||||
url: https://github.com/embedchain/embedchain/tree/main/embedchain-js
|
||||
---
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
title: '📊 CSV'
|
||||
---
|
||||
|
||||
To add any csv file, use the data_type as `csv`. `csv` allows remote urls and conventional file paths. Headers are included for each line, so if you have an `age` column, `18` will be added as `age: 18`. Eg:
|
||||
|
||||
```python
|
||||
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.
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
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."
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
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>
|
||||
</CardGroup>
|
||||
|
||||
<br/ >
|
||||
|
||||
<Snippet file="missing-data-source-tip.mdx" />
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
title: '📰 PDF file'
|
||||
---
|
||||
|
||||
To add any pdf file, use the data_type as `pdf_file`. Eg:
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
|
||||
app.add('https://arxiv.org/pdf/1706.03762.pdf', data_type='pdf_file')
|
||||
app.query("What is the paper 'attention is all you need' about?")
|
||||
# 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.
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
title: '🎥📺 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')
|
||||
```
|
||||
@@ -1,93 +0,0 @@
|
||||
---
|
||||
title: '🌍 API Server'
|
||||
---
|
||||
|
||||
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
|
||||
|
||||
- Open variables.env, and edit it to add your 🔑 `OPENAI_API_KEY`.
|
||||
- To setup your api server using docker, run the following command inside this folder using your terminal.
|
||||
|
||||
```bash
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
📝 Note: The build command might take a while to install all the packages depending on your system resources.
|
||||
|
||||
### 🚀 Usage Instructions
|
||||
|
||||
- Your api server is running on [http://localhost:5000/](http://localhost:5000/)
|
||||
- To use the api server, make an api call to the endpoints `/add`, `/query` and `/chat` using the json formats discussed below.
|
||||
- To add data sources to the bot (/add):
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"data_type": "your_data_type_here",
|
||||
"url_or_text": "your_url_or_text_here"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"data": "Added data_type: url_or_text"
|
||||
}
|
||||
```
|
||||
- To ask queries from the bot (/query):
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"question": "your_question_here"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"data": "your_answer_here"
|
||||
}
|
||||
```
|
||||
- To chat with the bot (/chat):
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"question": "your_question_here"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"data": "your_answer_here"
|
||||
}
|
||||
```
|
||||
|
||||
### 📡 Curl Call Formats
|
||||
|
||||
- To add data sources to the bot (/add):
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"data_type": "your_data_type_here",
|
||||
"url_or_text": "your_url_or_text_here"
|
||||
}' \
|
||||
http://localhost:5000/add
|
||||
```
|
||||
- To ask queries from the bot (/query):
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"question": "your_question_here"
|
||||
}' \
|
||||
http://localhost:5000/query
|
||||
```
|
||||
- To chat with the bot (/chat):
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"question": "your_question_here"
|
||||
}' \
|
||||
http://localhost:5000/chat
|
||||
```
|
||||
|
||||
🎉 Happy Chatting! 🎉
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: Customer Support AI Agent
|
||||
---
|
||||
|
||||
You can create a personalized Customer Support AI Agent using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
|
||||
|
||||
## Overview
|
||||
|
||||
The Customer Support AI Agent leverages Mem0 to retain information across interactions, enabling a personalized and efficient support experience.
|
||||
|
||||
## Setup
|
||||
|
||||
Install the necessary packages using pip:
|
||||
|
||||
```bash
|
||||
pip install openai mem0ai
|
||||
```
|
||||
|
||||
## Full Code Example
|
||||
|
||||
Below is the simplified code to create and interact with a Customer Support AI Agent using Mem0:
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
|
||||
# Set the OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
class CustomerSupportAIAgent:
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize the CustomerSupportAIAgent with memory configuration and OpenAI client.
|
||||
"""
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
}
|
||||
self.memory = Memory.from_config(config)
|
||||
self.client = OpenAI()
|
||||
self.app_id = "customer-support"
|
||||
|
||||
def handle_query(self, query, user_id=None):
|
||||
"""
|
||||
Handle a customer query and store the relevant information in memory.
|
||||
|
||||
:param query: The customer query to handle.
|
||||
:param user_id: Optional user ID to associate with the memory.
|
||||
"""
|
||||
# Start a streaming chat completion request to the AI
|
||||
stream = self.client.chat.completions.create(
|
||||
model="gpt-4",
|
||||
stream=True,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a customer support AI agent."},
|
||||
{"role": "user", "content": query}
|
||||
]
|
||||
)
|
||||
# Store the query in memory
|
||||
self.memory.add(query, user_id=user_id, metadata={"app_id": self.app_id})
|
||||
|
||||
# Print the response from the AI in real-time
|
||||
for chunk in stream:
|
||||
if chunk.choices[0].delta.content is not None:
|
||||
print(chunk.choices[0].delta.content, end="")
|
||||
|
||||
def get_memories(self, user_id=None):
|
||||
"""
|
||||
Retrieve all memories associated with the given customer ID.
|
||||
|
||||
:param user_id: Optional user ID to filter memories.
|
||||
:return: List of memories.
|
||||
"""
|
||||
return self.memory.get_all(user_id=user_id)
|
||||
|
||||
# Instantiate the CustomerSupportAIAgent
|
||||
support_agent = CustomerSupportAIAgent()
|
||||
|
||||
# Define a customer ID
|
||||
customer_id = "jane_doe"
|
||||
|
||||
# Handle a customer query
|
||||
support_agent.handle_query("I need help with my recent order. It hasn't arrived yet.", user_id=customer_id)
|
||||
```
|
||||
|
||||
### Fetching Memories
|
||||
|
||||
You can fetch all the memories at any point in time using the following code:
|
||||
|
||||
```python
|
||||
memories = support_agent.get_memories(user_id=customer_id)
|
||||
for m in memories:
|
||||
print(m['text'])
|
||||
```
|
||||
|
||||
### Key Points
|
||||
|
||||
- **Initialization**: The CustomerSupportAIAgent class is initialized with the necessary memory configuration and OpenAI client setup.
|
||||
- **Handling Queries**: The handle_query method sends a query to the AI and stores the relevant information in memory.
|
||||
- **Retrieving Memories**: The get_memories method fetches all stored memories associated with a customer.
|
||||
|
||||
### Conclusion
|
||||
|
||||
As the conversation progresses, Mem0's memory automatically updates based on the interactions, providing a continuously improving personalized support experience.
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
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.
|
||||
|
||||
```bash
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
📝 Note: The build command might take a while to install all the packages depending on your system resources.
|
||||
|
||||
### 🚀 Usage Instructions
|
||||
|
||||
- Go to [http://localhost:3000/](http://localhost:3000/) in your browser to view the dashboard.
|
||||
- Add your `OpenAI API key` 🔑 in the Settings.
|
||||
- Create a new bot and you'll be navigated to its page.
|
||||
- Here you can add your data sources and then chat with the bot.
|
||||
|
||||
🎉 Happy Chatting! 🎉
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Overview
|
||||
description: How to use mem0 in your existing applications?
|
||||
---
|
||||
|
||||
|
||||
With Mem0, you can create stateful LLM-based applications such as chatbots, virtual assistants, or AI agents. Mem0 enhances your applications by providing a memory layer that makes responses:
|
||||
|
||||
- More personalized
|
||||
- More reliable
|
||||
- Cost-effective by reducing the number of LLM interactions
|
||||
- More engaging
|
||||
- Enables long-term memory
|
||||
|
||||
Here are some examples of how Mem0 can be integrated into various applications:
|
||||
|
||||
## Example Use Cases
|
||||
|
||||
<CardGroup cols={1}>
|
||||
<Card title="Personal AI Tutor" icon="square-1" href="/examples/personal-ai-tutor">
|
||||
<img width="100%" src="/images/ai-tutor.png" />
|
||||
Create a Personalized AI Tutor that adapts to student progress and learning preferences.
|
||||
</Card>
|
||||
<Card title="Personal Travel Assistant" icon="square-2" href="/examples/personal-travel-assistant">
|
||||
<img src="/images/personal-travel-agent.png" />
|
||||
Build a Personalized AI Travel Assistant that understands your travel preferences and past itineraries.
|
||||
</Card>
|
||||
<Card title="Customer Support Agent" icon="square-3" href="/examples/customer-support-agent">
|
||||
<img width="100%" src="/images/customer-support-agent.png" />
|
||||
Develop a Personal AI Assistant that remembers user preferences, past interactions, and context to provide personalized and efficient assistance.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
title: Personalized AI Tutor
|
||||
---
|
||||
|
||||
You can create a personalized AI Tutor using Mem0. This guide will walk you through the necessary steps and provide the complete code to get you started.
|
||||
|
||||
## Overview
|
||||
|
||||
The Personalized AI Tutor leverages Mem0 to retain information across interactions, enabling a tailored learning experience. By integrating with OpenAI's GPT-4 model, the tutor can provide detailed and context-aware responses to user queries.
|
||||
|
||||
## Setup
|
||||
Before you begin, ensure you have the required dependencies installed. You can install the necessary packages using pip:
|
||||
|
||||
```bash
|
||||
pip install openai mem0ai
|
||||
```
|
||||
|
||||
## Full Code Example
|
||||
|
||||
Below is the complete code to create and interact with a Personalized AI Tutor using Mem0:
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
|
||||
# Set the OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
# Initialize the OpenAI client
|
||||
client = OpenAI()
|
||||
|
||||
class PersonalAITutor:
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize the PersonalAITutor with memory configuration and OpenAI client.
|
||||
"""
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
}
|
||||
self.memory = Memory.from_config(config)
|
||||
self.client = client
|
||||
self.app_id = "app-1"
|
||||
|
||||
def ask(self, question, user_id=None):
|
||||
"""
|
||||
Ask a question to the AI and store the relevant facts in memory
|
||||
|
||||
:param question: The question to ask the AI.
|
||||
:param user_id: Optional user ID to associate with the memory.
|
||||
"""
|
||||
# Start a streaming chat completion request to the AI
|
||||
stream = self.client.chat.completions.create(
|
||||
model="gpt-4",
|
||||
stream=True,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a personal AI Tutor."},
|
||||
{"role": "user", "content": question}
|
||||
]
|
||||
)
|
||||
# Store the question in memory
|
||||
self.memory.add(question, user_id=user_id, metadata={"app_id": self.app_id})
|
||||
|
||||
# Print the response from the AI in real-time
|
||||
for chunk in stream:
|
||||
if chunk.choices[0].delta.content is not None:
|
||||
print(chunk.choices[0].delta.content, end="")
|
||||
|
||||
def get_memories(self, user_id=None):
|
||||
"""
|
||||
Retrieve all memories associated with the given user ID.
|
||||
|
||||
:param user_id: Optional user ID to filter memories.
|
||||
:return: List of memories.
|
||||
"""
|
||||
return self.memory.get_all(user_id=user_id)
|
||||
|
||||
# Instantiate the PersonalAITutor
|
||||
ai_tutor = PersonalAITutor()
|
||||
|
||||
# Define a user ID
|
||||
user_id = "john_doe"
|
||||
|
||||
# Ask a question
|
||||
ai_tutor.ask("I am learning introduction to CS. What is queue? Briefly explain.", user_id=user_id)
|
||||
```
|
||||
|
||||
### Fetching Memories
|
||||
|
||||
You can fetch all the memories at any point in time using the following code:
|
||||
|
||||
```python
|
||||
memories = ai_tutor.get_memories(user_id=user_id)
|
||||
for m in memories:
|
||||
print(m['text'])
|
||||
```
|
||||
|
||||
### Key Points
|
||||
|
||||
- **Initialization**: The PersonalAITutor class is initialized with the necessary memory configuration and OpenAI client setup.
|
||||
- **Asking Questions**: The ask method sends a question to the AI and stores the relevant information in memory.
|
||||
- **Retrieving Memories**: The get_memories method fetches all stored memories associated with a user.
|
||||
|
||||
### Conclusion
|
||||
|
||||
As the conversation progresses, Mem0's memory automatically updates based on the interactions, providing a continuously improving personalized learning experience. This setup ensures that the AI Tutor can offer contextually relevant and accurate responses, enhancing the overall educational process.
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: Personal AI Travel Assistant
|
||||
---
|
||||
Create a personalized AI Travel Assistant using Mem0. This guide provides step-by-step instructions and the complete code to get you started.
|
||||
|
||||
## Overview
|
||||
|
||||
The Personalized AI Travel Assistant uses Mem0 to store and retrieve information across interactions, enabling a tailored travel planning experience. It integrates with OpenAI's GPT-4 model to provide detailed and context-aware responses to user queries.
|
||||
|
||||
## Setup
|
||||
|
||||
Install the required dependencies using pip:
|
||||
|
||||
```bash
|
||||
pip install openai mem0ai
|
||||
```
|
||||
|
||||
## Full Code Example
|
||||
|
||||
Here's the complete code to create and interact with a Personalized AI Travel Assistant using Mem0:
|
||||
|
||||
```python
|
||||
import os
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
|
||||
# Set the OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = 'sk-xxx'
|
||||
|
||||
class PersonalTravelAssistant:
|
||||
def __init__(self):
|
||||
self.client = OpenAI()
|
||||
self.memory = Memory()
|
||||
self.messages = [{"role": "system", "content": "You are a personal AI Assistant."}]
|
||||
|
||||
def ask_question(self, question, user_id):
|
||||
# Fetch previous related memories
|
||||
previous_memories = self.search_memories(question, user_id=user_id)
|
||||
prompt = question
|
||||
if previous_memories:
|
||||
prompt = f"User input: {question}\n Previous memories: {previous_memories}"
|
||||
self.messages.append({"role": "user", "content": prompt})
|
||||
|
||||
# Generate response using GPT-4o
|
||||
response = self.client.chat.completions.create(
|
||||
model="gpt-4o",
|
||||
messages=self.messages
|
||||
)
|
||||
answer = response.choices[0].message.content
|
||||
self.messages.append({"role": "assistant", "content": answer})
|
||||
|
||||
# Store the question in memory
|
||||
self.memory.add(question, user_id=user_id)
|
||||
return answer
|
||||
|
||||
def get_memories(self, user_id):
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
return [m['text'] for m in memories]
|
||||
|
||||
def search_memories(self, query, user_id):
|
||||
memories = self.memory.search(query, user_id=user_id)
|
||||
return [m['text'] for m in memories]
|
||||
|
||||
# Usage example
|
||||
user_id = "traveler_123"
|
||||
ai_assistant = PersonalTravelAssistant()
|
||||
|
||||
def main():
|
||||
while True:
|
||||
question = input("Question: ")
|
||||
if question.lower() in ['q', 'exit']:
|
||||
print("Exiting...")
|
||||
break
|
||||
|
||||
answer = ai_assistant.ask_question(question, user_id=user_id)
|
||||
print(f"Answer: {answer}")
|
||||
memories = ai_assistant.get_memories(user_id=user_id)
|
||||
print("Memories:")
|
||||
for memory in memories:
|
||||
print(f"- {memory}")
|
||||
print("-----")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
- **Initialization**: The `PersonalTravelAssistant` class is initialized with the OpenAI client and Mem0 memory setup.
|
||||
- **Asking Questions**: The `ask_question` method sends a question to the AI, incorporates previous memories, and stores new information.
|
||||
- **Memory Management**: The `get_memories` and search_memories methods handle retrieval and searching of stored memories.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Set your OpenAI API key in the environment variable.
|
||||
2. Instantiate the `PersonalTravelAssistant`.
|
||||
3. Use the `main()` function to interact with the assistant in a loop.
|
||||
|
||||
## Conclusion
|
||||
|
||||
This Personalized AI Travel Assistant leverages Mem0's memory capabilities to provide context-aware responses. As you interact with it, the assistant learns and improves, offering increasingly personalized travel advice and information.
|
||||
|
Before Width: | Height: | Size: 70 KiB |
@@ -0,0 +1,49 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="white"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="url(#paint0_radial_101_2703)"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="black" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M7.95343 21.1394C4.89586 21.1304 2.25471 19.458 0.987296 16.2895C-0.280118 13.121 0.108924 9.16314 1.74363 5.61505C4.8012 5.62409 7.44235 7.29648 8.70976 10.465C9.97718 13.6335 9.58814 17.5914 7.95343 21.1394Z" fill="url(#paint1_linear_101_2703)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M8.68359 10.4755C9.94543 13.63 9.56145 17.5723 7.9354 21.1112C4.89702 21.0957 2.27411 19.4306 1.01347 16.279C-0.248375 13.1245 0.135612 9.18218 1.76165 5.64328C4.80004 5.65883 7.42295 7.32386 8.68359 10.4755Z" stroke="url(#paint2_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<path d="M7.31038 21.2574C11.3543 20.2215 14.8836 17.3754 16.6285 13.2361C18.3735 9.09671 17.9448 4.58749 15.8598 0.976291C11.8159 2.01214 8.2866 4.85826 6.54167 8.99762C4.79674 13.137 5.2254 17.6462 7.31038 21.2574Z" fill="white"/>
|
||||
<path d="M7.31038 21.2574C11.3543 20.2215 14.8836 17.3754 16.6285 13.2361C18.3735 9.09671 17.9448 4.58749 15.8598 0.976291C11.8159 2.01214 8.2866 4.85826 6.54167 8.99762C4.79674 13.137 5.2254 17.6462 7.31038 21.2574Z" fill="url(#paint3_radial_101_2703)"/>
|
||||
<path d="M16.6026 13.2251C14.8642 17.349 11.3512 20.1866 7.32411 21.2248C5.25257 17.624 4.82926 13.1324 6.56764 9.00855C8.30603 4.88472 11.819 2.04706 15.8461 1.00889C17.9176 4.60967 18.3409 9.10131 16.6026 13.2251Z" stroke="url(#paint4_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="white"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="url(#paint5_radial_101_2703)"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="black" fill-opacity="0.2" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M7.23368 21.2069C9.78906 23.2373 13.2102 23.9506 16.5772 22.8141C19.9441 21.6775 22.5058 18.9445 23.7304 15.6382C21.175 13.6078 17.7538 12.8944 14.3869 14.031C11.0199 15.1676 8.45822 17.9006 7.23368 21.2069Z" fill="url(#paint6_linear_101_2703)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M16.5682 22.7874C13.2176 23.9184 9.81361 23.2124 7.2672 21.1975C8.49194 17.9068 11.0444 15.189 14.3959 14.0577C17.7465 12.9266 21.1504 13.6326 23.6968 15.6476C22.4721 18.9383 19.9196 21.656 16.5682 22.7874Z" stroke="url(#paint7_linear_101_2703)" stroke-opacity="0.05" stroke-width="0.056338"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(-3.00503 15.023) rotate(-10.029) scale(17.9572 17.784)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint1_linear_101_2703" x1="7.39036" y1="4.81308" x2="1.62975" y2="18.6894" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_101_2703" x1="7.94816" y1="8.01563" x2="1.7612" y2="18.746" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint3_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(8.11404 20.8822) rotate(-75.7542) scale(21.6246 23.7772)">
|
||||
<stop stop-color="#00BBBB"/>
|
||||
<stop offset="0.712616" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint4_linear_101_2703" x1="7.60205" y1="5.8709" x2="15.5561" y2="16.3719" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint5_radial_101_2703" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(7.84537 21.5181) rotate(-20.3525) scale(18.5603 17.32)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint6_linear_101_2703" x1="16.8078" y1="13.0071" x2="10.0409" y2="22.9937" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00B1BC"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_101_2703" x1="16.8078" y1="13.0071" x2="14.1687" y2="23.841" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -1,68 +0,0 @@
|
||||
---
|
||||
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" />
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
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.
|
||||
@@ -1,58 +0,0 @@
|
||||
---
|
||||
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.
|
||||
```
|
||||
|
After Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 843 KiB |
|
Before Width: | Height: | Size: 256 KiB |
|
After Width: | Height: | Size: 4.6 MiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 565 KiB |
|
After Width: | Height: | Size: 3.9 MiB |
|
After Width: | Height: | Size: 180 KiB |
|
After Width: | Height: | Size: 169 KiB |
@@ -1,51 +0,0 @@
|
||||
---
|
||||
title: '🛠️ LangSmith'
|
||||
description: 'Integrate with Langsmith to debug and monitor your LLM app'
|
||||
---
|
||||
|
||||
Embedchain now supports integration with [LangSmith](https://www.langchain.com/langsmith).
|
||||
|
||||
To use langsmith, you need to do the following steps
|
||||
|
||||
1. Have an account on langsmith and keep the environment variables in handy
|
||||
2. Set the environments variables in your app so that embedchain has context about it.
|
||||
3. Just use embedchain and everything will be logged to LangSmith, so that you can better test and monitor your application.
|
||||
|
||||
Lets cover each step in detail.
|
||||
|
||||
* First make sure that you a LangSmith account created and have all the necessary variables handy. LangSmith has a [good documentation](https://docs.smith.langchain.com/) on how to get started with their service.
|
||||
|
||||
* Once you have the account setup, we will need the following environment variables
|
||||
|
||||
```bash
|
||||
export LANGCHAIN_TRACING_V2=true
|
||||
export LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
|
||||
export LANGCHAIN_API_KEY=<your-api-key>
|
||||
export LANGCHAIN_PROJECT=<your-project> # if not specified, defaults to "default"
|
||||
```
|
||||
|
||||
If you are using Python, you can use the following code to set environment variables
|
||||
|
||||
```python
|
||||
import os
|
||||
|
||||
os.environ['LANGCHAIN_TRACING_V2'] = 'true'
|
||||
os.environ['LANGCHAIN_ENDPOINT'] = 'https://api.smith.langchain.com'
|
||||
os.environ['LANGCHAIN_API_KEY'] = <your-api-key>
|
||||
os.environ['LANGCHAIN_PROJECT] = <your-project>
|
||||
```
|
||||
|
||||
* Now create an app using embedchain and everything will be automatically visible in the LangSmith
|
||||
|
||||
|
||||
```python
|
||||
from embedchain import App
|
||||
|
||||
app = App()
|
||||
app.add("https://en.wikipedia.org/wiki/Elon_Musk")
|
||||
app.query("How many companies did Elon found?")
|
||||
```
|
||||
|
||||
* Now the entire log for this will be visible in langsmith.
|
||||
|
||||
<img src="/images/langsmith.png"/>
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: MultiOn
|
||||
---
|
||||
|
||||
Build personal browser agent remembers user preferences and automates web tasks. It integrates Mem0 for memory management with MultiOn for executing browser actions, enabling personalized and efficient web interactions.
|
||||
|
||||
## Overview
|
||||
|
||||
In this example, we will create a Browser based AI Agent that searches [arxiv.org](https://arxiv.org) for research papers relevant to user's research interests.
|
||||
|
||||
## Setup and Configuration
|
||||
|
||||
Install necessary libraries:
|
||||
|
||||
```bash
|
||||
pip install mem0ai multion
|
||||
```
|
||||
|
||||
First, we'll import the necessary libraries and set up our configurations.
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
from multion.client import MultiOn
|
||||
|
||||
# Configuration
|
||||
OPENAI_API_KEY = 'sk-xxx' # Replace with your actual OpenAI API key
|
||||
MULTION_API_KEY = 'your-multion-key' # Replace with your actual MultiOn API key
|
||||
USER_ID = "deshraj"
|
||||
|
||||
# Set up OpenAI API key
|
||||
os.environ['OPENAI_API_KEY'] = OPENAI_API_KEY
|
||||
|
||||
# Initialize Mem0 and MultiOn
|
||||
memory = Memory()
|
||||
multion = MultiOn(api_key=MULTION_API_KEY)
|
||||
```
|
||||
|
||||
## Add memories to Mem0
|
||||
|
||||
Next, we'll define our user data and add it to Mem0.
|
||||
|
||||
```python
|
||||
# Define user data
|
||||
USER_DATA = """
|
||||
About me
|
||||
- I'm Deshraj Yadav, Co-founder and CTO at Mem0, interested in AI and ML Infrastructure.
|
||||
- Previously, I was a Senior Autopilot Engineer at Tesla, leading the AI Platform for Autopilot.
|
||||
- I built EvalAI at Georgia Tech, an open-source platform for evaluating ML algorithms.
|
||||
- Outside of work, I enjoy playing cricket in two leagues in the San Francisco.
|
||||
"""
|
||||
|
||||
# Add user data to memory
|
||||
memory.add(USER_DATA, user_id=USER_ID)
|
||||
print("User data added to memory.")
|
||||
```
|
||||
|
||||
## Retrieving Relevant Memories
|
||||
|
||||
Now, we'll define our search command and retrieve relevant memories from Mem0.
|
||||
|
||||
```python
|
||||
# Define search command and retrieve relevant memories
|
||||
command = "Find papers on arxiv that I should read based on my interests."
|
||||
|
||||
relevant_memories = memory.search(command, user_id=USER_ID, limit=3)
|
||||
relevant_memories_text = '\n'.join(mem['text'] for mem in relevant_memories)
|
||||
print(f"Relevant memories:")
|
||||
print(relevant_memories_text)
|
||||
```
|
||||
|
||||
## Browsing arXiv
|
||||
|
||||
Finally, we'll use MultiOn to browse arXiv based on our command and relevant memories.
|
||||
|
||||
```python
|
||||
# Create prompt and browse arXiv
|
||||
prompt = f"{command}\n My past memories: {relevant_memories_text}"
|
||||
browse_result = multion.browse(cmd=prompt, url="https://arxiv.org/")
|
||||
print(browse_result)
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
By integrating Mem0 with MultiOn, you've created a personalized browser agent that remembers user preferences and automates web tasks. For more details and advanced usage, refer to the full [cookbook here](https://github.com/mem0ai/mem0/blob/main/cookbooks/mem0-multion.ipynb).
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: 🤖 Overview
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Mem0 includes built-in support for various popular large language models. Memory can utilize the LLM provided by the user, ensuring efficient use for specific needs.
|
||||
|
||||
<CardGroup cols={4}>
|
||||
<Card title="OpenAI" href="#openai"></Card>
|
||||
<Card title="Groq" href="#groq"></Card>
|
||||
<Card title="Together" href="#together"></Card>
|
||||
<Card title="AWS Bedrock" href="#aws_bedrock"></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 mem0 import Memory
|
||||
|
||||
os.environ['OPENAI_API_KEY'] = 'xxx'
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## Groq
|
||||
|
||||
[Groq](https://groq.com/) is the creator of the world's first Language Processing Unit (LPU), providing exceptional speed performance for AI workloads running on their LPU Inference Engine.
|
||||
|
||||
In order to use LLMs from Groq, go to their [platform](https://console.groq.com/keys) and get the API key. Set the API key as `GROQ_API_KEY` environment variable to use the model as given below in the example.
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ['GROQ_API_KEY'] = 'xxx'
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "groq",
|
||||
"config": {
|
||||
"model": "mixtral-8x7b-32768",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 1000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## TogetherAI
|
||||
|
||||
To use TogetherAI LLM models, you have to set the `TOGETHER_API_KEY` environment variable. You can obtain the TogetherAI API key from their [Account settings page](https://api.together.xyz/settings/api-keys).
|
||||
|
||||
Once you have obtained the key, you can use it like this:
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ['TOGETHER_API_KEY'] = 'xxx'
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "togetherai",
|
||||
"config": {
|
||||
"model": "mistralai/Mixtral-8x7B-Instruct-v0.1",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
## AWS Bedrock
|
||||
|
||||
### Setup
|
||||
- Before using the AWS Bedrock LLM, make sure you have the appropriate model access from [Bedrock Console](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess).
|
||||
- You will also need to authenticate the `boto3` client by using a method in the [AWS documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials)
|
||||
- You will have to export `AWS_REGION`, `AWS_ACCESS_KEY`, and `AWS_SECRET_ACCESS_KEY` to set environment variables.
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ['AWS_REGION'] = 'us-east-1'
|
||||
os.environ["AWS_ACCESS_KEY"] = "xx"
|
||||
os.environ["AWS_SECRET_ACCESS_KEY"] = "xx"
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "aws_bedrock",
|
||||
"config": {
|
||||
"model": "arn:aws:bedrock:us-east-1:123456789012:model/your-model-name",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 1500,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 13 KiB |
@@ -1,115 +1,94 @@
|
||||
{
|
||||
"$schema": "https://mintlify.com/schema.json",
|
||||
"name": "Embedchain",
|
||||
"name": "Mem0.ai",
|
||||
"favicon": "/logo/favicon.png",
|
||||
"colors": {
|
||||
"primary": "#3B2FC9",
|
||||
"light": "#6673FF",
|
||||
"dark": "#3B2FC9",
|
||||
"background": {
|
||||
"dark": "#0f1117",
|
||||
"light": "#fff"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"dark": "/logo/dark.svg",
|
||||
"light": "/logo/light.svg"
|
||||
"light": "/logo/light.svg",
|
||||
"href": "https://github.com/embedchain/embedchain"
|
||||
},
|
||||
"favicon": "/favicon.png",
|
||||
"colors": {
|
||||
"primary": "#12A7D3",
|
||||
"light": "#81D7F7",
|
||||
"dark": "#004E7A"
|
||||
},
|
||||
"topbarLinks": [
|
||||
"tabs": [
|
||||
{
|
||||
"name": "Twitter",
|
||||
"url": "https://twitter.com/embedchain"
|
||||
"name": "💡 Examples",
|
||||
"url": "examples"
|
||||
},
|
||||
{
|
||||
"name":"Slack",
|
||||
"url":"https://join.slack.com/t/embedchain/shared_invite/zt-22uwz3c46-Zg7cIh5rOBteT_xe1jwLDw"
|
||||
"name": "🖥️ Platform",
|
||||
"url": "platform"
|
||||
}
|
||||
],
|
||||
"topbarLinks": [
|
||||
{
|
||||
"name": "Support",
|
||||
"url": "mailto:founders@mem0.ai"
|
||||
}
|
||||
],
|
||||
"anchors": [
|
||||
{
|
||||
"name": "Slack",
|
||||
"icon": "slack",
|
||||
"url": "https://mem0.ai/slack/"
|
||||
},
|
||||
{
|
||||
"name": "Discord",
|
||||
"url": "https://discord.gg/6PzXDgEjG5"
|
||||
"icon": "discord",
|
||||
"url": "https://mem0.ai/discord/"
|
||||
},
|
||||
{
|
||||
"name": "Talk to founders",
|
||||
"icon": "calendar",
|
||||
"url": "https://cal.com/taranjeetio/meet"
|
||||
}
|
||||
],
|
||||
"topbarCtaButton": {
|
||||
"name": "GitHub",
|
||||
"url": "https://embedchain.ai"
|
||||
},
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Get started",
|
||||
"pages": ["get-started/quickstart", "get-started/introduction", "get-started/faq", "get-started/examples"]
|
||||
},
|
||||
{
|
||||
"group": "Components",
|
||||
"pages": ["components/llms", "components/embedding-models", "components/vector-databases"]
|
||||
},
|
||||
{
|
||||
"group": "Data sources",
|
||||
"group": "Get Started",
|
||||
"pages": [
|
||||
"data-sources/overview",
|
||||
{
|
||||
"group": "Supported data sources",
|
||||
"pages": [
|
||||
"data-sources/csv",
|
||||
"data-sources/json",
|
||||
"data-sources/docs-site",
|
||||
"data-sources/docx",
|
||||
"data-sources/mdx",
|
||||
"data-sources/notion",
|
||||
"data-sources/pdf-file",
|
||||
"data-sources/qna",
|
||||
"data-sources/sitemap",
|
||||
"data-sources/text",
|
||||
"data-sources/web-page",
|
||||
"data-sources/openapi",
|
||||
"data-sources/youtube-video"
|
||||
]
|
||||
},
|
||||
"data-sources/data-type-handling"
|
||||
"overview",
|
||||
"quickstart"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": "Community",
|
||||
"group": "LLMs",
|
||||
"pages": [
|
||||
"community/connect-with-us",
|
||||
"community/showcase"
|
||||
"llms"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Integrations",
|
||||
"pages": ["integration/langsmith"]
|
||||
},
|
||||
{
|
||||
"group": "Contribute",
|
||||
"pages": [
|
||||
"contribution/guidelines",
|
||||
"contribution/dev",
|
||||
"contribution/docs",
|
||||
"contribution/python",
|
||||
"contribution/javascript"
|
||||
"integrations/multion"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Product",
|
||||
"group": "💡 Examples",
|
||||
"pages": [
|
||||
"product/release-notes"
|
||||
"examples/overview",
|
||||
"examples/personal-ai-tutor",
|
||||
"examples/customer-support-agent",
|
||||
"examples/personal-travel-assistant"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "🖥️ Platform",
|
||||
"pages": [
|
||||
"platform/overview",
|
||||
"platform/quickstart"
|
||||
]
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
"footerSocials": {
|
||||
"website": "https://embedchain.ai",
|
||||
"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,
|
||||
"feedback.thumbsRating": true
|
||||
}
|
||||
"x": "https://x.com/mem0ai",
|
||||
"github": "https://github.com/embedchain/embedchain/mem0",
|
||||
"linkedin": "https://www.linkedin.com/company/mem0/"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
title: 📚 Overview
|
||||
description: 'Welcome to the Mem0 docs!'
|
||||
---
|
||||
|
||||
> Mem0 provides a smart, self-improving memory layer for Large Language Models, enabling personalized AI experiences across applications.
|
||||
|
||||
## Core features
|
||||
|
||||
- **User, Session, and AI Agent Memory**: Retains information across user sessions, interactions, and AI agents, ensuring continuity and context.
|
||||
- **Adaptive Personalization**: Continuously improves personalization based on user interactions and feedback.
|
||||
- **Developer-Friendly API**: Offers a straightforward API for seamless integration into various applications.
|
||||
- **Platform Consistency**: Ensures consistent behavior and data across different platforms and devices.
|
||||
- **Managed Service**: Provides a hosted solution for easy deployment and maintenance.
|
||||
|
||||
If you are looking to quick start, jump to one of the following links:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Quickstart" icon="square-1" href="/quickstart/">
|
||||
Jump to quickstart section to get started
|
||||
</Card>
|
||||
<Card title="Examples" icon="square-2" href="/examples/overview/">
|
||||
Checkout curated examples
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
- **Personalized Learning Assistants**: Long-term memory allows learning assistants to remember user preferences, past interactions, and progress, providing a more tailored and effective learning experience.
|
||||
|
||||
- **Customer Support AI Agents**: By retaining information from previous interactions, customer support bots can offer more accurate and context-aware assistance, improving customer satisfaction and reducing resolution times.
|
||||
|
||||
- **Healthcare Assistants**: Long-term memory enables healthcare assistants to keep track of patient history, medication schedules, and treatment plans, ensuring personalized and consistent care.
|
||||
|
||||
- **Virtual Companions**: Virtual companions can use long-term memory to build deeper relationships with users by remembering personal details, preferences, and past conversations, making interactions more meaningful.
|
||||
|
||||
- **Productivity Tools**: Long-term memory helps productivity tools remember user habits, frequently used documents, and task history, streamlining workflows and enhancing efficiency.
|
||||
|
||||
- **Gaming AI**: In gaming, AI with long-term memory can create more immersive experiences by remembering player choices, strategies, and progress, adapting the game environment accordingly.
|
||||
|
||||
## How is Mem0 different from RAG?
|
||||
|
||||
Mem0's memory implementation for Large Language Models (LLMs) offers several advantages over Retrieval-Augmented Generation (RAG):
|
||||
|
||||
- **Entity Relationships**: Mem0 can understand and relate entities across different interactions, unlike RAG which retrieves information from static documents. This leads to a deeper understanding of context and relationships.
|
||||
|
||||
- **Recency, Relevancy, and Decay**: Mem0 prioritizes recent interactions and gradually forgets outdated information, ensuring the memory remains relevant and up-to-date for more accurate responses.
|
||||
|
||||
- **Contextual Continuity**: Mem0 retains information across sessions, maintaining continuity in conversations and interactions, which is essential for long-term engagement applications like virtual companions or personalized learning assistants.
|
||||
|
||||
- **Adaptive Learning**: Mem0 improves its personalization based on user interactions and feedback, making the memory more accurate and tailored to individual users over time.
|
||||
|
||||
- **Dynamic Updates**: Mem0 can dynamically update its memory with new information and interactions, unlike RAG which relies on static data. This allows for real-time adjustments and improvements, enhancing the user experience.
|
||||
|
||||
These advanced memory capabilities make Mem0 a powerful tool for developers aiming to create personalized and context-aware AI applications.
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: 'Empower your AI applications with long-term memory and personalization'
|
||||
---
|
||||
|
||||
## Welcome to Mem0 Platform
|
||||
|
||||
Mem0 Platform is a managed service that revolutionizes the way AI applications handle memory. By providing a smart, self-improving memory layer for Large Language Models (LLMs), we enable developers to create personalized AI experiences that evolve with each user interaction.
|
||||
|
||||
## Why Choose Mem0 Platform?
|
||||
|
||||
1. **Enhanced User Experience**: Deliver tailored interactions that make your AI applications truly stand out.
|
||||
2. **Simplified Development**: Our API-first approach streamlines integration, allowing you to focus on building great features.
|
||||
3. **Scalable Solution**: Designed to grow with your application, from prototypes to production-ready systems.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Comprehensive Memory Management**: Easily manage long-term, short-term, semantic, and episodic memories for individual users, agents, and sessions through our robust APIs.
|
||||
- **Self-Improving Memory**: Our adaptive system continuously learns from user interactions, refining its understanding over time.
|
||||
- **Cross-Platform Consistency**: Ensure a unified user experience across various AI platforms and applications.
|
||||
- **Centralized Memory Control**: Store, update, and delete memories effortlessly, taking away the hassle of memory management.
|
||||
|
||||
## Common Use Cases
|
||||
|
||||
- Personalized Learning Assistants
|
||||
- Customer Support AI Agents
|
||||
- Healthcare Assistants
|
||||
- Virtual Companions
|
||||
- Productivity Tools
|
||||
- Gaming AI
|
||||
|
||||
## Getting Started
|
||||
Ready to supercharge your AI application with Mem0? Follow these steps:
|
||||
|
||||
1. **Sign Up**: Create your Mem0 account at our platform.
|
||||
2. **API Key**: Generate your API key in the dashboard.
|
||||
3. **Installation**: Install our Python SDK using pip: `pip install mem0ai`
|
||||
4. **Quick Implementation**: Check out our [Quickstart Guide](/platform/quickstart) to start using Mem0 quickly.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Explore our API Reference for detailed endpoint documentation.
|
||||
- Join our [slack](https://mem0.ai/slack) or [discord](https://mem0.ai/discord) with other developers and get support.
|
||||
|
||||
We're excited to see what you'll build with Mem0 Platform. Let's create smarter, more personalized AI experiences together!
|
||||
@@ -0,0 +1,358 @@
|
||||
---
|
||||
title: Quickstart
|
||||
description: 'Get started with Mem0 Platform in minutes'
|
||||
---
|
||||
|
||||
## 1. Installation
|
||||
|
||||
Install the Mem0 Python package:
|
||||
|
||||
```bash
|
||||
pip install mem0ai
|
||||
```
|
||||
|
||||
## 2. API Key Setup
|
||||
|
||||
1. Sign in to [Mem0 Platform](https://app.mem0.ai/dashboard/api-keys)
|
||||
2. Copy your API Key from the dashboard
|
||||
|
||||

|
||||
|
||||
## 3. Instantiate Client
|
||||
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
client = MemoryClient(api_key="your-api-key")
|
||||
```
|
||||
|
||||
## 4. Memory Operations
|
||||
|
||||
We provide a simple yet customizable interface for performing CRUD operations on memory. Here is how you can create and get memories:
|
||||
|
||||
|
||||
### 4.1 Create Memories
|
||||
|
||||
For users (long-term memory):
|
||||
|
||||
```python
|
||||
# create long-term memory for users
|
||||
client.add("Remember my name is Deshraj Yadav.", user_id="deshraj")
|
||||
client.add("I like to eat pizza and go out on weekends.", user_id="deshraj")
|
||||
client.add("Oh I am actually allergic to cheese to cannot eat pizza anymore.", user_id="deshraj")
|
||||
```
|
||||
|
||||
Output:
|
||||
```python
|
||||
{'message': 'Memory added successfully!'}
|
||||
```
|
||||
|
||||
You can see all the memory operations happening on the platform itself.
|
||||
|
||||

|
||||
|
||||
|
||||
You can also add memories for a particular session or for an AI agent that you are building:
|
||||
|
||||
- For user sessions (short-term memory):
|
||||
|
||||
```python
|
||||
client.add("Deshraj is building Gmail AI agent", user_id="deshraj", session_id="session-1")
|
||||
```
|
||||
|
||||
- For agents (long-term memory):
|
||||
|
||||
```python
|
||||
client.add("Return short responses when responding to emails", agent_id="gmail-agent")
|
||||
```
|
||||
|
||||
### 4.2 Retrieve Memories
|
||||
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
client.get_all(user_id="deshraj")
|
||||
```
|
||||
|
||||
```python Output
|
||||
[
|
||||
{
|
||||
'id': 'dbce6e06-6adf-40b8-9187-3d30bd13b741',
|
||||
'agent': None,
|
||||
'consumer': {
|
||||
'id': 8,
|
||||
'user_id': 'deshraj',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:23.899900-07:00',
|
||||
'updated_at': '2024-07-17T16:47:23.899918-07:00'
|
||||
},
|
||||
'app': None,
|
||||
'run': None,
|
||||
'hash': '57288ac8a87c4ac8d3ac7f2075d264ca',
|
||||
'input': 'Remember my name is Deshraj Yadav.',
|
||||
'text': 'My name is Deshraj Yadav.',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:25.670180-07:00',
|
||||
'updated_at': '2024-07-17T16:47:25.670197-07:00'
|
||||
},
|
||||
{
|
||||
'id': 'f6dec5d1-b5db-45f5-a2fb-3979a0f27d30',
|
||||
'agent': None,
|
||||
'consumer': {
|
||||
'id': 8,
|
||||
'user_id': 'deshraj',
|
||||
# ... other consumer fields ...
|
||||
},
|
||||
# ... other fields ...
|
||||
'text': 'I am allergic to cheese so I cannot eat pizza anymore.',
|
||||
# ... remaining fields ...
|
||||
},
|
||||
# ... additional memory entries ...
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Similarly, you can get all memories for an agent:
|
||||
|
||||
```python
|
||||
agent_memories = client.get_all(agent_id="gmail-agent")
|
||||
```
|
||||
|
||||
Get specific memory:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
memory = client.get(memory_id="dbce6e06-6adf-40b8-9187-3d30bd13b741")
|
||||
```
|
||||
|
||||
```python Output
|
||||
{
|
||||
'id': 'dbce6e06-6adf-40b8-9187-3d30bd13b741',
|
||||
'agent': None,
|
||||
'consumer': {
|
||||
'id': 8,
|
||||
'user_id': 'deshraj',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:23.899900-07:00',
|
||||
'updated_at': '2024-07-17T16:47:23.899918-07:00'
|
||||
},
|
||||
'app': None,
|
||||
'run': None,
|
||||
'hash': '57288ac8a87c4ac8d3ac7f2075d264ca',
|
||||
'input': 'Remember my name is Deshraj Yadav.',
|
||||
'text': 'My name is Deshraj Yadav.',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:25.670180-07:00',
|
||||
'updated_at': '2024-07-17T16:47:25.670197-07:00'
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### 4.3 Update Memory
|
||||
|
||||
You can also update specific memory by using the following method:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
client.update(memory_id, data="Updated name is Deshraj Kumar")
|
||||
```
|
||||
|
||||
```python Output
|
||||
{
|
||||
'id': 'dbce6e06-6adf-40b8-9187-3d30bd13b741',
|
||||
'agent': None,
|
||||
'consumer': {
|
||||
'id': 8,
|
||||
'user_id': 'deshraj',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:23.899900-07:00',
|
||||
'updated_at': '2024-07-17T16:47:23.899918-07:00'
|
||||
},
|
||||
'app': None,
|
||||
'run': None,
|
||||
'hash': '57288ac8a87c4ac8d3ac7f2075d264ca',
|
||||
'input': 'Updated name is Deshraj Kumar.',
|
||||
'text': 'Name is Deshraj Kumar.',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:25.670180-07:00',
|
||||
'updated_at': '2024-07-17T16:47:25.670197-07:00'
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
### 4.4 Memory History
|
||||
|
||||
Get history of how a memory has changed over time
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
history = client.history(memory_id)
|
||||
```
|
||||
|
||||
```python Output
|
||||
[
|
||||
{
|
||||
'id': '51193804-2ee6-4f81-b4e7-497e98b70858',
|
||||
'memory': {
|
||||
'id': 'dbce6e06-6adf-40b8-9187-3d30bd13b741',
|
||||
'agent': None,
|
||||
'consumer': {
|
||||
'id': 8,
|
||||
'user_id': 'deshraj',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:23.899900-07:00',
|
||||
'updated_at': '2024-07-17T16:47:23.899918-07:00'
|
||||
},
|
||||
'app': None,
|
||||
'run': None,
|
||||
'hash': '57288ac8a87c4ac8d3ac7f2075d264ca',
|
||||
'input': 'Remember my name is Deshraj Yadav.',
|
||||
'text': 'My name is Deshraj Yadav.',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:25.670180-07:00',
|
||||
'updated_at': '2024-07-17T16:47:25.670197-07:00'
|
||||
},
|
||||
'hash': '57288ac8a87c4ac8d3ac7f2075d264ca',
|
||||
'event': 'ADD',
|
||||
'input': 'Remember my name is Deshraj Yadav.',
|
||||
'previous_text': None,
|
||||
'text': 'My name is Deshraj Yadav.',
|
||||
'metadata': None,
|
||||
'created_at': '2024-07-17T16:47:25.686899-07:00',
|
||||
'updated_at': '2024-07-17T16:47:25.670197-07:00',
|
||||
'change_description': 'Memory ADD event'
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### 4.5 Search for relevant memories
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
client.search("What does Deshraj like to eat?", user_id="deshraj", limit=3)
|
||||
```
|
||||
|
||||
```python Output
|
||||
[
|
||||
{
|
||||
"id": "dbce6e06-6adf-40b8-9187-3d30bd13b741",
|
||||
"agent": null,
|
||||
"consumer": {
|
||||
"id": 8,
|
||||
"user_id": "deshraj",
|
||||
"metadata": null,
|
||||
"created_at": "...",
|
||||
"updated_at": "..."
|
||||
},
|
||||
"app": null,
|
||||
"run": null,
|
||||
"hash": "57288ac8a87c4ac8d3ac7f2075d264ca",
|
||||
"input": "Remember my name is Deshraj Yadav.",
|
||||
"text": "My name is Deshraj Yadav.",
|
||||
"metadata": null,
|
||||
"created_at": "2024-07-17T16:47:25.670180-07:00",
|
||||
"updated_at": "..."
|
||||
},
|
||||
{
|
||||
"id": "091dbed6-74b4-4e15-b765-81be2abe0d6b",
|
||||
"agent": null,
|
||||
"consumer": {
|
||||
"id": 8,
|
||||
"user_id": "deshraj",
|
||||
"metadata": null,
|
||||
"created_at": "...",
|
||||
"updated_at": "..."
|
||||
},
|
||||
"app": null,
|
||||
"run": null,
|
||||
"hash": "622a5a24d5ac54136414a22ec12f9520",
|
||||
"input": "Oh I am actually allergic to cheese to cannot eat pizza anymore.",
|
||||
"text": "I like to eat pizza and go out on weekends.",
|
||||
"metadata": null,
|
||||
"created_at": "2024-07-17T16:49:24.276695-07:00",
|
||||
"updated_at": "..."
|
||||
},
|
||||
{
|
||||
"id": "5fb8f85d-3383-4bad-9d46-f171272478a4",
|
||||
"agent": null,
|
||||
"consumer": {
|
||||
"id": 8,
|
||||
"user_id": "deshraj",
|
||||
"metadata": null,
|
||||
"created_at": "...",
|
||||
"updated_at": "..."
|
||||
},
|
||||
"app": null,
|
||||
"run": {
|
||||
"id": 1,
|
||||
"run_id": "session-1",
|
||||
"name": "",
|
||||
"metadata": null,
|
||||
"created_at": "...",
|
||||
"updated_at": "..."
|
||||
},
|
||||
"hash": "179ced9649ac2b85350ece4946b1ee9b",
|
||||
"input": "Deshraj is building Gmail AI agent",
|
||||
"text": "Deshraj is building Gmail AI agent",
|
||||
"metadata": null,
|
||||
"created_at": "2024-07-17T16:52:41.278920-07:00",
|
||||
"updated_at": "..."
|
||||
},
|
||||
{
|
||||
"id": "f6dec5d1-b5db-45f5-a2fb-3979a0f27d30",
|
||||
"agent": null,
|
||||
"consumer": {
|
||||
"id": 8,
|
||||
"user_id": "deshraj",
|
||||
"metadata": null,
|
||||
"created_at": "...",
|
||||
"updated_at": "..."
|
||||
},
|
||||
"app": null,
|
||||
"run": null,
|
||||
"hash": "19248f0766044b5973fc0ef1bf3955ef",
|
||||
"input": "Oh I am actually allergic to cheese to cannot eat pizza anymore.",
|
||||
"text": "I am allergic to cheese so I cannot eat pizza anymore.",
|
||||
"metadata": null,
|
||||
"created_at": "2024-07-17T16:49:38.622084-07:00",
|
||||
"updated_at": "..."
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
### 4.6 Delete Memory
|
||||
|
||||
Delete specific memory:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
client.delete(memory_id)
|
||||
```
|
||||
|
||||
```python Output
|
||||
{'message': 'Memory deleted successfully!'}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
Delete all memories of a user:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Code
|
||||
client.delete_all(user_id="alex")
|
||||
```
|
||||
|
||||
```python Output
|
||||
{'message': 'Memories deleted successfully!'}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -0,0 +1,210 @@
|
||||
---
|
||||
title: 🚀 Quickstart
|
||||
description: 'Get started with Mem0 quickly!'
|
||||
---
|
||||
|
||||
> Welcome to the Mem0 quickstart guide. This guide will help you get up and running with Mem0 in no time.
|
||||
|
||||
## Installation
|
||||
|
||||
To install Mem0, you can use pip. Run the following command in your terminal:
|
||||
|
||||
```bash
|
||||
pip install mem0ai
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Initialize Mem0
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Basic">
|
||||
```python
|
||||
from mem0 import Memory
|
||||
m = Memory()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Advanced">
|
||||
If you want to run Mem0 in production, initialize using the following method:
|
||||
|
||||
Run Qdrant first:
|
||||
|
||||
```bash
|
||||
docker pull qdrant/qdrant
|
||||
|
||||
docker run -p 6333:6333 -p 6334:6334 \
|
||||
-v $(pwd)/qdrant_storage:/qdrant/storage:z \
|
||||
qdrant/qdrant
|
||||
```
|
||||
|
||||
Then, instantiate memory with qdrant server:
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
"config": {
|
||||
"host": "localhost",
|
||||
"port": 6333,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Store a Memory
|
||||
|
||||
```python
|
||||
# For a user
|
||||
result = m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
print(result)
|
||||
```
|
||||
|
||||
Output:
|
||||
```python
|
||||
[
|
||||
{
|
||||
'id': 'm1',
|
||||
'event': 'add',
|
||||
'data': 'Likes to play cricket on weekends'
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Retrieve Memories
|
||||
|
||||
```python
|
||||
# Get all memories
|
||||
all_memories = m.get_all()
|
||||
print(all_memories)
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```python
|
||||
[
|
||||
{
|
||||
'id': 'm1',
|
||||
'text': 'Likes to play cricket on weekends',
|
||||
'metadata': {
|
||||
'data': 'Likes to play cricket on weekends',
|
||||
'category': 'hobbies'
|
||||
}
|
||||
},
|
||||
# ... other memories ...
|
||||
]
|
||||
```
|
||||
|
||||
```python
|
||||
# Get a single memory by ID
|
||||
specific_memory = m.get("m1")
|
||||
print(specific_memory)
|
||||
```
|
||||
|
||||
Output:
|
||||
```python
|
||||
{
|
||||
'id': 'm1',
|
||||
'text': 'Likes to play cricket on weekends',
|
||||
'metadata': {
|
||||
'data': 'Likes to play cricket on weekends',
|
||||
'category': 'hobbies'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Search Memories
|
||||
|
||||
```python
|
||||
related_memories = m.search(query="What are Alice's hobbies?", user_id="alice")
|
||||
print(related_memories)
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```python
|
||||
[
|
||||
{
|
||||
'id': 'm1',
|
||||
'text': 'Likes to play cricket on weekends',
|
||||
'metadata': {
|
||||
'data': 'Likes to play cricket on weekends',
|
||||
'category': 'hobbies'
|
||||
},
|
||||
'score': 0.85 # Similarity score
|
||||
},
|
||||
# ... other related memories ...
|
||||
]
|
||||
```
|
||||
|
||||
### Update a Memory
|
||||
|
||||
```python
|
||||
result = m.update(memory_id="m1", data="Likes to play tennis on weekends")
|
||||
print(result)
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```python
|
||||
{
|
||||
'id': 'm1',
|
||||
'event': 'update',
|
||||
'data': 'Likes to play tennis on weekends'
|
||||
}
|
||||
```
|
||||
|
||||
### Memory History
|
||||
|
||||
```python
|
||||
history = m.history(memory_id="m1")
|
||||
print(history)
|
||||
```
|
||||
Output:
|
||||
```python
|
||||
[
|
||||
{
|
||||
'id': 'h1',
|
||||
'memory_id': 'm1',
|
||||
'prev_value': None,
|
||||
'new_value': 'Likes to play cricket on weekends',
|
||||
'event': 'add',
|
||||
'timestamp': '2024-07-14 10:00:54.466687',
|
||||
'is_deleted': 0
|
||||
},
|
||||
{
|
||||
'id': 'h2',
|
||||
'memory_id': 'm1',
|
||||
'prev_value': 'Likes to play cricket on weekends',
|
||||
'new_value': 'Likes to play tennis on weekends',
|
||||
'event': 'update',
|
||||
'timestamp': '2024-07-14 10:15:17.230943',
|
||||
'is_deleted': 0
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Delete Memory
|
||||
|
||||
```python
|
||||
m.delete(memory_id="m1") # Delete a memory
|
||||
|
||||
m.delete_all(user_id="alice") # Delete all memories
|
||||
```
|
||||
|
||||
### Reset Memory
|
||||
|
||||
```python
|
||||
m.reset() # Reset all memories
|
||||
```
|
||||
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,4 @@
|
||||
One of the core principles of software development is DRY (Don't Repeat
|
||||
Yourself). This is a principle that apply to documentation as
|
||||
well. If you find yourself repeating the same content in multiple places, you
|
||||
should consider creating a custom snippet to keep your content in sync.
|
||||
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
dist
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
// Configuration for JavaScript files
|
||||
"extends": [
|
||||
"airbnb-base",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"singleQuote": true,
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
// Configuration for TypeScript files
|
||||
{
|
||||
"files": ["**/*.ts", "**/__tests__/*.test.ts"],
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"unused-imports",
|
||||
"simple-import-sort"
|
||||
],
|
||||
"extends": [
|
||||
"airbnb-typescript",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"rules": {
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"singleQuote": true,
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/comma-dangle": "off", // Avoid conflict rule between Eslint and Prettier
|
||||
"@typescript-eslint/consistent-type-imports": "error", // Ensure `import type` is used when it's necessary
|
||||
"import/prefer-default-export": "off", // Named export is easier to refactor automatically
|
||||
"simple-import-sort/imports": "error", // Import configuration for `eslint-plugin-simple-import-sort`
|
||||
"simple-import-sort/exports": "error", // Export configuration for `eslint-plugin-simple-import-sort`
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"react/jsx-filename-extension": "off", // Gives error
|
||||
"unused-imports/no-unused-imports": "error",
|
||||
"unused-imports/no-unused-vars": [
|
||||
"error",
|
||||
{ "argsIgnorePattern": "^_" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
name: Node.js Package
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- run: npm ci
|
||||
- run: npm test
|
||||
- run: npm run build
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: types
|
||||
path: types
|
||||
|
||||
publish-npm:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: https://registry.npmjs.org/
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: dist
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: types
|
||||
path: types
|
||||
- run: npm ci
|
||||
- run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
||||
@@ -1,138 +0,0 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
.ideas.md
|
||||
.todos.md
|
||||
|
||||
# Custom
|
||||
dist
|
||||
types
|
||||
build
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no -- commitlint --edit $1
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
# Disable concurent to run `check-types` after ESLint in lint-staged
|
||||
npx lint-staged --concurrent false
|
||||
@@ -1,8 +0,0 @@
|
||||
cff-version: 1.2.0
|
||||
message: "If you use this software, please cite it as below."
|
||||
authors:
|
||||
- family-names: "Singh"
|
||||
given-names: "Taranjeet"
|
||||
title: "Embedchain"
|
||||
date-released: 2023-06-25
|
||||
url: "https://github.com/embedchain/embedchainjs"
|
||||
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,263 +0,0 @@
|
||||
# embedchainjs
|
||||
|
||||
[](https://discord.gg/CUU9FPhRNt)
|
||||
[](https://twitter.com/embedchain)
|
||||
[](https://embedchain.substack.com/)
|
||||
|
||||
embedchain is a framework to easily create LLM powered bots over any dataset. embedchainjs is Javascript version of embedchain. If you want a python version, check out [embedchain-python](https://github.com/embedchain/embedchain)
|
||||
|
||||
# 🤝 Let's Talk Embedchain!
|
||||
|
||||
Schedule a [Feedback Session](https://cal.com/taranjeetio/ec) with Taranjeet, the founder, to discuss any issues, provide feedback, or explore improvements.
|
||||
|
||||
# How it works
|
||||
|
||||
It abstracts the entire process of loading dataset, chunking it, creating embeddings and then storing in vector database.
|
||||
|
||||
You can add a single or multiple dataset using `.add` and `.addLocal` function and then use `.query` function to find an answer from the added datasets.
|
||||
|
||||
If you want to create a Naval Ravikant bot which has 2 of his blog posts, as well as a question and answer pair you supply, all you need to do is add the links to the blog posts and the QnA pair and embedchain will create a bot for you.
|
||||
|
||||
```javascript
|
||||
const dotenv = require("dotenv");
|
||||
dotenv.config();
|
||||
const { App } = require("embedchain");
|
||||
|
||||
//Run the app commands inside an async function only
|
||||
async function testApp() {
|
||||
const navalChatBot = await App();
|
||||
|
||||
// Embed Online Resources
|
||||
await navalChatBot.add("web_page", "https://nav.al/feedback");
|
||||
await navalChatBot.add("web_page", "https://nav.al/agi");
|
||||
await navalChatBot.add(
|
||||
"pdf_file",
|
||||
"https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf"
|
||||
);
|
||||
|
||||
// Embed Local Resources
|
||||
await navalChatBot.addLocal("qna_pair", [
|
||||
"Who is Naval Ravikant?",
|
||||
"Naval Ravikant is an Indian-American entrepreneur and investor.",
|
||||
]);
|
||||
|
||||
const result = await navalChatBot.query(
|
||||
"What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?"
|
||||
);
|
||||
console.log(result);
|
||||
// answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
|
||||
}
|
||||
|
||||
testApp();
|
||||
```
|
||||
|
||||
# Getting Started
|
||||
|
||||
## Installation
|
||||
|
||||
- First make sure that you have the package installed. If not, then install it using `npm`
|
||||
|
||||
```bash
|
||||
npm install embedchain && npm install -S openai@^3.3.0
|
||||
```
|
||||
|
||||
- Currently, it is only compatible with openai 3.X, not the latest version 4.X. Please make sure to use the right version, otherwise you will see the `ChromaDB` error `TypeError: OpenAIApi.Configuration is not a constructor`
|
||||
|
||||
- Make sure that dotenv package is installed and your `OPENAI_API_KEY` in a file called `.env` in the root folder. You can install dotenv by
|
||||
|
||||
```js
|
||||
npm install dotenv
|
||||
```
|
||||
|
||||
- Download and install Docker on your device by visiting [this link](https://www.docker.com/). You will need this to run Chroma vector database on your machine.
|
||||
|
||||
- Run the following commands to setup Chroma container in Docker
|
||||
|
||||
```bash
|
||||
git clone https://github.com/chroma-core/chroma.git
|
||||
cd chroma
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
- Once Chroma container has been set up, run it inside Docker
|
||||
|
||||
## Usage
|
||||
|
||||
- We use 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 have dont 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`
|
||||
|
||||
```js
|
||||
// Set this inside your .env file
|
||||
OPENAI_API_KEY = "sk-xxxx";
|
||||
```
|
||||
|
||||
- Load the environment variables inside your .js file using the following commands
|
||||
|
||||
```js
|
||||
const dotenv = require("dotenv");
|
||||
dotenv.config();
|
||||
```
|
||||
|
||||
- Next import the `App` class from embedchain and use `.add` function to add any dataset.
|
||||
- Now your app is created. You can use `.query` function to get the answer for any query.
|
||||
|
||||
```js
|
||||
const dotenv = require("dotenv");
|
||||
dotenv.config();
|
||||
const { App } = require("embedchain");
|
||||
|
||||
async function testApp() {
|
||||
const navalChatBot = await App();
|
||||
|
||||
// Embed Online Resources
|
||||
await navalChatBot.add("web_page", "https://nav.al/feedback");
|
||||
await navalChatBot.add("web_page", "https://nav.al/agi");
|
||||
await navalChatBot.add(
|
||||
"pdf_file",
|
||||
"https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf"
|
||||
);
|
||||
|
||||
// Embed Local Resources
|
||||
await navalChatBot.addLocal("qna_pair", [
|
||||
"Who is Naval Ravikant?",
|
||||
"Naval Ravikant is an Indian-American entrepreneur and investor.",
|
||||
]);
|
||||
|
||||
const result = await navalChatBot.query(
|
||||
"What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?"
|
||||
);
|
||||
console.log(result);
|
||||
// answer: Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.
|
||||
}
|
||||
|
||||
testApp();
|
||||
```
|
||||
|
||||
- If there is any other app instance in your script or app, you can change the import as
|
||||
|
||||
```javascript
|
||||
const { App: EmbedChainApp } = require("embedchain");
|
||||
|
||||
// or
|
||||
|
||||
const { App: ECApp } = require("embedchain");
|
||||
```
|
||||
|
||||
## Format supported
|
||||
|
||||
We support the following formats:
|
||||
|
||||
### PDF File
|
||||
|
||||
To add any pdf file, use the data_type as `pdf_file`. Eg:
|
||||
|
||||
```javascript
|
||||
await app.add("pdf_file", "a_valid_url_where_pdf_file_can_be_accessed");
|
||||
```
|
||||
|
||||
### Web Page
|
||||
|
||||
To add any web page, use the data_type as `web_page`. Eg:
|
||||
|
||||
```javascript
|
||||
await app.add("web_page", "a_valid_web_page_url");
|
||||
```
|
||||
|
||||
### QnA Pair
|
||||
|
||||
To supply your own QnA pair, use the data_type as `qna_pair` and enter a tuple. Eg:
|
||||
|
||||
```javascript
|
||||
await app.addLocal("qna_pair", ["Question", "Answer"]);
|
||||
```
|
||||
|
||||
### More Formats coming soon
|
||||
|
||||
- If you want to add any other format, please create an [issue](https://github.com/embedchain/embedchainjs/issues) and we will add it to the list of supported formats.
|
||||
|
||||
## Testing
|
||||
|
||||
Before you consume valueable tokens, you should make sure that the embedding you have done works and that it's receiving the correct document from the database.
|
||||
|
||||
For this you can use the `dryRun` method.
|
||||
|
||||
Following the example above, add this to your script:
|
||||
|
||||
```js
|
||||
let result = await naval_chat_bot.dryRun("What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?");console.log(result);
|
||||
|
||||
'''
|
||||
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.
|
||||
terms of the unseen. And I think that’s critical. That is what humans do uniquely that no other creature, no other computer, no other intelligence—biological or artificial—that we have ever encountered does. And not only do we do it uniquely, but if we were to meet an alien species that also had the power to generate these good explanations, there is no explanation that they could generate that we could not understand. We are maximally capable of understanding. There is no concept out there that is possible in this physical reality that a human being, given sufficient time and resources and
|
||||
Query: What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?
|
||||
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.**
|
||||
|
||||
# How does it work?
|
||||
|
||||
Creating a chat bot over any dataset needs the following steps to happen
|
||||
|
||||
- load the data
|
||||
- create meaningful chunks
|
||||
- create embeddings for each chunk
|
||||
- store the chunks in vector database
|
||||
|
||||
Whenever a user asks any query, following process happens to find the answer for the query
|
||||
|
||||
- create the embedding for query
|
||||
- find similar documents for this query from vector database
|
||||
- pass similar documents as context to LLM to get the final answer.
|
||||
|
||||
The process of loading the dataset and then querying involves multiple steps and each steps has nuances of it is own.
|
||||
|
||||
- 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 vector database? Which vector database should I use?
|
||||
- Should I store meta data along with the embeddings?
|
||||
- How should I find similar documents for a query? Which ranking model should I use?
|
||||
|
||||
These questions may be trivial for some but for a lot of us, it needs research, experimentation and time to find out the accurate answers.
|
||||
|
||||
embedchain is a framework which takes care of all these nuances and provides a simple interface to create bots over any dataset.
|
||||
|
||||
In the first release, we are making it easier for anyone to get a chatbot over any dataset up and running in less than a minute. All you need to do is create an app instance, add the data sets using `.add` function and then use `.query` function to get the relevant answer.
|
||||
|
||||
# Tech Stack
|
||||
|
||||
embedchain is built on the following stack:
|
||||
|
||||
- [Langchain](https://github.com/hwchase17/langchain) as an LLM framework to load, chunk and index data
|
||||
- [OpenAI's Ada embedding model](https://platform.openai.com/docs/guides/embeddings) to create embeddings
|
||||
- [OpenAI's ChatGPT API](https://platform.openai.com/docs/guides/gpt/chat-completions-api) as LLM to get answers given the context
|
||||
- [Chroma](https://github.com/chroma-core/chroma) as the vector database to store embeddings
|
||||
|
||||
# Team
|
||||
|
||||
## Author
|
||||
|
||||
- Taranjeet Singh ([@taranjeetio](https://twitter.com/taranjeetio))
|
||||
|
||||
## Maintainer
|
||||
|
||||
- [cachho](https://github.com/cachho)
|
||||
- [sahilyadav902](https://github.com/sahilyadav902)
|
||||
|
||||
## Citation
|
||||
|
||||
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},
|
||||
year = {2023},
|
||||
publisher = {GitHub},
|
||||
journal = {GitHub repository},
|
||||
howpublished = {\url{https://github.com/embedchain/embedchainjs}},
|
||||
}
|
||||
```
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = { extends: ['@commitlint/config-conventional'] };
|
||||
@@ -1,66 +0,0 @@
|
||||
import { EmbedChainApp } from '../embedchain';
|
||||
|
||||
const mockAdd = jest.fn();
|
||||
const mockAddLocal = jest.fn();
|
||||
const mockQuery = jest.fn();
|
||||
|
||||
jest.mock('../embedchain', () => {
|
||||
return {
|
||||
EmbedChainApp: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
add: mockAdd,
|
||||
addLocal: mockAddLocal,
|
||||
query: mockQuery,
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('Test App', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('tests the App', async () => {
|
||||
mockQuery.mockResolvedValue(
|
||||
'Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.'
|
||||
);
|
||||
|
||||
const navalChatBot = await new EmbedChainApp(undefined, false);
|
||||
|
||||
// Embed Online Resources
|
||||
await navalChatBot.add('web_page', 'https://nav.al/feedback');
|
||||
await navalChatBot.add('web_page', 'https://nav.al/agi');
|
||||
await navalChatBot.add(
|
||||
'pdf_file',
|
||||
'https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf'
|
||||
);
|
||||
|
||||
// Embed Local Resources
|
||||
await navalChatBot.addLocal('qna_pair', [
|
||||
'Who is Naval Ravikant?',
|
||||
'Naval Ravikant is an Indian-American entrepreneur and investor.',
|
||||
]);
|
||||
|
||||
const result = await navalChatBot.query(
|
||||
'What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?'
|
||||
);
|
||||
|
||||
expect(mockAdd).toHaveBeenCalledWith('web_page', 'https://nav.al/feedback');
|
||||
expect(mockAdd).toHaveBeenCalledWith('web_page', 'https://nav.al/agi');
|
||||
expect(mockAdd).toHaveBeenCalledWith(
|
||||
'pdf_file',
|
||||
'https://navalmanack.s3.amazonaws.com/Eric-Jorgenson_The-Almanack-of-Naval-Ravikant_Final.pdf'
|
||||
);
|
||||
expect(mockAddLocal).toHaveBeenCalledWith('qna_pair', [
|
||||
'Who is Naval Ravikant?',
|
||||
'Naval Ravikant is an Indian-American entrepreneur and investor.',
|
||||
]);
|
||||
expect(mockQuery).toHaveBeenCalledWith(
|
||||
'What unique capacity does Naval argue humans possess when it comes to understanding explanations or concepts?'
|
||||
);
|
||||
expect(result).toBe(
|
||||
'Naval argues that humans possess the unique capacity to understand explanations or concepts to the maximum extent possible in this physical reality.'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,44 +0,0 @@
|
||||
import { createHash } from 'crypto';
|
||||
import type { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
|
||||
|
||||
import type { BaseLoader } from '../loaders';
|
||||
import type { Input, LoaderResult } from '../models';
|
||||
import type { ChunkResult } from '../models/ChunkResult';
|
||||
|
||||
class BaseChunker {
|
||||
textSplitter: RecursiveCharacterTextSplitter;
|
||||
|
||||
constructor(textSplitter: RecursiveCharacterTextSplitter) {
|
||||
this.textSplitter = textSplitter;
|
||||
}
|
||||
|
||||
async createChunks(loader: BaseLoader, url: Input): Promise<ChunkResult> {
|
||||
const documents: ChunkResult['documents'] = [];
|
||||
const ids: ChunkResult['ids'] = [];
|
||||
const datas: LoaderResult = await loader.loadData(url);
|
||||
const metadatas: ChunkResult['metadatas'] = [];
|
||||
|
||||
const dataPromises = datas.map(async (data) => {
|
||||
const { content, metaData } = data;
|
||||
const chunks: string[] = await this.textSplitter.splitText(content);
|
||||
chunks.forEach((chunk) => {
|
||||
const chunkId = createHash('sha256')
|
||||
.update(chunk + metaData.url)
|
||||
.digest('hex');
|
||||
ids.push(chunkId);
|
||||
documents.push(chunk);
|
||||
metadatas.push(metaData);
|
||||
});
|
||||
});
|
||||
|
||||
await Promise.all(dataPromises);
|
||||
|
||||
return {
|
||||
documents,
|
||||
ids,
|
||||
metadatas,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export { BaseChunker };
|
||||
@@ -1,26 +0,0 @@
|
||||
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
|
||||
|
||||
import { BaseChunker } from './BaseChunker';
|
||||
|
||||
interface TextSplitterChunkParams {
|
||||
chunkSize: number;
|
||||
chunkOverlap: number;
|
||||
keepSeparator: boolean;
|
||||
}
|
||||
|
||||
const TEXT_SPLITTER_CHUNK_PARAMS: TextSplitterChunkParams = {
|
||||
chunkSize: 1000,
|
||||
chunkOverlap: 0,
|
||||
keepSeparator: false,
|
||||
};
|
||||
|
||||
class PdfFileChunker extends BaseChunker {
|
||||
constructor() {
|
||||
const textSplitter = new RecursiveCharacterTextSplitter(
|
||||
TEXT_SPLITTER_CHUNK_PARAMS
|
||||
);
|
||||
super(textSplitter);
|
||||
}
|
||||
}
|
||||
|
||||
export { PdfFileChunker };
|
||||
@@ -1,26 +0,0 @@
|
||||
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
|
||||
|
||||
import { BaseChunker } from './BaseChunker';
|
||||
|
||||
interface TextSplitterChunkParams {
|
||||
chunkSize: number;
|
||||
chunkOverlap: number;
|
||||
keepSeparator: boolean;
|
||||
}
|
||||
|
||||
const TEXT_SPLITTER_CHUNK_PARAMS: TextSplitterChunkParams = {
|
||||
chunkSize: 300,
|
||||
chunkOverlap: 0,
|
||||
keepSeparator: false,
|
||||
};
|
||||
|
||||
class QnaPairChunker extends BaseChunker {
|
||||
constructor() {
|
||||
const textSplitter = new RecursiveCharacterTextSplitter(
|
||||
TEXT_SPLITTER_CHUNK_PARAMS
|
||||
);
|
||||
super(textSplitter);
|
||||
}
|
||||
}
|
||||
|
||||
export { QnaPairChunker };
|
||||
@@ -1,26 +0,0 @@
|
||||
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
|
||||
|
||||
import { BaseChunker } from './BaseChunker';
|
||||
|
||||
interface TextSplitterChunkParams {
|
||||
chunkSize: number;
|
||||
chunkOverlap: number;
|
||||
keepSeparator: boolean;
|
||||
}
|
||||
|
||||
const TEXT_SPLITTER_CHUNK_PARAMS: TextSplitterChunkParams = {
|
||||
chunkSize: 500,
|
||||
chunkOverlap: 0,
|
||||
keepSeparator: false,
|
||||
};
|
||||
|
||||
class WebPageChunker extends BaseChunker {
|
||||
constructor() {
|
||||
const textSplitter = new RecursiveCharacterTextSplitter(
|
||||
TEXT_SPLITTER_CHUNK_PARAMS
|
||||
);
|
||||
super(textSplitter);
|
||||
}
|
||||
}
|
||||
|
||||
export { WebPageChunker };
|
||||
@@ -1,6 +0,0 @@
|
||||
import { BaseChunker } from './BaseChunker';
|
||||
import { PdfFileChunker } from './PdfFile';
|
||||
import { QnaPairChunker } from './QnaPair';
|
||||
import { WebPageChunker } from './WebPage';
|
||||
|
||||
export { BaseChunker, PdfFileChunker, QnaPairChunker, WebPageChunker };
|
||||
@@ -1,317 +0,0 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import type { Collection } from 'chromadb';
|
||||
import type { QueryResponse } from 'chromadb/dist/main/types';
|
||||
import * as fs from 'fs';
|
||||
import { Document } from 'langchain/document';
|
||||
import OpenAI from 'openai';
|
||||
import * as path from 'path';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import type { BaseChunker } from './chunkers';
|
||||
import { PdfFileChunker, QnaPairChunker, WebPageChunker } from './chunkers';
|
||||
import type { BaseLoader } from './loaders';
|
||||
import { LocalQnaPairLoader, PdfFileLoader, WebPageLoader } from './loaders';
|
||||
import type {
|
||||
DataDict,
|
||||
DataType,
|
||||
FormattedResult,
|
||||
Input,
|
||||
LocalInput,
|
||||
Metadata,
|
||||
Method,
|
||||
RemoteInput,
|
||||
} from './models';
|
||||
import { ChromaDB } from './vectordb';
|
||||
import type { BaseVectorDB } from './vectordb/BaseVectorDb';
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: process.env.OPENAI_API_KEY,
|
||||
});
|
||||
|
||||
class EmbedChain {
|
||||
dbClient: any;
|
||||
|
||||
// TODO: Definitely assign
|
||||
collection!: Collection;
|
||||
|
||||
userAsks: [DataType, Input][] = [];
|
||||
|
||||
initApp: Promise<void>;
|
||||
|
||||
collectMetrics: boolean;
|
||||
|
||||
sId: string; // sessionId
|
||||
|
||||
constructor(db?: BaseVectorDB, collectMetrics: boolean = true) {
|
||||
if (!db) {
|
||||
this.initApp = this.setupChroma();
|
||||
} else {
|
||||
this.initApp = this.setupOther(db);
|
||||
}
|
||||
|
||||
this.collectMetrics = collectMetrics;
|
||||
|
||||
// Send anonymous telemetry
|
||||
this.sId = uuidv4();
|
||||
this.sendTelemetryEvent('init');
|
||||
}
|
||||
|
||||
async setupChroma(): Promise<void> {
|
||||
const db = new ChromaDB();
|
||||
await db.initDb;
|
||||
this.dbClient = db.client;
|
||||
if (db.collection) {
|
||||
this.collection = db.collection;
|
||||
} else {
|
||||
// TODO: Add proper error handling
|
||||
console.error('No collection');
|
||||
}
|
||||
}
|
||||
|
||||
async setupOther(db: BaseVectorDB): Promise<void> {
|
||||
await db.initDb;
|
||||
// TODO: Figure out how we can initialize an unknown database.
|
||||
// this.dbClient = db.client;
|
||||
// this.collection = db.collection;
|
||||
this.userAsks = [];
|
||||
}
|
||||
|
||||
static getLoader(dataType: DataType) {
|
||||
const loaders: { [t in DataType]: BaseLoader } = {
|
||||
pdf_file: new PdfFileLoader(),
|
||||
web_page: new WebPageLoader(),
|
||||
qna_pair: new LocalQnaPairLoader(),
|
||||
};
|
||||
return loaders[dataType];
|
||||
}
|
||||
|
||||
static getChunker(dataType: DataType) {
|
||||
const chunkers: { [t in DataType]: BaseChunker } = {
|
||||
pdf_file: new PdfFileChunker(),
|
||||
web_page: new WebPageChunker(),
|
||||
qna_pair: new QnaPairChunker(),
|
||||
};
|
||||
return chunkers[dataType];
|
||||
}
|
||||
|
||||
public async add(dataType: DataType, url: RemoteInput) {
|
||||
const loader = EmbedChain.getLoader(dataType);
|
||||
const chunker = EmbedChain.getChunker(dataType);
|
||||
this.userAsks.push([dataType, url]);
|
||||
const { documents, countNewChunks } = await this.loadAndEmbed(
|
||||
loader,
|
||||
chunker,
|
||||
url
|
||||
);
|
||||
|
||||
if (this.collectMetrics) {
|
||||
const wordCount = documents.reduce(
|
||||
(sum, document) => sum + document.split(' ').length,
|
||||
0
|
||||
);
|
||||
|
||||
this.sendTelemetryEvent('add', {
|
||||
data_type: dataType,
|
||||
word_count: wordCount,
|
||||
chunks_count: countNewChunks,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async addLocal(dataType: DataType, content: LocalInput) {
|
||||
const loader = EmbedChain.getLoader(dataType);
|
||||
const chunker = EmbedChain.getChunker(dataType);
|
||||
this.userAsks.push([dataType, content]);
|
||||
const { documents, countNewChunks } = await this.loadAndEmbed(
|
||||
loader,
|
||||
chunker,
|
||||
content
|
||||
);
|
||||
|
||||
if (this.collectMetrics) {
|
||||
const wordCount = documents.reduce(
|
||||
(sum, document) => sum + document.split(' ').length,
|
||||
0
|
||||
);
|
||||
|
||||
this.sendTelemetryEvent('add_local', {
|
||||
data_type: dataType,
|
||||
word_count: wordCount,
|
||||
chunks_count: countNewChunks,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected async loadAndEmbed(
|
||||
loader: any,
|
||||
chunker: BaseChunker,
|
||||
src: Input
|
||||
): Promise<{
|
||||
documents: string[];
|
||||
metadatas: Metadata[];
|
||||
ids: string[];
|
||||
countNewChunks: number;
|
||||
}> {
|
||||
const embeddingsData = await chunker.createChunks(loader, src);
|
||||
let { documents, ids, metadatas } = embeddingsData;
|
||||
|
||||
const existingDocs = await this.collection.get({ ids });
|
||||
const existingIds = new Set(existingDocs.ids);
|
||||
|
||||
if (existingIds.size > 0) {
|
||||
const dataDict: DataDict = {};
|
||||
for (let i = 0; i < ids.length; i += 1) {
|
||||
const id = ids[i];
|
||||
if (!existingIds.has(id)) {
|
||||
dataDict[id] = { doc: documents[i], meta: metadatas[i] };
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(dataDict).length === 0) {
|
||||
console.log(`All data from ${src} already exists in the database.`);
|
||||
return { documents: [], metadatas: [], ids: [], countNewChunks: 0 };
|
||||
}
|
||||
ids = Object.keys(dataDict);
|
||||
const dataValues = Object.values(dataDict);
|
||||
documents = dataValues.map(({ doc }) => doc);
|
||||
metadatas = dataValues.map(({ meta }) => meta);
|
||||
}
|
||||
|
||||
const countBeforeAddition = await this.count();
|
||||
await this.collection.add({ documents, metadatas, ids });
|
||||
const countNewChunks = (await this.count()) - countBeforeAddition;
|
||||
console.log(
|
||||
`Successfully saved ${src}. New chunks count: ${countNewChunks}`
|
||||
);
|
||||
return { documents, metadatas, ids, countNewChunks };
|
||||
}
|
||||
|
||||
static async formatResult(
|
||||
results: QueryResponse
|
||||
): Promise<FormattedResult[]> {
|
||||
return results.documents[0].map((document: any, index: number) => {
|
||||
const metadata = results.metadatas[0][index] || {};
|
||||
// TODO: Add proper error handling
|
||||
const distance = results.distances ? results.distances[0][index] : null;
|
||||
return [new Document({ pageContent: document, metadata }), distance];
|
||||
});
|
||||
}
|
||||
|
||||
static async getOpenAiAnswer(prompt: string) {
|
||||
const messages: OpenAI.Chat.CreateChatCompletionRequestMessage[] = [
|
||||
{ role: 'user', content: prompt },
|
||||
];
|
||||
const response = await openai.chat.completions.create({
|
||||
model: 'gpt-3.5-turbo',
|
||||
messages,
|
||||
temperature: 0,
|
||||
max_tokens: 1000,
|
||||
top_p: 1,
|
||||
});
|
||||
return (
|
||||
response.choices[0].message?.content ?? 'Response could not be processed.'
|
||||
);
|
||||
}
|
||||
|
||||
protected async retrieveFromDatabase(inputQuery: string) {
|
||||
const result = await this.collection.query({
|
||||
nResults: 1,
|
||||
queryTexts: [inputQuery],
|
||||
});
|
||||
const resultFormatted = await EmbedChain.formatResult(result);
|
||||
const content = resultFormatted[0][0].pageContent;
|
||||
return content;
|
||||
}
|
||||
|
||||
static generatePrompt(inputQuery: string, context: any) {
|
||||
const prompt = `Use the following pieces of context to answer the query at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.\n${context}\nQuery: ${inputQuery}\nHelpful Answer:`;
|
||||
return prompt;
|
||||
}
|
||||
|
||||
static async getAnswerFromLlm(prompt: string) {
|
||||
const answer = await EmbedChain.getOpenAiAnswer(prompt);
|
||||
return answer;
|
||||
}
|
||||
|
||||
public async query(inputQuery: string) {
|
||||
const context = await this.retrieveFromDatabase(inputQuery);
|
||||
const prompt = EmbedChain.generatePrompt(inputQuery, context);
|
||||
const answer = await EmbedChain.getAnswerFromLlm(prompt);
|
||||
this.sendTelemetryEvent('query');
|
||||
return answer;
|
||||
}
|
||||
|
||||
public async dryRun(input_query: string) {
|
||||
const context = await this.retrieveFromDatabase(input_query);
|
||||
const prompt = EmbedChain.generatePrompt(input_query, context);
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of embeddings.
|
||||
* @returns {Promise<number>}: The number of embeddings.
|
||||
*/
|
||||
public count(): Promise<number> {
|
||||
return this.collection.count();
|
||||
}
|
||||
|
||||
protected async sendTelemetryEvent(method: Method, extraMetadata?: object) {
|
||||
if (!this.collectMetrics) {
|
||||
return;
|
||||
}
|
||||
const url = 'https://api.embedchain.ai/api/v1/telemetry/';
|
||||
|
||||
// Read package version from filesystem (because it's not in the ts root dir)
|
||||
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
||||
|
||||
const metadata = {
|
||||
s_id: this.sId,
|
||||
version: packageJson.version,
|
||||
method,
|
||||
language: 'js',
|
||||
...extraMetadata,
|
||||
};
|
||||
|
||||
const maxRetries = 3;
|
||||
|
||||
// Retry the fetch
|
||||
for (let i = 0; i < maxRetries; i += 1) {
|
||||
try {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ metadata }),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
// Break out of the loop if the request was successful
|
||||
break;
|
||||
} else {
|
||||
// Log the unsuccessful response (optional)
|
||||
console.error(
|
||||
`Telemetry: Attempt ${i + 1} failed with status:`,
|
||||
response.status
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
// Log the error (optional)
|
||||
console.error(`Telemetry: Attempt ${i + 1} failed with error:`, error);
|
||||
}
|
||||
|
||||
// If this was the last attempt, throw an error or handle the failure
|
||||
if (i === maxRetries - 1) {
|
||||
console.error('Telemetry: Max retries reached');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EmbedChainApp extends EmbedChain {
|
||||
// The EmbedChain app.
|
||||
// Has two functions: add and query.
|
||||
// adds(dataType, url): adds the data from the given URL to the vector db.
|
||||
// query(query): finds answer to the given query using vector database and LLM.
|
||||
}
|
||||
|
||||
export { EmbedChainApp };
|
||||
@@ -1,7 +0,0 @@
|
||||
import { EmbedChainApp } from './embedchain';
|
||||
|
||||
export const App = async () => {
|
||||
const app = new EmbedChainApp();
|
||||
await app.initApp;
|
||||
return app;
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { Input, LoaderResult } from '../models';
|
||||
|
||||
export abstract class BaseLoader {
|
||||
abstract loadData(src: Input): Promise<LoaderResult>;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { LoaderResult, QnaPair } from '../models';
|
||||
import { BaseLoader } from './BaseLoader';
|
||||
|
||||
class LocalQnaPairLoader extends BaseLoader {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async loadData(content: QnaPair): Promise<LoaderResult> {
|
||||
const [question, answer] = content;
|
||||
const contentText = `Q: ${question}\nA: ${answer}`;
|
||||
const metaData = {
|
||||
url: 'local',
|
||||
};
|
||||
return [
|
||||
{
|
||||
content: contentText,
|
||||
metaData,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
export { LocalQnaPairLoader };
|
||||
@@ -1,58 +0,0 @@
|
||||
import type { TextContent } from 'pdfjs-dist/types/src/display/api';
|
||||
|
||||
import type { LoaderResult, Metadata } from '../models';
|
||||
import { cleanString } from '../utils';
|
||||
import { BaseLoader } from './BaseLoader';
|
||||
|
||||
const pdfjsLib = require('pdfjs-dist');
|
||||
|
||||
interface Page {
|
||||
page_content: string;
|
||||
}
|
||||
|
||||
class PdfFileLoader extends BaseLoader {
|
||||
static async getPagesFromPdf(url: string): Promise<Page[]> {
|
||||
const loadingTask = pdfjsLib.getDocument(url);
|
||||
const pdf = await loadingTask.promise;
|
||||
const { numPages } = pdf;
|
||||
|
||||
const promises = Array.from({ length: numPages }, async (_, i) => {
|
||||
const page = await pdf.getPage(i + 1);
|
||||
const pageText: TextContent = await page.getTextContent();
|
||||
const pageContent: string = pageText.items
|
||||
.map((item) => ('str' in item ? item.str : ''))
|
||||
.join(' ');
|
||||
|
||||
return {
|
||||
page_content: pageContent,
|
||||
};
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async loadData(url: string): Promise<LoaderResult> {
|
||||
const pages: Page[] = await PdfFileLoader.getPagesFromPdf(url);
|
||||
const output: LoaderResult = [];
|
||||
|
||||
if (!pages.length) {
|
||||
throw new Error('No data found');
|
||||
}
|
||||
|
||||
pages.forEach((page) => {
|
||||
let content: string = page.page_content;
|
||||
content = cleanString(content);
|
||||
const metaData: Metadata = {
|
||||
url,
|
||||
};
|
||||
output.push({
|
||||
content,
|
||||
metaData,
|
||||
});
|
||||
});
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
export { PdfFileLoader };
|
||||
@@ -1,51 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { JSDOM } from 'jsdom';
|
||||
|
||||
import { cleanString } from '../utils';
|
||||
import { BaseLoader } from './BaseLoader';
|
||||
|
||||
class WebPageLoader extends BaseLoader {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
async loadData(url: string) {
|
||||
const response = await axios.get(url);
|
||||
const html = response.data;
|
||||
const dom = new JSDOM(html);
|
||||
const { document } = dom.window;
|
||||
const unwantedTags = [
|
||||
'nav',
|
||||
'aside',
|
||||
'form',
|
||||
'header',
|
||||
'noscript',
|
||||
'svg',
|
||||
'canvas',
|
||||
'footer',
|
||||
'script',
|
||||
'style',
|
||||
];
|
||||
unwantedTags.forEach((tagName) => {
|
||||
const elements = document.getElementsByTagName(tagName);
|
||||
Array.from(elements).forEach((element) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
(element as HTMLElement).textContent = ' ';
|
||||
});
|
||||
});
|
||||
|
||||
const output = [];
|
||||
let content = document.body.textContent;
|
||||
if (!content) {
|
||||
throw new Error('Web page content is empty.');
|
||||
}
|
||||
content = cleanString(content);
|
||||
const metaData = {
|
||||
url,
|
||||
};
|
||||
output.push({
|
||||
content,
|
||||
metaData,
|
||||
});
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
export { WebPageLoader };
|
||||
@@ -1,6 +0,0 @@
|
||||
import { BaseLoader } from './BaseLoader';
|
||||
import { LocalQnaPairLoader } from './LocalQnaPair';
|
||||
import { PdfFileLoader } from './PdfFile';
|
||||
import { WebPageLoader } from './WebPage';
|
||||
|
||||
export { BaseLoader, LocalQnaPairLoader, PdfFileLoader, WebPageLoader };
|
||||
@@ -1,7 +0,0 @@
|
||||
import type { Metadata } from './Metadata';
|
||||
|
||||
export type ChunkResult = {
|
||||
documents: string[];
|
||||
ids: string[];
|
||||
metadatas: Metadata[];
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
import type { ChunkResult } from './ChunkResult';
|
||||
|
||||
type Data = {
|
||||
doc: ChunkResult['documents'][0];
|
||||
meta: ChunkResult['metadatas'][0];
|
||||
};
|
||||
|
||||
export type DataDict = {
|
||||
[id: string]: Data;
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export type DataType = 'pdf_file' | 'web_page' | 'qna_pair';
|
||||
@@ -1,3 +0,0 @@
|
||||
import type { Document } from 'langchain/document';
|
||||
|
||||
export type FormattedResult = [Document, number | null];
|
||||
@@ -1,7 +0,0 @@
|
||||
import type { QnaPair } from './QnAPair';
|
||||
|
||||
export type RemoteInput = string;
|
||||
|
||||
export type LocalInput = QnaPair;
|
||||
|
||||
export type Input = RemoteInput | LocalInput;
|
||||
@@ -1,3 +0,0 @@
|
||||
import type { Metadata } from './Metadata';
|
||||
|
||||
export type LoaderResult = { content: any; metaData: Metadata }[];
|
||||
@@ -1,3 +0,0 @@
|
||||
export type Metadata = {
|
||||
url: string;
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
export type Method = 'init' | 'query' | 'add' | 'add_local';
|
||||
@@ -1,4 +0,0 @@
|
||||
type Question = string;
|
||||
type Answer = string;
|
||||
|
||||
export type QnaPair = [Question, Answer];
|
||||
@@ -1,21 +0,0 @@
|
||||
import { DataDict } from './DataDict';
|
||||
import { DataType } from './DataType';
|
||||
import { FormattedResult } from './FormattedResult';
|
||||
import { Input, LocalInput, RemoteInput } from './Input';
|
||||
import { LoaderResult } from './LoaderResult';
|
||||
import { Metadata } from './Metadata';
|
||||
import { Method } from './Method';
|
||||
import { QnaPair } from './QnAPair';
|
||||
|
||||
export {
|
||||
DataDict,
|
||||
DataType,
|
||||
FormattedResult,
|
||||
Input,
|
||||
LoaderResult,
|
||||
LocalInput,
|
||||
Metadata,
|
||||
Method,
|
||||
QnaPair,
|
||||
RemoteInput,
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* This function takes in a string and performs a series of text cleaning operations.
|
||||
* @param {str} text: The text to be cleaned. This is expected to be a string.
|
||||
* @returns {str}: The cleaned text after all the cleaning operations have been performed.
|
||||
*/
|
||||
export function cleanString(text: string): string {
|
||||
// Replacement of newline characters:
|
||||
let cleanedText = text.replace(/\n/g, ' ');
|
||||
|
||||
// Stripping and reducing multiple spaces to single:
|
||||
cleanedText = cleanedText.trim().replace(/\s+/g, ' ');
|
||||
|
||||
// Removing backslashes:
|
||||
cleanedText = cleanedText.replace(/\\/g, '');
|
||||
|
||||
// Replacing hash characters:
|
||||
cleanedText = cleanedText.replace(/#/g, ' ');
|
||||
|
||||
// Eliminating consecutive non-alphanumeric characters:
|
||||
// This regex identifies consecutive non-alphanumeric characters (i.e., not a word character [a-zA-Z0-9_] and not a whitespace) in the string
|
||||
// and replaces each group of such characters with a single occurrence of that character.
|
||||
// For example, "!!! hello !!!" would become "! hello !".
|
||||
cleanedText = cleanedText.replace(/([^\w\s])\1*/g, '$1');
|
||||
|
||||
return cleanedText;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
class BaseVectorDB {
|
||||
initDb: Promise<void>;
|
||||
|
||||
constructor() {
|
||||
this.initDb = this.getClientAndCollection();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
protected async getClientAndCollection(): Promise<void> {
|
||||
throw new Error('getClientAndCollection() method is not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
export { BaseVectorDB };
|
||||
@@ -1,38 +0,0 @@
|
||||
import type { Collection } from 'chromadb';
|
||||
import { ChromaClient, OpenAIEmbeddingFunction } from 'chromadb';
|
||||
|
||||
import { BaseVectorDB } from './BaseVectorDb';
|
||||
|
||||
const embedder = new OpenAIEmbeddingFunction({
|
||||
openai_api_key: process.env.OPENAI_API_KEY ?? '',
|
||||
});
|
||||
|
||||
class ChromaDB extends BaseVectorDB {
|
||||
client: ChromaClient | undefined;
|
||||
|
||||
collection: Collection | null = null;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected async getClientAndCollection(): Promise<void> {
|
||||
this.client = new ChromaClient({ path: 'http://localhost:8000' });
|
||||
try {
|
||||
this.collection = await this.client.getCollection({
|
||||
name: 'embedchain_store',
|
||||
embeddingFunction: embedder,
|
||||
});
|
||||
} catch (err) {
|
||||
if (!this.collection) {
|
||||
this.collection = await this.client.createCollection({
|
||||
name: 'embedchain_store',
|
||||
embeddingFunction: embedder,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { ChromaDB };
|
||||
@@ -1,3 +0,0 @@
|
||||
import { ChromaDB } from './ChromaDb';
|
||||
|
||||
export { ChromaDB };
|
||||
@@ -1,9 +0,0 @@
|
||||
const { EmbedChainApp } = require("./embedchain/embedchain");
|
||||
|
||||
async function App() {
|
||||
const app = new EmbedChainApp();
|
||||
await app.init_app;
|
||||
return app;
|
||||
}
|
||||
|
||||
module.exports = { App };
|
||||
@@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testPathIgnorePatterns: ['.d.ts'],
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
'*.{js,ts}': ['eslint --fix', 'eslint'],
|
||||
'**/*.ts?(x)': () => 'npm run check-types',
|
||||
'*.json': ['prettier --write'],
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
{
|
||||
"name": "embedchain",
|
||||
"version": "0.0.8",
|
||||
"description": "embedchain is a framework to easily create LLM powered bots over any dataset",
|
||||
"main": "dist/index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"types"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.build.json --listFiles",
|
||||
"prepare": "husky install",
|
||||
"test": "jest",
|
||||
"check-types": "tsc --noEmit --pretty"
|
||||
},
|
||||
"author": "Taranjeet Singh",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"axios": "^1.4.0",
|
||||
"chromadb": "^1.5.6",
|
||||
"jsdom": "^22.1.0",
|
||||
"langchain": "^0.0.136",
|
||||
"openai": "^4.3.1",
|
||||
"pdfjs-dist": "^3.8.162",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.1.2",
|
||||
"@commitlint/config-conventional": "^17.1.0",
|
||||
"@commitlint/cz-commitlint": "^17.1.2",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/jsdom": "^21.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.41.0",
|
||||
"@typescript-eslint/parser": "^5.41.0",
|
||||
"eslint": "^8.34.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"eslint-plugin-simple-import-sort": "^8.0.0",
|
||||
"eslint-plugin-testing-library": "^5.9.1",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"husky": "^8.0.1",
|
||||
"jest": "^29.5.0",
|
||||
"lint-staged": "^13.0.3",
|
||||
"prettier": "^2.7.1",
|
||||
"ts-jest": "^29.1.0",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"exclude": ["embedchain/__tests__"]
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "CommonJS",
|
||||
"strict": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "embedchain",
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"declarationDir": "types",
|
||||
"esModuleInterop": true
|
||||
},
|
||||
"include": ["embedchain/**/*.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -67,6 +67,10 @@ We use `pytest` to test our code. You can run the tests by running the following
|
||||
poetry run pytest
|
||||
```
|
||||
|
||||
|
||||
Several packages have been removed from Poetry to make the package lighter. Therefore, it is recommended to run `make install_all` to install the remaining packages and ensure all tests pass.
|
||||
|
||||
|
||||
Make sure that all tests pass before submitting a pull request.
|
||||
|
||||
## 🚀 Release Process
|
||||