Embedbase es una API de código abierto para crear, almacenar y recuperar incrustaciones.
Hoy crearemos un motor de búsqueda para los ensayos de Paul Graham que usaremos con los accesos directos de Siri de Apple, por ejemplo, haciéndole preguntas a Siri sobre estos ensayos.
Las "incrustaciones" son un concepto en el aprendizaje automático que le permite comparar datos.
No profundizaremos en el tema técnico de las incrustaciones hoy.
Una forma de pensar en las "incrustaciones" es como juntar cosas similares en una bolsa. Entonces, si tiene una bolsa de juguetes y quiere encontrar un juguete determinado, mira en la bolsa y ve qué otros juguetes hay cerca para descubrir cuál quiere. Una computadora puede hacer lo mismo con las palabras, juntando palabras similares en una bolsa y luego encontrando la palabra que busca basándose en las otras palabras cercanas.
Cuando desee utilizar incrustaciones en su software de producción, debe poder almacenarlas y acceder a ellas fácilmente.
Hay muchas bases de datos vectoriales y modelos NLP para almacenar y calcular incrustaciones. También hay algunos trucos adicionales para lidiar con las incrustaciones.
Por ejemplo, puede volverse costoso e ineficiente volver a calcular cuando no es necesario, por ejemplo, si la nota contiene "perro" y luego "perro", no necesariamente desea volver a calcular porque la información modificada podría no ser útil.
Además, estas bases de datos vectoriales requieren una curva de aprendizaje pronunciada y la necesidad de comprender el aprendizaje automático.
Embedbase le permite sincronizar y buscar datos semánticamente sin saber nada sobre aprendizaje automático, bases de datos vectoriales y optimización de cálculos en unas pocas líneas de código.
En orden, haremos lo siguiente:
git clone https://github.com/another-ai/embedbase cd embedbase
Dirígete al sitio web de Pinecone , inicia sesión y crea un índice:
Lo llamaremos "paul" y usaremos la dimensión "1536" ( importante para obtener este número correcto , debajo del capó, es el "tamaño" de las "incrustaciones" de la estructura de datos de OpenAI), las otras configuraciones son menos importantes.
Debe obtener su clave API de Pinecone que le permitirá a Embedbase comunicarse con Pinecone:
Ahora necesita obtener su configuración de OpenAI en https://platform.openai.com/account/api-keys (cree una cuenta si es necesario).
Presiona “Crear una nueva clave”:
Además, obtenga el ID de su organización aquí:
Ahora escriba y complete los valores en el archivo "config.yaml" ( en el directorio 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"
🎉 ¡Ya puedes ejecutar Embedbase !
Inicie Docker, si no lo tiene, instálelo siguiendo las instrucciones en el sitio web oficial .
Ahora ejecute Embedbase:
docker-compose up
Esto es opcional, ¡siéntete libre de pasar a la siguiente parte!
Si está motivado, puede implementar Embedbase en Google Cloud Run. Asegúrate de tener un proyecto de Google Cloud y haber instalado la línea de comando “gcloud” a través de la documentación oficial .
# 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
Los rastreadores web le permiten descargar todas las páginas de un sitio web, es el algoritmo subyacente utilizado por Google.
Clona el repositorio e instala las dependencias:
git clone https://github.com/another-ai/embedbase-paul-graham cd embedbase-paul-graham npm i
Veamos el código, si está abrumado con todos los archivos necesarios para un proyecto de TypeScript, no se preocupe e ignórelos.
// 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);
Puede ver que el rastreador se inicializa con "rutas", ¿cuáles son estas rutas misteriosas?
// 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é es agregar() ?
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); }); };
Ahora puede ejecutar el rastreador, debería tomar menos de un minuto descargar e ingerir todo en Embedbase.
Se utilizarán créditos OpenAI, por menos de <$1
npm start
Si implementó Embedbase en la nube, utilice
# 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}
Debería ver alguna actividad en su terminal (tanto el contenedor Embedbase Docker como el proceso del nodo) sin errores ( de lo contrario, siéntase libre de buscar ayuda ).
En el repositorio de ejemplo, puede notar " src/playground.ts ", que es un script simple que le permite interactuar con Embedbase en su terminal, el código es sencillo:
// 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();
Puede ejecutarlo así si está ejecutando Embedbase localmente:
npm run playground
O, así, si implementó Embedbase en la nube:
npm run playground ${CLOUD_RUN_URL}
Resultados:
tiempo de diversión! Construyamos un atajo de Apple Siri para poder hacerle preguntas a Siri sobre los ensayos de Paul Graham 😜
Primero, comencemos los atajos de Apple:
Crear un nuevo acceso directo:
Llamaremos a este atajo "Buscar Paul" (tenga en cuenta que así le pedirá a Siri que inicie el atajo, así que elija algo fácil)
En lenguaje sencillo, este atajo le hace una consulta al usuario y llama a Embedbase con él, y le dice a Siri que pronuncie en voz alta los ensayos que encontró.
"Get for in" extraerá la propiedad "similitudes" de la respuesta de Embedbase
“Repetir con cada elemento en” será, para cada similitud:
"Combinar" "unirá" los resultados con una nueva línea
(Opcional, se mostrará cómo a continuación) Este es un truco divertido que puede agregar al atajo para picante, usando OpenAI GPT3 para transformar un poco del texto de resultado para que suene mejor cuando Siri lo pronuncie.
Reunimos el resultado en un "Texto" para que sea compatible con la voz
Pídele a Siri que lo hable
Puede transformar los resultados en un texto más agradable usando este atajo funcional de GPT3
(llene el valor de “Autorización” con “Portador [SU CLAVE OPENAI]”)
Con Embedbase, puede crear un producto con tecnología semántica en muy poco tiempo sin tener el dolor de cabeza de crear, almacenar y recuperar incrustaciones mientras mantiene el costo bajo.