Build semantic search

Embed your notes through the exchange and search them by meaning.

In about 10 minutes, you embed six short notes, store the vectors in memory, and find the three notes that are closest in meaning to a question.

Before you start

1. Install the OpenAI SDK

The exchange has the shape of the OpenAI API, so the official client works without changes.

pip install openai

2. Write the search program

Save this as search.py. The program embeds the notes in one request. It then embeds the query and ranks the notes by cosine similarity.

import math
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://router.inference.ai.exchange/v1",
    api_key=os.environ["LIQUID_API_KEY"],
)
MODEL = "text-embedding-3-small"

notes = [
    "Reset your password in Settings under Security.",
    "Invoices are sent by email on the first day of each month.",
    "The office closes at 6 pm on Fridays.",
    "To cancel a subscription, open Billing and choose Cancel plan.",
    "Our API returns a 429 error when you send requests too fast.",
    "New hires get a laptop on their first day.",
]

def embed(texts):
    result = client.embeddings.create(model=MODEL, input=texts)
    return [item.embedding for item in result.data]

def cosine(a, b):
    dot = sum(x * y for x, y in zip(a, b))
    return dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))

vectors = embed(notes)
query = "how do I change my password"
query_vector = embed([query])[0]

ranked = sorted(zip(notes, vectors), key=lambda p: cosine(query_vector, p[1]), reverse=True)
for note, vector in ranked[:3]:
    print(f"{cosine(query_vector, vector):.2f}  {note}")

3. Run it

python search.py

You see three lines, from the closest note to the third closest. The scores differ a little from run to run, because the exchange can buy from a different provider each time.

0.62  Reset your password in Settings under Security.
0.21  To cancel a subscription, open Billing and choose Cancel plan.
0.17  Our API returns a 429 error when you send requests too fast.

4. Try your own query

Change query to "when do I get a bill" and run the program again. The invoice note now comes first, although the query has no word in common with it. This is the difference between search by meaning and search by keyword.

Check it works

If something goes wrong

Next steps