\n\n\n\n Wie man die Token-Nutzung mit ChromaDB optimiert (Schritt für Schritt) - AgntKit \n

Wie man die Token-Nutzung mit ChromaDB optimiert (Schritt für Schritt)

📖 10 min read1,970 wordsUpdated Mar 29, 2026

Wie man Token-Nutzung mit ChromaDB optimiert (Schritt für Schritt)

Wenn du nicht auf die Token-Nutzung in deinen Abfragen an die Vektordatenbank achtest, verbrauchst du Credits und Leistung schneller als du denkst – hier ist, wie du die Token-Nutzung in ChromaDB optimieren kannst, als möchtest du tatsächlich Geld sparen und die Geschwindigkeit erhöhen.

Was du bauen wirst und warum es wichtig ist

Wir bauen eine minimale, aber effektive Pipeline, die chaotische reale Dokumente aufnimmt, sie in ChromaDB speichert und sie mit OpenAI-Embeddings abfragt, während wir gleichzeitig den Token-Abfall auf ein Minimum reduzieren.

Voraussetzungen

  • Python 3.11+
  • pip install chroma-core==0.10.0 (neueste Version ab März 2026)
  • OpenAI API-Schlüssel mit Zugriff auf Embedding-Endpunkte
  • Grundkenntnisse über Vektordatenbanken und APIs großer Sprachmodelle

Schritt 1: Richte deine ChromaDB-Umgebung ein

Zunächst musst du ChromaDB installieren und so zum Laufen bringen, dass es gut mit deiner Umgebung funktioniert. Chroma-core, die Kern-Engine hinter ChromaDB, zieht eine Menge Aufmerksamkeit auf GitHub auf sich: über 26.759 Sterne und 2.140 Forks, das bedeutet, dass es weit entfernt von einem Nischenexperiment ist. Das bedeutet viel Unterstützung aus der Community, aber auch einige unvermeidliche offene Probleme (und ChromaDB hat zum Stand März 2026 513 offene).

Die neueste Version, lizenziert unter Apache-2.0, wurde am 21.03.2026 aktualisiert – also wird sie aktiv gewartet, und das ist gut, denn du wirst stark darauf angewiesen sein, um deine Embeddings vernünftig zu verwalten.

# Installiere chroma-core, falls du es noch nicht getan hast
pip install chroma-core==0.10.0

Die Einrichtung einer permanenten ChromaDB bedeutet normalerweise einfach, diesen minimalen Code-Schnipsel auszuführen:

from chromadb import Client

client = Client() # Standard-Einstellungen - SQLite + Lokale Festplatte
collection = client.get_or_create_collection(name="mydocs")

Warum das zuerst machen? Weil jeder andere Schritt sich um variables Token-Budget dreht – und das Management der ChromaDB-Abhängigkeiten zuerst kommt.

Übliche Probleme: Wenn du auf Fehler wie ModuleNotFoundError stößt, überprüfe deine Versionen. Chroma-core-Updates ändern oft die internen Abläufe, also vermeide zufällige Probleme, indem du eine spezifische Version festlegst.

Schritt 2: Inhalte für Token-Effizienz chunkieren

Deine Dokumente sind nicht ordentlich und aufgeräumt – sie kommen mit Überschriften, Tabellen, Fußnoten und unerwünschten Bits daher. Langes Füttern von Strings an Embedding-APIs ist ein sicherer Weg, um Tokens zu verschwenden. Jedes Token zählt.

Stattdessen solltest du deine Inhalte clever chunkieren. Nicht zu groß, nicht zu klein. Eine Chunk-Größe, die den Token-Grenzen deiner Embedding-API entspricht oder leicht darunter liegt, spart eine Menge an Rechenleistung und Kosten.

import tiktoken # Für die Token-Zählung, OpenAIs eigenen Tokenizer
from langchain.text_splitter import RecursiveCharacterTextSplitter

# Initialisiere einen Splitter für ~500 Tokens Chunks (sicher für OpenAI Embeddings)
splitter = RecursiveCharacterTextSplitter(
 chunk_size=500,
 chunk_overlap=50,
 length_function=lambda text: len(tiktoken.encoding_for_model("text-embedding-3-small").encode(text))
)

def chunk_text(text):
 chunks = splitter.split_text(text)
 print(f"Aufgeteilt in {len(chunks)} Chunks")
 return chunks

# Beispielnutzung
doc_text = open("messy_doc.txt").read()
chunks = chunk_text(doc_text)

Warum chunkieren Tokens spart: Wenn du ganze Dokumente an die Embedding-API sendest, erhältst du riesige Embeddings, aber größtenteils nur Rauschen – außerdem könntest du die Token-Grenzen überschreiten oder die Ratenlimits auslösen. Kleine, aber bedeutungsvolle Chunks erzeugen zuverlässig fokussierte Embeddings für eine genaue Vektorsuche.

Fehler, auf die man achten sollte: Überlappende Chunks könnten gelegentlich in den Suchergebnissen redundant erscheinen – passe chunk_overlap entsprechend an. Und achte auf die Auswahl des Tokenizers. Wenn du Tokenizer-Modelle nicht übereinstimmend wählst, werden deine Token-Zahlen um 20-30% abweichen, was deinen gesamten Token-Budgetplan ruinieren kann.

Schritt 3: Embeddings mit ChromaDB – Optimiere, embedde nicht blind alles

Hier blasen viele Entwickler ihr Token-Budget. Jedes Chunk durch den Embedding-Endpunkt von OpenAI zu schicken, schädigt dein Budget.

Stattdessen möchtest du Chunks vor dem Embedding vorfiltern. Verwende einen günstigen Textähnlichkeitsfilter. Mach einen schnellen TF-IDF-Test und embedde dann nur die besten 30–40% der Chunks. Das reduziert den Speicherbedarf, die Abfragezeit und die Token-Kosten.

from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np

# Eine günstige Annäherung, um bedeutungsvolle Chunks vor teuren Embeddings zu filtern
def filter_chunks(chunks, query, keep_ratio=0.4):
 vectorizer = TfidfVectorizer()
 X = vectorizer.fit_transform(chunks + [query])
 query_vec = X[-1]
 chunk_vecs = X[:-1]
 similarities = (chunk_vecs @ query_vec.T).toarray().flatten()
 threshold = np.quantile(similarities, 1 - keep_ratio)
 filtered = [chunk for chunk, sim in zip(chunks, similarities) if sim >= threshold]
 print(f"Gefiltert von {len(chunks)} auf {len(filtered)} Chunks vor dem Embedding")
 return filtered

chunks_to_embed = filter_chunks(chunks, "Was ist Token-Nutzungsoptimierung?")

Jetzt embedde nur chunks_to_embed in ChromaDB:

from openai import OpenAI
import chromadb

client = chromadb.Client()
collection = client.get_or_create_collection("mydocs")

embedding_model = OpenAI()

for chunk in chunks_to_embed:
 embedding = embedding_model.embeddings.create(input=chunk).data[0].embedding
 collection.add(
 documents=[chunk], 
 embeddings=[embedding], 
 ids=[hash(chunk) % (10 ** 8)] # einzigartiger, aber einfacher ID
 )

Warum dieser Ansatz? Weil Embeddings die großen Token-Verschwender sind. Ein einzelner 500-Token-Chunk kostet 500 Tokens nur für die Vektorisierung. Willst du wirklich Müllfragmente embedden? Nein. Filtere clever und spare Tokens.

Fehler, auf die du stoßen könntest: API-Ratenlimits. Die Batch-Einfügung von ChromaDB kann helfen, API-Aufrufe zu minimieren – mehr dazu weiter unten.

Schritt 4: Bulk-Batch-Einfügungen zur Reduzierung von API-Aufrufen

Es geht nicht nur um Tokens – du frisst Latenz und zahlst am Ende mehr für zu viele kleine Aufrufe. Bulk-Batch-Einfügungen erledigen zwei Probleme auf einmal: bessere Durchsatzrate und weniger redundante API-Zugriffe.

ChromaDB’s collection.add unterstützt mehrere Dokumente und Embeddings auf einmal. Staple deine gefilterten Chunks in Chargen von 50 oder 100, um viel Zeit zu sparen.

BATCH_SIZE = 50

def batch(iterable, n=1):
 l = len(iterable)
 for ndx in range(0, l, n):
 yield iterable[ndx:min(ndx + n, l)]

for chunk_batch in batch(chunks_to_embed, BATCH_SIZE):
 embeddings = [embedding_model.embeddings.create(input=chunk).data[0].embedding for chunk in chunk_batch]
 collection.add(
 documents=chunk_batch,
 embeddings=embeddings,
 ids=[hash(chunk) % (10 ** 8) for chunk in chunk_batch]
 )
 print(f"Indexiert {len(chunk_batch)} Chunks in Batch")

Warum Batch? Eine Anfrage = ein Token-Abrechnungsereignis und ein Netzwerkaufruf. Sei nicht dieser Entwickler, der auf 100 individuelle API-Aufrufe wartet.

Achte auf:

  • Zu große Batchgrößen – über 100 pro Aufruf können drosseln.
  • Teilweise Fehler – umhülle deine Aufrufe mit try/except, um intermittierende Fehler wie Zeitüberschreitungen oder 429s zu behandeln.

Schritt 5: Intelligente Token-Zählung vor Abfragen – Geh nicht nur nach Gefühl

Bei der Durchführung von Abfragen benötigst du einen Überblick über die Tokens, die die gesamte Pipeline verbraucht. Dies ist besonders kritisch, wenn deine Abfragen selbst lange Passagen oder kombinierte Benutzereingaben plus Kontext sind.

Anstatt die Token-Zahlen zu schätzen, verlasse dich auf tiktoken oder ein Äquivalent, um genau die Tokens bei jedem Schritt zu zählen. So kannst du Eingaben in Echtzeit kürzen oder anpassen, bevor du die Abfrage ausführst.

def count_tokens(text, model_name="gpt-4o-mini"):
 tokenizer = tiktoken.encoding_for_model(model_name)
 tokens = tokenizer.encode(text)
 return len(tokens)

query = "Erkläre die Token-Optimierung in ChromaDB so einfach wie möglich."
tokens_used = count_tokens(query)
print(f"Token-Zahl für die Abfrage: {tokens_used}")

Warum das Ganze? Weil OpenAI-Embeddings und Chat-Komplettierungen strenge Token-Grenzen haben. Wenn du über 4.096 Tokens kommst, wird normalerweise eine Kürzung, ein Fehler oder zusätzliche Abrechnung ausgelöst, die du lieber vermeiden würdest.

Fehler, die du sehen wirst: Der gefürchtete OpenAIError: Die maximale Kontextlänge dieses Modells beträgt 4097 Tokens. Geh damit um, indem du die Tokens vor dem Senden von Anfragen zählst und die Benutzereingaben oder den Kontext entsprechend kürzt (im nächsten Abschnitt detailliert).

Schritt 6: Kontextkürzung und Caching von Embeddings

Wenn du Dokumente und Chatverläufe in dein Sprachmodell einspeist, sind die insgesamt verwendeten Tokens von großer Bedeutung. Ein häufiger Anfängerfehler besteht darin, immer dein gesamtes Dokument oder den gesamten Chatverlauf unbedacht zu senden. Du überschreitest die Token-Grenzen in Sekunden.

Deine beste Option: kürzen und cachen.

  • Speichere Embeddings für statische Dokumente (keine erneute Einbettung desselben Textes)
  • Kürze den Chatverlauf intelligent, indem du recent wichtige Eingaben priorisierst
  • Verwende ein rollierendes Token-Fenster von ~3.000 Tokens für den Kontext in Chats/Vervollständigungen

Hier ist ein Snippet, das den Cache-Check und die Kürzung veranschaulicht:

embedding_cache = {}

def get_embedding(text):
 if text in embedding_cache:
 print("Cache Treffer für Embedding")
 return embedding_cache[text]
 embedding = embedding_model.embeddings.create(input=text).data[0].embedding
 embedding_cache[text] = embedding
 return embedding

def trim_context(contexts, max_tokens=3000, model_name="gpt-4o-mini"):
 trimmed = []
 token_count = 0
 for c in reversed(contexts): # von den neuesten beginnen
 tcount = count_tokens(c, model_name)
 if (token_count + tcount) <= max_tokens:
 trimmed.insert(0, c)
 token_count += tcount
 else:
 break
 print(f"Kontext auf {len(trimmed)} Nachrichten mit insgesamt {token_count} Tokens gekürzt")
 return trimmed

Dieser caching Ansatz spart Ihnen monatlich Hunderte, vielleicht Tausende von Tokens.

Die Probleme

Hier bricht der idealisierte Tutorial-Code in der realen Welt zusammen:

Problem Was passiert Wie man es vermeidet
Tokenlimits mismatch Ihre Tokenzählungen sind aufgrund von Unterschieden im Tokenizer oder Modell ungenau; Sie überschreiten oder unterschreiten Tokens Verwenden Sie immer tiktoken.encoding_for_model(), das genau mit dem Embedding oder dem Completion-Modell übereinstimmt, das Sie verwenden
Duplicate embeddings Das mehrmalige Embedding des gleichen Segments verschwendet Tokens und Speicherplatz Implementieren Sie Caching und dokumentieren Sie Checksumme-Hashing
Chunk-Überlappungsfehler Zu hohe Überlappung erzeugt redundante Vektoren; zu wenig Überlappung verliert den Kontext in geteilten Dokumenten Experimentieren Sie mit dem Parameter chunk_overlap, wobei Sie bei 10-15% der Chunk-Größe bleiben
Concurrency deadlocks Mehrere asynchrone Aufrufe an ChromaDB oder OpenAI können Rennbedingungen oder partielle Einfügungen verursachen Verwenden Sie synchronen Code oder geeignete asynchrone Warteschlangen; Batch-Einfügungen schützen Sie davor
Unzuverlässige Tokenzählung bei nicht-englischen Texten Tokenizer können aufgrund von Multi-Byte-Zeichen oder ungewöhnlichen Schriften falsch zählen Testen Sie mit repräsentativen Sprachen und passen Sie die Chunk-Größen entsprechend an

Vollständiges Codebeispiel: Alles zusammenfügen

Dieses Beispiel kombiniert alle vorherigen Schritte in einer funktionierenden Pipeline:

import tiktoken
from chromadb import Client
from openai import OpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np

# Konstanten
MODEL_NAME = "text-embedding-3-small"
EMBEDDING_BATCH_SIZE = 50
CHUNK_SIZE = 500
CHUNK_OVERLAP = 50

# Setup
client = Client()
collection = client.get_or_create_collection(name="mydocs")
openai_client = OpenAI()
tokenizer = tiktoken.encoding_for_model(MODEL_NAME)

def count_tokens(text):
 return len(tokenizer.encode(text))

def chunk_text(text):
 splitter = RecursiveCharacterTextSplitter(
 chunk_size=CHUNK_SIZE,
 chunk_overlap=CHUNK_OVERLAP,
 length_function=count_tokens
 )
 return splitter.split_text(text)

def filter_chunks(chunks, query, keep_ratio=0.4):
 vectorizer = TfidfVectorizer()
 X = vectorizer.fit_transform(chunks + [query])
 query_vec = X[-1]
 chunk_vecs = X[:-1]
 sims = (chunk_vecs @ query_vec.T).toarray().flatten()
 thresh = np.quantile(sims, 1 - keep_ratio)
 return [chunk for chunk, sim in zip(chunks, sims) if sim >= thresh]

def batch(iterable, n=1):
 l = len(iterable)
 for ndx in range(0, l, n):
 yield iterable[ndx:min(ndx + n, l)]

def embed_and_index(chunks):
 for chunk_batch in batch(chunks, EMBEDDING_BATCH_SIZE):
 embeddings = []
 for chunk in chunk_batch:
 response = openai_client.embeddings.create(input=chunk)
 embeddings.append(response.data[0].embedding)
 ids = [str(hash(chunk) % (10**8)) for chunk in chunk_batch]
 collection.add(documents=chunk_batch, embeddings=embeddings, ids=ids)
 print(f"Batch indiziert {len(chunk_batch)} Segmente")

# Hauptpipeline
doc_text = open("messy_doc.txt").read()

print("Dokument wird in Segmente unterteilt...")
chunks = chunk_text(doc_text)
print(f"{len(chunks)} Segmente erstellt")

# Simuliere eine Beispielanfrage
query = "Wie wird die Token-Nutzung mit ChromaDB optimiert?"

print("Segmente vor dem Embedding filtern...")
chunks_to_embed = filter_chunks(chunks, query)

print(f"{len(chunks_to_embed)} Segmente werden eingebettet und indiziert...")
embed_and_index(chunks_to_embed)

print("Pipeline abgeschlossen.")

Was kommt als Nächstes

Wenn es Ihnen gelungen ist, dies erfolgreich umzusetzen, sollte Ihr nächster Schritt darin bestehen, die rangierte Abfrage mit den GPT-Vervollständigungen von OpenAI zu integrieren, um ein retrieval augmentiertes Generierung (RAG) System zu erstellen, das Antworten aus Ihrer Vektordatenbank mit minimierten Token-Abrechnungen erhält.

Konzentrieren Sie sich speziell darauf, Ihre ChromaDB-Anfragen mit einem Antwortgenerator zu kombinieren, der den Kontext intelligent kürzt, idealerweise indem Sie die Anfrage umformulieren, um den Tokenverbrauch bei der Eingabeaufforderung zu reduzieren.

Häufig gestellte Fragen

F: Warum nicht einfach das gesamte Dokument einmal an die Embedding-API senden?

A: Weil die Tokenlimits der Embedding-API normalerweise bei einigen Tausend Tokens liegen – zu wenig für große Dokumente – und Sie linear pro Token bezahlen, sodass Sie Geld verschwenden und weniger präzise Embeddings erhalten, die die Abrufgenauigkeit beeinträchtigen.

F: Wie gehe ich mit Dokumenten um, die sich häufig ändern, mit ChromaDB?

A: Sie müssen Delta-Embeddings implementieren – nur neue oder geänderte Segmente erneut einbetten. Ein naiver Ansatz ist, den Text jedes Segments zu hashen und mit gespeicherten IDs zu vergleichen, um zu wissen, was aktualisiert werden muss.

F: Wie kann ich Tokenfehlzählungen in meiner App debuggen?

A: Verwenden Sie die offizielle tiktoken Bibliothek von OpenAI und stellen Sie sicher, dass der Modellname in encoding_for_model() genau mit dem übereinstimmt, was Sie an die API senden. Überprüfen Sie Ihre Zählung, indem Sie Token-Arrays drucken und die Chunk-Größen überprüfen.

Empfehlungen für verschiedene Entwicklerpersönlichkeiten

Junior Devs: Beginnen Sie damit, die Tokenlimits und Chunking zu verstehen. Versuchen Sie nicht, alles auf einmal zu optimieren. Ihr Fokus sollte darauf liegen, Dokumente in ~500 Token große Segmente zu zerlegen und sicherzustellen, dass Ihre API-Aufrufe fehlerfrei funktionieren.

Mid-Level Devs: Implementieren Sie als Nächstes das Filtern und Batchen. Verwenden Sie TF-IDF, um vorab auszuwählen, welche Segmente eingebettet werden sollen. Fügen Sie Caching hinzu, damit Sie keine Duplikate erneut einbetten. In dieser Phase sparen Sie echtes Geld und Zeit.

Senior Engineers: Automatisieren Sie das Token-Monitoring von Ende zu Ende. Erstellen Sie Dashboards, die Sie bei spitzen Nutzung alarmieren. Erkunden Sie benutzerdefinierte Chunker, die auf Ihren Dokumenttyp abgestimmt sind. Integrieren Sie Nutzungsmetriken mit Kostendashboards und experimentieren Sie mit Eingabeaufforderungsingenieurtechnik für das Kürzen des Kontexts.

Daten vom 22. März 2026. Quellen: https://github.com/chroma-core/chroma, https://community.openai.com/t/issue-chromadb-document-and-token-openai-limitations/317378

Verwandte Artikel

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: comparisons | libraries | open-source | reviews | toolkits
Scroll to Top