ChromaDB per BrowserURL abfragen (+ AnythingLLM)

Ich habe neulich per AnythingLLM eine Docker Chroma Instanz verwendet.

Dazu wollte ich dann Daten abfragen. Das war erst mal nicht ganz so einfach, bis ich die YAML dazu gefunden habe (das YAML ist am Ende dieser Seite bzw unter http://localhost:8000/docs).

Das Ganze sieht in swagger.io formatiert so aus

ChromaDB API Yaml in Swagger visualisiert

So kannst du die DB Abfragen

Ist die DB überhaupt erreichbar / Heartbeat

http://127.0.0.1:8000/api/v1/heartbeat

Ausgabe irgendwas wie: {„nanosecond heartbeat“:1717134488888233555}

Collections auflisten

http://127.0.0.1:8000/api/v1/collections

Es findet sich der CollectionName der zum Workspace passt.

AnythingLLM Desktop

Dort habe ich mehrere Dokumente eingestellt

AnythingLLM Dokumente embedden

obige URL gibt also die Collections aus, in dem falle die „drei“, also den Namen des Workspaces.. Hätte ich das gewusst, hätte ichs anders benamst 😉

Beim Einfügen von Daten sieht man das übrigens schön in Docker

Anzahl der Embeddings auflisten

Dazu nutzen wir die (UU)id von „drei“ (siehe Screenshot vorher)

http://127.0.0.1:8000/api/v1/collections/734cb4ec-0b72-43d0-8e2c-d23680b7b2c8/count

Das entspricht auch der Ausgabe in AnythingLLM

AnythingLLM Anzahl Embeddings

Das Gleiche in python

pip install chromadb-client

ist installiert:

import chromadb


# Example setup of the client to connect to your chroma server
client = chromadb.HttpClient(host='localhost', port=8000)

collection = client.get_collection(name="drei")

print("-----------------------");
print(collection.peek()) # returns a list of the first 10 items in the collection
print("-----------------------");
print(collection.count()) # returns the number of items in the collection
print("-----------------------");

Wie kommen wir nun an die Daten / query?

Dazu müssen wir erst mal verstehen, welches Embedding-Modell genutzt wurde.
AnythingLLM hat im Standard sein „eigenes“ Modell

https://docs.useanything.com/features/embedding-models

und das verweist auf https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2

Dann erstellen wir mal einen einfachen python Client dazu:

import chromadb
from chromadb.config import Settings
from transformers import AutoTokenizer, AutoModel
import torch
import json



# Verbinde dich mit der ChromaDB
client = chromadb.HttpClient(host='localhost', port=8000)

# Definiere den Namen der Collection
collection_name = "drei"

# Hole oder erstelle die Collection
collection = client.get_or_create_collection(name=collection_name)

# Lade ein vortrainiertes Modell und Tokenizer von Hugging Face
tokenizer = AutoTokenizer.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")
model = AutoModel.from_pretrained("sentence-transformers/all-MiniLM-L6-v2")

# Definiere eine Einbettungsfunktion
def embed_text(texts):
    inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")
    with torch.no_grad():
        embeddings = model(**inputs)
    return embeddings.last_hidden_state.mean(dim=1).numpy()


# Führe eine Query aus
query_text = ["Frithjof Bergmann"]
query_embeddings = embed_text(query_text)
results = collection.query(
    query_embeddings=query_embeddings.tolist(),  # Nutze die Einbettungen für die Abfrage
    n_results=5
)

print("-----RESULTS-----");

# print(results);

# Formatiert ausgeben
formatted_data = json.dumps(results, indent=4, ensure_ascii=False)
print(formatted_data)

## Zeige die Ergebnisse an
#for result in results:
##    print(result)

und klappt:

Zusammenfassung

(Folgende Antworten sind von der KI generiert)

Hier ist ein schematisches Diagramm, das den Aufbau und die Interaktion der Komponenten im beschriebenen System darstellt:

  1. Einbettungsfunktion: Dies ist der Teil, in dem du mit einem vortrainierten Modell (z.B. von Hugging Face) Texte in numerische Vektoren (Embeddings) umwandelst.
  2. ChromaDB: Dies ist die Datenbank, die in SQLite gespeichert ist und die Dokumente sowie ihre zugehörigen Embeddings speichert.
  3. Abfrage: Der Teil, in dem du die Embeddings von Abfragetexten berechnest und diese Embeddings dann zur Abfrage der Datenbank verwendest, um ähnliche Dokumente zu finden.




Erläuterungen:

  1. Benutzer-Anwendung: Hier beginnt der Prozess. Der Benutzer sendet einen Text (z.B. Dokumente oder Abfragen).
  2. Einbettungsfunktion: Diese Komponente verwendet ein vortrainiertes Modell, um Texte in Embeddings (numerische Vektoren) zu transformieren.
  3. Embeddings: Die generierten Embeddings werden entweder in die Datenbank eingefügt (für neue Dokumente) oder für Abfragen verwendet.
  4. ChromaDB: Eine SQLite-basierte Datenbank, die die Dokumente und ihre Embeddings speichert.
  5. Abfrageverarbeitung: Bei einer Abfrage werden die Embeddings des Abfragetextes mit den gespeicherten Embeddings in der Datenbank verglichen, um ähnliche Dokumente zu finden.
  6. Abfrageergebnisse: Die Ergebnisse der Abfrage (ähnliche Dokumente) werden an die Benutzer-Anwendung zurückgegeben.

Wie funktioniert die Abfrage?

1) Wieso muss der Text in einen Vektor eingebettet werden?

In der maschinellen Verarbeitung von Sprache (Natural Language Processing, NLP) sind Maschinen nicht in der Lage, Text direkt zu verstehen. Sie benötigen eine numerische Darstellung des Textes, die sie verarbeiten können. Diese numerische Darstellung wird als „Einbettung“ (Embedding) bezeichnet und ist ein Vektor, der den Text in einem kontinuierlichen Zahlenraum repräsentiert.

Einbettungen haben folgende Vorteile:

  • Semantische Ähnlichkeit: Ähnliche Texte erhalten ähnliche Vektoren. Das bedeutet, dass die Abstände zwischen Vektoren semantische Ähnlichkeiten widerspiegeln.
  • Effizienz: Vektoroperationen sind effizient und ermöglichen schnelle Berechnungen und Vergleiche.
  • Universelle Darstellung: Einbettungen können universell für verschiedene Aufgaben verwendet werden, z.B. für Klassifikation, Clustering oder Suche.

2) Wie formuliere ich den Text richtig? Wird dieser 1:1 gesucht oder sollte man eine Frage stellen oder wie funktioniert das?

Der Text wird nicht 1:1 gesucht wie bei einer einfachen Textsuche, sondern die Einbettung des Textes wird mit den Einbettungen der in der Datenbank gespeicherten Texte verglichen. Daher ist es wichtig, den Text so zu formulieren, dass er den gewünschten Inhalt oder Kontext gut wiedergibt.

Hier sind einige Hinweise zur Formulierung des Textes:

  • Klarheit und Präzision: Verwende klare und präzise Formulierungen, um den gewünschten Kontext oder die Bedeutung zu vermitteln.
  • Natürliche Sprache: Du kannst den Text in natürlicher Sprache schreiben, da das Einbettungsmodell in der Lage ist, den semantischen Gehalt zu erfassen.
  • Fragen stellen: Das Stellen von Fragen kann hilfreich sein, wenn du nach spezifischen Informationen suchst. Zum Beispiel: „Was ist die Philosophie von Frithjof Bergmann?“ anstatt nur „Frithjof Bergmann“.

3) Wird hier das KI-Modell irgendwie genutzt?

Ja, das KI-Modell wird in mehreren Schritten genutzt:

  1. Text-Einbettung: Das Modell sentence-transformers/all-MiniLM-L6-v2, das auf der Hugging Face-Plattform bereitgestellt wird, ist ein vortrainiertes Transformationsmodell, das dazu dient, Texte in Vektoren (Einbettungen) umzuwandeln. Hier wird der Text durch den Tokenizer und das Modell verarbeitet, um seine numerische Darstellung zu erhalten.
  2. Ähnlichkeitsabfrage: Die erhaltenen Einbettungen werden dann genutzt, um semantische Ähnlichkeiten zwischen dem Abfragetext und den in der Datenbank gespeicherten Texten zu berechnen. Das KI-Modell hilft dabei, die Bedeutung des Textes zu erfassen und vergleichbare Inhalte in der Datenbank zu finden.

Hier ein genauerer Ablauf:

  • Der Text „Frithjof Bergmann“ wird tokenisiert und durch das Modell geführt, das eine Einbettung (Vektor) erstellt.
  • Diese Einbettung wird mit den Einbettungen der Texte in der Datenbank verglichen.
  • Die Ähnlichkeit wird berechnet, und die am besten passenden Einträge werden zurückgegeben.

Das vortrainierte Modell sorgt dafür, dass die Einbettungen die semantische Bedeutung des Textes widerspiegeln, wodurch ähnliche Inhalte gefunden werden können, selbst wenn die exakten Wörter nicht übereinstimmen.

4) Kann man das nur für Suche nutzen oder könnte man zB zu Fragen so auch Antworten hinterlegen und diese nutzen?

a, du kannst verschiedene Dokumenttypen in der Datenbank hinterlegen und sicherstellen, dass nur bestimmte Typen bei einer Abfrage berücksichtigt werden. Hier sind einige Strategien, wie du dies erreichen kannst:

1. Dokumenttyp kennzeichnen:

Du kannst jedes Dokument mit einem Typ-Tag versehen, z.B. „Frage“ oder „Antwort“. Diese Tags werden bei der Abfrage berücksichtigt, um sicherzustellen, dass nur die relevanten Dokumente zurückgegeben werden.

2. Sammlung in verschiedene Kategorien unterteilen:

Du könntest mehrere Sammlungen erstellen, z.B. eine Sammlung für „Fragen“ und eine andere für „Antworten“. Bei einer Abfrage auf die Sammlung „Antworten“ wird sichergestellt, dass nur Antworten zurückgegeben werden.

3. Filter in der Abfrage verwenden:

Wenn du alle Dokumente in einer einzigen Sammlung behältst, kannst du zusätzliche Metadaten verwenden, um den Typ zu kennzeichnen und dann bei der Abfrage einen Filter anzuwenden.

Beispielimplementierung:

Hier ein Beispiel, wie du die Dokumenttypen in einer ChromaDB-Sammlung kennzeichnen und filtern kannst:

  1. Dokumente hinzufügen mit Typ-Tag:

# Beispiel-Dokumente hinzufügen
documents = [ {"text": "Was ist die Philosophie von Frithjof Bergmann?", "type": "Frage"}, {"text": "Die Philosophie von Frithjof Bergmann betont die Bedeutung der Arbeit.", "type": "Antwort"} ]

for doc in documents: embedding = embed_text([doc["text"]]) collection.add({ "text": doc["text"], "type": doc["type"], "embedding": embedding.tolist() })

  1. Abfrage mit Typ-Filter:

# Beispiel-Abfrage
query_text = ["Was ist die Philosophie von Frithjof Bergmann?"]
query_embedding = embed_text(query_text)

results = collection.query( query_embeddings=query_embedding.tolist(), n_results=5, filter={"type": "Antwort"} # Nur Antworten zurückgeben )

print("-----RESULTS-----")
formatted_data = json.dumps(results, indent=4, ensure_ascii=False)
print(formatted_data)

Erweiterte Filterung:

Falls ChromaDB erweiterte Filterung unterstützt, kannst du auch komplexere Filterkriterien anwenden, um gezielt nach Antworten zu suchen.

Nutzung mehrerer Sammlungen:

Eine alternative Methode besteht darin, separate Sammlungen für Fragen und Antworten zu verwenden. Hier ein Beispiel:

  1. Erstellen von Sammlungen für Fragen und Antworten:

# Sammlungen erstellen questions_collection = client.get_or_create_collection(name="questions") answers_collection = client.get_or_create_collection(name="answers")

# Dokumente hinzufügen
questions_collection.add({ "text": "Was ist die Philosophie von Frithjof Bergmann?", "embedding": embed_text(["Was ist die Philosophie von Frithjof Bergmann?"]).tolist() })

answers_collection.add({ "text": "Die Philosophie von Frithjof Bergmann betont die Bedeutung der Arbeit.", "embedding": embed_text(["Die Philosophie von Frithjof Bergmann betont die Bedeutung der Arbeit."]).tolist() })

  1. Abfrage nur in der Antworten-Sammlung:

# Beispiel-Abfrage nur in der Antworten-Sammlung

query_text = ["Was ist die Philosophie von Frithjof Bergmann?"]
query_embedding = embed_text(query_text)

results = answers_collection.query( query_embeddings=query_embedding.tolist(), n_results=5 )

print("-----RESULTS-----")

formatted_data = json.dumps(results, indent=4, ensure_ascii=False)
print(formatted_data)

Fazit:

Durch das Kennzeichnen von Dokumenttypen und die Anwendung von Filtern bei der Abfrage kannst du sicherstellen, dass nur relevante Dokumente zurückgegeben werden, z.B. nur Antworten auf gestellte Fragen. Dies bietet eine flexible und effektive Methode, um unterschiedliche Dokumenttypen in einer einzigen Datenbank zu verwalten und abzufragen.

Hier das oben erwähnte Yaml für ChromaDB

openapi: 3.0.2
info:
  title: FastAPI
  version: 0.1.0
paths:
  /api/v1:
    get:
      summary: Root
      operationId: root
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                additionalProperties:
                  type: integer
                type: object
                title: Response Root Api V1 Get
  /api/v1/reset:
    post:
      summary: Reset
      operationId: reset
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: boolean
                title: Response Reset Api V1 Reset Post
  /api/v1/version:
    get:
      summary: Version
      operationId: version
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: string
                title: Response Version Api V1 Version Get
  /api/v1/heartbeat:
    get:
      summary: Heartbeat
      operationId: heartbeat
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                additionalProperties:
                  type: integer
                type: object
                title: Response Heartbeat Api V1 Heartbeat Get
  /api/v1/collections:
    get:
      summary: List Collections
      operationId: list_collections
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Collection'
                type: array
                title: Response List Collections Api V1 Collections Get
    post:
      summary: Create Collection
      operationId: create_collection
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCollection'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Collection'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_id}/add:
    post:
      summary: Add
      operationId: add
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Id
          name: collection_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddEmbedding'
        required: true
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                type: boolean
                title: Response Add Api V1 Collections  Collection Id  Add Post
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_id}/update:
    post:
      summary: Update
      operationId: update
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Id
          name: collection_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateEmbedding'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: boolean
                title: Response Update Api V1 Collections  Collection Id  Update Post
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_id}/upsert:
    post:
      summary: Upsert
      operationId: upsert
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Id
          name: collection_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddEmbedding'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: boolean
                title: Response Upsert Api V1 Collections  Collection Id  Upsert Post
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_id}/get:
    post:
      summary: Get
      operationId: get
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Id
          name: collection_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GetEmbedding'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetResult'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_id}/delete:
    post:
      summary: Delete
      operationId: delete
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Id
          name: collection_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeleteEmbedding'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                items:
                  type: string
                  format: uuid
                type: array
                title: Response Delete Api V1 Collections  Collection Id  Delete Post
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_id}/count:
    get:
      summary: Count
      operationId: count
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Id
          name: collection_id
          in: path
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: integer
                title: Response Count Api V1 Collections  Collection Id  Count Get
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_id}/query:
    post:
      summary: Get Nearest Neighbors
      operationId: get_nearest_neighbors
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Id
          name: collection_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QueryEmbedding'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryResult'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_name}:
    get:
      summary: Get Collection
      operationId: get_collection
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Name
          name: collection_name
          in: path
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Collection'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
    delete:
      summary: Delete Collection
      operationId: delete_collection
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Name
          name: collection_name
          in: path
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Collection'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /api/v1/collections/{collection_id}:
    put:
      summary: Update Collection
      operationId: update_collection
      parameters:
        - required: true
          schema:
            type: string
            title: Collection Id
          name: collection_id
          in: path
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCollection'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Collection'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    AddEmbedding:
      properties:
        metadatas:
          items:
            additionalProperties:
              type: string
            type: object
        embeddings:
          items:
            items:
              type: number
              format: float
            type: array
      type: object
      required:
        - ids
      title: AddEmbedding
    Collection:
      properties:
        name:
          type: string
        id:
          type: string
          format: uuid
        metadatas:
          additionalProperties:
            type: string
          type: object
      type: object
      required:
        - name
        - id
      title: Collection
    CreateCollection:
      properties:
        metadata:
          additionalProperties:
            type: string
          type: object
      type: object
      required:
        - name
      title: CreateCollection
    DeleteEmbedding:
      properties:
        ids:
          items:
            type: string
          type: array
        where:
          additionalProperties:
            type: string
          type: object
        where_document:
          additionalProperties:
            type: string
          type: object
      type: object
      title: DeleteEmbedding
    GetEmbedding:
      properties:
        ids:
          items:
            type: string
          type: array
        limit:
          type: integer
        offset:
          type: integer
        sort:
          type: string
        where:
          additionalProperties:
            type: string
          type: object
        where_document:
          additionalProperties:
            type: string
          type: object
      type: object
      title: GetEmbedding
    GetResult:
      properties:
        ids:
          items:
            type: string
          type: array
          title: Ids
        embeddings:
          items:
            anyOf:
              - items:
                  type: number
                type: array
              - items:
                  type: integer
                type: array
          type: array
          title: Embeddings
        documents:
          items:
            type: string
          type: array
          title: Documents
        metadatas:
          items:
            additionalProperties:
              anyOf:
                - type: string
                - type: integer
                - type: number
                - type: boolean
            type: object
          type: array
          title: Metadatas
      type: object
      required:
        - ids
        - embeddings
        - documents
        - metadatas
      title: GetResult
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    QueryEmbedding:
      properties:
        where:
          additionalProperties:
            type: string
          type: object
        where_document:
          additionalProperties:
            type: string
          type: object
        query_embeddings:
          items:
            items:
              type: number
              format: float
            type: array
          type: array
        n_results:
          type: integer
        include:
          items:
            type: string
          type: array
      type: object
      required:
        - query_embeddings
      title: QueryEmbedding
    QueryResult:
      properties:
        ids:
          items:
            items:
              type: string
            type: array
          type: array
          title: Ids
        embeddings:
          items:
            items:
              anyOf:
                - items:
                    type: number
                  type: array
                - items:
                    type: integer
                  type: array
            type: array
          type: array
          title: Embeddings
        documents:
          items:
            items:
              type: string
            type: array
          type: array
          title: Documents
        metadatas:
          items:
            items:
              additionalProperties:
                anyOf:
                  - type: string
                  - type: integer
                  - type: number
                  - type: boolean
              type: object
            type: array
          type: array
          title: Metadatas
        distances:
          items:
            items:
              type: number
            type: array
          type: array
          title: Distances
      type: object
      required:
        - ids
        - embeddings
        - documents
        - metadatas
        - distances
      title: QueryResult
    UpdateCollection:
      properties:
        new_name:
          type: string
        new_metadata:
          additionalProperties:
            type: string
          type: object
      type: object
      title: UpdateCollection
    UpdateEmbedding:
      properties:
        metadatas:
          items:
            additionalProperties:
              type: string
            type: object
        embeddings:
          items:
            items:
              type: number
              format: float
            type: array
      type: object
      required:
        - ids
      title: UpdateEmbedding
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError

Beitrag veröffentlicht

in

von

Schlagwörter: