Embedbase est une API open source pour créer, stocker et récupérer des intégrations.
Aujourd'hui, nous allons créer un moteur de recherche pour les essais de Paul Graham que nous utiliserons avec les raccourcis Apple Siri, par exemple en posant des questions à Siri sur ces essais.
Les « embeddings » sont un concept d'apprentissage automatique qui vous permet de comparer des données.
Nous n'aborderons pas le sujet technique des plongements aujourd'hui.
Une façon de penser aux "incorporations" est comme mettre des choses similaires ensemble dans un sac. Donc, si vous avez un sac de jouets et que vous voulez trouver un certain jouet, vous regardez dans le sac et voyez quels autres jouets se trouvent à proximité pour déterminer lequel vous voulez. Un ordinateur peut faire la même chose avec des mots, en rassemblant des mots similaires dans un sac, puis en trouvant le mot qu'il veut en fonction des autres mots à proximité.
Lorsque vous souhaitez utiliser des représentations incorporées dans votre logiciel de production, vous devez pouvoir les stocker et y accéder facilement.
Il existe de nombreuses bases de données vectorielles et modèles NLP pour stocker et calculer les plongements. Il existe également quelques astuces supplémentaires pour gérer les intégrations.
Par exemple, il peut devenir coûteux et inefficace de recalculer quand ce n'est pas nécessaire, par exemple, si la note contient "chien" puis "chien", vous ne voulez pas nécessairement recalculer car les informations modifiées peuvent ne pas être utiles.
De plus, ces bases de données vectorielles nécessitent une courbe d'apprentissage abrupte et la nécessité de comprendre l'apprentissage automatique.
Embedbase vous permet de synchroniser et de rechercher sémantiquement des données sans rien connaître du machine learning, des bases de données vectorielles et de l'optimisation des calculs en quelques lignes de code.
Dans l'ordre, nous allons :
git clone https://github.com/another-ai/embedbase cd embedbase
Rendez-vous sur le site Web de Pinecone , connectez-vous et créez un index :
Nous l'appellerons « paul » et utiliserons la dimension « 1536 » ( important pour bien saisir ce nombre , sous le capot, il s'agit de la « taille » de la structure de données OpenAI « embeddings »), les autres paramètres sont moins importants.
Vous devez obtenir votre clé API Pinecone qui permettra à Embedbase de communiquer avec Pinecone :
Vous devez maintenant obtenir votre configuration OpenAI sur https://platform.openai.com/account/api-keys (créez un compte si nécessaire).
Appuyez sur "Créer une nouvelle clé":
Obtenez également l'identifiant de votre organisation ici :
Maintenant, écrivez et remplissez les valeurs dans le fichier « config.yaml » ( dans le répertoire embedbase ) :
# embedbase/config.yaml # https://app.pinecone.io/ pinecone_index: "my index name" # replace this with your environment pinecone_environment: "us-east1-gcp" pinecone_api_key: "" # https://platform.openai.com/account/api-keys openai_api_key: "sk-xxxxxxx" # https://platform.openai.com/account/org-settings openai_organization: "org-xxxxx"
🎉 Vous pouvez exécuter Embedbase maintenant !
Démarrez Docker, si vous ne l'avez pas, veuillez l'installer en suivant les instructions sur le site officiel .
Exécutez maintenant Embedbase :
docker-compose up
Ceci est facultatif, n'hésitez pas à passer à la partie suivante !
Si vous êtes motivé, vous pouvez déployer Embedbase sur Google Cloud Run. Assurez-vous d'avoir un projet Google Cloud et d'avoir installé la ligne de commande "gcloud" via la documentation officielle .
# login to gcloud gcloud auth login # Get your Google Cloud project ID PROJECT_ID=$(gcloud config get-value project) # Enable container registry gcloud services enable containerregistry.googleapis.com # Enable Cloud Run gcloud services enable run.googleapis.com # Enable Secret Manager gcloud services enable secretmanager.googleapis.com # create a secret for the config gcloud secrets create EMBEDBASE_PAUL_GRAHAM --replication-policy=automatic # add a secret version based on your yaml config gcloud secrets versions add EMBEDBASE_PAUL_GRAHAM --data-file=config.yaml # Set your Docker image URL IMAGE_URL="gcr.io/${PROJECT_ID}/embedbase-paul-graham:0.0.1" # Build the Docker image for cloud deployment docker buildx build . --platform linux/amd64 -t ${IMAGE_URL} -f ./search/Dockerfile # Push the docker image to Google Cloud Docker registries # Make sure to be authenticated https://cloud.google.com/container-registry/docs/advanced-authentication docker push ${IMAGE_URL} # Deploy Embedbase to Google Cloud Run gcloud run deploy embedbase-paul-graham \ --image ${IMAGE_URL} \ --region us-central1 \ --allow-unauthenticated \ --set-secrets /secrets/config.yaml=EMBEDBASE_PAUL_GRAHAM:1
Les robots d'exploration Web permettent de télécharger toutes les pages d'un site Web, c'est l'algorithme sous-jacent utilisé par Google.
Clonez le dépôt et installez les dépendances :
git clone https://github.com/another-ai/embedbase-paul-graham cd embedbase-paul-graham npm i
Regardons le code, si vous êtes submergé par tous les fichiers nécessaires à un projet Typescript, ne vous inquiétez pas et ignorez-les.
// src/main.ts // Here we want to start from the page that list all Paul's essays const startUrls = ['http://www.paulgraham.com/articles.html']; const crawler = new PlaywrightCrawler({ requestHandler: router, }); await crawler.run(startUrls);
Vous pouvez voir que le crawler est initialisé avec des « routes », quelles sont ces routes mystérieuses ?
// src/routes.ts router.addDefaultHandler(async ({ enqueueLinks, log }) => { log.info(`enqueueing new URLs`); await enqueueLinks({ // Here we tell the crawler to only accept pages that are under // "http://www.paulgraham.com/" domain name, // for example if we find a link on Paul's website to an url // like "https://ycombinator.com/startups" if it will ignored globs: ['http://www.paulgraham.com/**'], label: 'detail', }); }); router.addHandler('detail', async ({ request, page, log }) => { // Here we will do some logic on all pages under // "http://www.paulgraham.com/" domain name // for example, collecting the page title const title = await page.title(); // getting the essays' content const blogPost = await page.locator('body > table > tbody > tr > td:nth-child(3)').textContent(); if (!blogPost) { log.info(`no blog post found for ${title}, skipping`); return; } log.info(`${title}`, { url: request.loadedUrl }); // Remember that usually AI models and databases have some limits in input size // and thus we will split essays in chunks of paragraphs // split blog post in chunks on the \n\n const chunks = blogPost.split(/\n\n/); if (!chunks) { log.info(`no blog post found for ${title}, skipping`); return; } // If you are not familiar with Promises, don't worry for now // it's just a mean to do things faster await Promise.all(chunks.flatMap((chunk) => { const d = { url: request.loadedUrl, title: title, blogPost: chunk, }; // Here we just want to send the page interesting // content into Embedbase (don't mind Dataset, it's optional local storage) return Promise.all([Dataset.pushData(d), add(title, chunk)]); })); });
Qu'est-ce que ajouter() ?
const add = (title: string, blogPost: string) => { // note "paul" in the URL, it can be anything you want // that will help you segment your data in // isolated parts const url = `${baseUrl}/v1/paul`; const data = { documents: [{ data: blogPost, }], }; // send the data to Embedbase using "node-fetch" library fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }).then((response) => { return response.json(); }).then((data) => { console.log('Success:', data); }).catch((error) => { console.error('Error:', error); }); };
Vous pouvez maintenant exécuter le crawler, cela devrait prendre moins d'une minute pour télécharger et ingérer tout dans Embedbase.
Les crédits OpenAI seront utilisés, pour moins de <$1
npm start
Si vous avez déployé Embedbase sur le cloud, veuillez utiliser
# you can get your cloud run URL like this: CLOUD_RUN_URL=$(gcloud run services list --platform managed --region us-central1 --format="value(status.url)" --filter="metadata.name=embedbase-paul-graham") npm run playground ${CLOUD_RUN_URL}
Vous devriez voir une certaine activité dans votre terminal (à la fois le conteneur Embedbase Docker et le processus de nœud) sans erreur ( n'hésitez pas à demander de l'aide sinon ).
Dans l'exemple de référentiel, vous pouvez remarquer « src/playground.ts » qui est un script simple qui vous permet d'interagir avec Embedbase dans votre terminal, le code est simple :
// src/playground.ts const search = async (query: string) => { const url = `${baseUrl}/v1/paul/search`; const data = { query, }; return fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), }).then((response) => { return response.json(); }).then((data) => { console.log('Success:', data); }).catch((error) => { console.error('Error:', error); }); }; const p = prompt(); // this is an interactive terminal that let you search in paul graham // blog posts using semantic search // It is an infinite loop that will ask you for a query // and show you the results const start = async () => { console.log('Welcome to the Embedbase playground!'); console.log('This playground is a simple example of how to use Embedbase'); console.log('Currently using Embedbase server at', baseUrl); console.log('This is an interactive terminal that let you search in paul graham blog posts using semantic search'); console.log('Try to run some queries such as "how to get rich"'); console.log('or "how to pitch investor"'); while (true) { const query = p('Enter a semantic query:'); if (!query) { console.log('Bye!'); return; } await search(query); } }; start();
Vous pouvez l'exécuter comme ceci si vous exécutez Embedbase localement :
npm run playground
Ou, comme ceci, si vous avez déployé Embedbase sur le cloud :
npm run playground ${CLOUD_RUN_URL}
Résultats:
Moment de plaisir ! Construisons un raccourci Apple Siri pour pouvoir poser des questions à Siri sur les essais de Paul Graham 😜
Commençons d'abord par les raccourcis Apple :
Créez un nouveau raccourci :
Nous nommerons ce raccourci "Rechercher Paul" (sachez que ce sera la façon dont vous demanderez à Siri de démarrer le raccourci, alors choisissez quelque chose de facile)
En clair, ce raccourci demande à l'utilisateur une requête et appelle Embedbase avec, et dit à Siri de prononcer à haute voix les essais qu'il a trouvés.
"Get for in" extraira la propriété "similitudes" de la réponse Embedbase
"Répéter avec chaque élément dans" va, pour chaque similarité :
"Combiner" "joindra" les résultats avec une nouvelle ligne
(Facultatif, montrera comment ci-dessous) C'est une astuce amusante que vous pouvez ajouter au raccourci pour le piquant, en utilisant OpenAI GPT3 pour transformer un peu le texte du résultat pour qu'il sonne mieux lorsque Siri le prononce
Nous assemblons le résultat dans un "Texte" pour être convivial
Demandez à Siri de le dire
Vous pouvez transformer les résultats en texte plus agréable à l'aide de ce raccourci GPT3 fonctionnel
(remplissez la valeur "Autorisation" avec "Porteur [VOTRE CLÉ OPENAI]")
Avec Embedbase, vous pouvez créer un produit sémantique en un rien de temps sans avoir le mal de tête de créer, stocker et récupérer des incorporations tout en maintenant un faible coût.