\n\n\n\n Wie man die Verwendung von Tokens mit ChromaDB optimiert (Schritt für Schritt) - AgntKit \n

Wie man die Verwendung von Tokens mit ChromaDB optimiert (Schritt für Schritt)

📖 11 min read2,040 wordsUpdated Mar 29, 2026

Wie Sie die Nutzung von Tokens mit ChromaDB optimieren (Schritt für Schritt)

Wenn Sie nicht auf die Verwendung von Tokens in Ihren Anfragen an die Vektordatenbank achten, verbrauchen Sie Credits und Leistung schneller, als Sie es bemerken – hier erfahren Sie also, wie Sie die Nutzung von Tokens mit chromadb optimieren können, als ob Sie wirklich Geld und Zeit sparen wollten.

Was Sie erstellen werden und warum es wichtig ist

Wir erstellen ein minimales, aber effektives Pipeline, das echte und unordentliche Dokumente nimmt, sie in ChromaDB speichert und sie mit OpenAI-Embeddings abfragt, während wir den Tokenverbrauch 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 die Embedding-Endpunkte
  • Grundkenntnisse über Vektordatenbanken und APIs für fortgeschrittene Sprachmodelle

Schritt 1: Richten Sie Ihre ChromaDB-Umgebung ein

Zuerst müssen Sie ChromaDB installieren und es so zum Laufen bringen, dass es gut in Ihre Umgebung integriert ist. Chroma-core, die Hauptantriebseinheit von ChromaDB, zieht viel Aufmerksamkeit auf GitHub auf sich: mehr als 26.759 Sterne und 2.140 Forks, also ist es kein einfaches Nischenprojekt. Das bedeutet viel Unterstützung von der Community, aber auch einige unvermeidbare offene Probleme (und ChromaDB hat ab März 2026 513 offene Issues).

Die neueste Version, lizenziert unter Apache-2.0, wurde am 2026-03-21 aktualisiert – also wird es aktiv gepflegt, und das ist gut, denn Sie werden es intensiv nutzen, um Ihre Embeddings sinnvoll zu verwalten.

# Installieren Sie chroma-core, falls noch nicht geschehen
pip install chroma-core==0.10.0

Die Konfiguration einer persistierenden ChromaDB bedeutet normalerweise, diesen minimalen Codeausschnitt auszuführen:

from chromadb import Client

client = Client() # Verwendet die Standardparameter - SQLite + lokaler Speicher
collection = client.get_or_create_collection(name="mydocs")

Warum sollten Sie das zuerst tun? Weil jeder folgende Schritt sich um die Verwaltung der Budget-Token-Variablen dreht – und die Verwaltung der Abhängigkeiten von ChromaDB Priorität hat.

Häufige Probleme: Wenn Sie Fehler wie ModuleNotFoundError begegnen, überprüfen Sie Ihre Versionen. Updates von Chroma-core ändern oft die internen Strukturen, daher verhindert das Festhalten an einer bestimmten Version zufällige Ausfälle.

Schritt 2: Inhalte für die Effizienz der Tokens fragmentieren

Ihre Dokumente sind nicht gut organisiert – sie kommen mit Überschriften, Tabellen, Fußnoten und unerwünschten Elementen. Lange Ketten an die Embedding-APIs zu senden, ist ein sicheres Mittel, um Tokens zu verschwenden. Jeder Token zählt.

Stattdessen fragmentieren Sie Ihren Inhalt intelligent. Nicht zu groß, nicht zu klein. Eine Chunk-Größe, die den Token-Grenzwerten Ihrer Embedding-API entspricht oder leicht darunter liegt, spart viel Rechenaufwand und unnötige Kosten.

import tiktoken # Für die Tokenzählung, den Tokenizer von OpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter

# Initialisieren Sie einen Teiler für Chunks von etwa 500 Tokens (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"In {len(chunks)} Chunks zerlegt")
 return chunks

# Beispiel für die Verwendung
doc_text = open("messy_doc.txt").read()
chunks = chunk_text(doc_text)

Warum das Fragmentieren Tokens spart: Wenn Sie gesamte Dokumente in die Embedding-API einspeisen, erhalten Sie riesige Embeddings, aber hauptsächlich Rauschen – zudem könnten Sie die Token-Grenzen überschreiten oder Ratenlimits auslösen. Kleine, aber bedeutungsvolle Chunks produzieren zuverlässig zielgerichtete Embeddings für präzise Vektorsuche.

Fehler, auf die Sie achten sollten: Überlappende Chunks erscheinen manchmal in den Suchergebnissen redundant – passen Sie chunk_overlap entsprechend an. Und seien Sie vorsichtig bei der Auswahl des Tokenizers. Wenn Sie unterschiedliche Tokenizer-Modelle verwenden, können Ihre Token-Zählungen um 20 bis 30 % abweichen und damit Ihre Token-Budgetplanung ruinieren.

Schritt 3: Embeddings mit ChromaDB – Optimieren, nicht alles vergraben

Hier überschreiten viele Entwickler ihr Token-Budget. Jeden Chunk über den Embedding-Endpunkt von OpenAI zu senden, erschöpft Ihr Budget.

Stattdessen möchten Sie die Chunks vor dem Embedding vorfiltern. Verwenden Sie einen kostengünstigen Textähnlichkeitsfilter. Wie eine schnelle TF-IDF-Prüfung, und dann nur die 30–40 % besten Chunks einbetten. Das reduziert die Speicherung, die Abfragezeit und die Token-Kosten.

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

# Eine kostengünstige Annäherung, um bedeutende Chunks vor kostspieligen 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 die Optimierung der Token-Nutzung?")

Jetzt betten Sie nur chunks_to_embed in ChromaDB ein:

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)] # Einfache, aber eindeutige ID
 )

Warum dieser Ansatz? Weil Embeddings große Verbraucher von Tokens sind. Ein einzelner Chunk von 500 Tokens kostet 500 Tokens allein für die Vektorisierung. Möchten Sie wirklich nutzlose Fragmente einbetten? Nein. Filtern Sie intelligent und sparen Sie Tokens.

Fehler, auf die Sie stoßen könnten: Ratenlimits der API. Das Batch-Insert von ChromaDB kann helfen, API-Aufrufe abzubauen – mehr dazu weiter unten.

Schritt 4: Batch-Status für API-Aufrufe reduzieren

Es geht nicht nur um Tokens – Sie erleben Latenz und zahlen am Ende mehr für zu viele kleine Aufrufe. Batch-Insert-Operationen erledigen zwei Dinge auf einmal: einen besseren Durchsatz und weniger redundante API-Aufrufe.

Die Methode collection.add von ChromaDB unterstützt mehrere Dokumente & Embeddings gleichzeitig. Gruppieren Sie Ihre gefilterten Chunks in Batches von 50 oder 100, um 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"Indiziert {len(chunk_batch)} Chunks im Batch")

Warum Batch-Verarbeitung? Eine Anfrage = ein Ereignis für die Token-Abrechnung und ein round-trip-Netzwerk. Seien Sie nicht der Entwickler, der auf 100 individuelle API-Aufrufe hintereinander wartet.

Achten Sie auf:

  • Zu große Batches – mehr als 100 pro Aufruf kann Sie verlangsamen.
  • Teilweise Fehler – umhüllen Sie Ihre Aufrufe mit try/except, um intermittierende Fehler wie Zeitüberschreitungen oder 429-Fehler zu bewältigen.

Schritt 5: Intelligente Token-Zählung vor Anfragen – nicht raten

Bei der Ausführung von Anfragen sollten Sie eine Vorstellung davon haben, wie viele Tokens die gesamte Pipeline verbraucht. Das ist besonders kritisch, wenn Ihre Anfragen selbst lange Absätze oder eine Kombination aus Benutzereingaben und Kontext sind.

Anstatt die Token-Zahl zu schätzen, verlassen Sie sich auf tiktoken oder dessen Pendant, um die Tokens genau in jedem Schritt zu zählen. So können Sie die Eingaben entweder auf die Schnelle kürzen oder anpassen, bevor Sie diese Anfrage ausgeben.

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ären Sie die Optimierung von Tokens in ChromaDB so einfach wie möglich."
tokens_used = count_tokens(query)
print(f"Token-Zähler für die Anfrage: {tokens_used}")

Warum sich die Mühe machen? Weil die OpenAI-Embeddings und Chatcompletions strenge Tokenlimits haben. Über 4.096 Tokens hinaus führt häufig zu Trunkierungen, Fehlern oder zusätzlichen Kosten, die Sie vermeiden möchten.

Fehler, die Sie möglicherweise treffen: Der gefürchtete OpenAIError: Die maximale Kontextlänge dieses Modells beträgt 4097 Tokens. Gehen Sie mit diesen Fehlern um, indem Sie die Tokens zählen, bevor Sie Anfragen senden, und gegebenenfalls die Benutzereingaben oder den Kontext anpassen (im nächsten Abschnitt genauer ausgeführt).

Schritt 6: Kontexttrimming und Caching der Embeddings

Wenn Sie Dokumente und einen Chatverlauf in Ihr Sprachmodell einspeisen, ist die Gesamtzahl der verwendeten Tokens von immensem Interesse. Ein häufiger Fehler von Anfängern ist es, immer Ihr gesamtes Dokument oder Ihren gesamten Chatverlauf ohne Unterscheidung zu senden. Sie überschreiten die Tokenlimits in wenigen Sekunden.

Ihre beste Option: Trimmen und Cachen.

  • Cache die Embeddings für statische Dokumente (nicht denselben Text erneut einbetten)
  • Trimmen Sie den Chatverlauf intelligent und priorisieren Sie wichtige, aktuelle Eingaben
  • Verwenden Sie ein gleitendes Tokenfenster von etwa 3.000 Tokens für den Kontext in Chats/Completions

Hier ist ein Auszug, der die Cacheüberprüfung und das Trimming veranschaulicht:

embedding_cache = {}

def get_embedding(text):
 if text in embedding_cache:
 print("Zugriff auf den Cache für das 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): # beginnt mit dem aktuellsten
 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 reduziert, insgesamt {token_count} Tokens")
 return trimmed

Dieser Caching-Ansatz spart Ihnen jeden Monat Hunderte, wenn nicht Tausende von Tokens.

Die Fallstricke

Hier trifft der ideale Tutorialcode auf die Realität:

Fallstrick Was passiert Wie man vermeidet
Inkonstanz bei den Tokenlimits Ihre Tokenzählungen sind falsch aufgrund einer Inkonsistenz zwischen dem Tokenizer oder dem Modell; Sie überschreiten oder verwenden zu wenige Tokens Verwenden Sie immer tiktoken.encoding_for_model(), das genau dem Embedding- oder Completion-Modell entspricht, das Sie verwenden
Duplizierte Embeddings Das wiederholte Einbetten desselben Stücks verschwendet Tokens und Speicherplatz Implementieren Sie Caching und Hashing von Dokumenten-Checksums
Überlappungsfehler bei Stücken Ein zu großes Überlappen erzeugt redundante Vektoren; ein zu kleines Überlappen verliert den Kontext in fragmentierten Dokumenten Experimentieren Sie mit dem Parameter chunk_overlap, indem Sie zwischen 10-15% der Größe der Stücke bleiben
Deadlocks bei der Parallelverarbeitung Mehrere asynchrone Aufrufe an ChromaDB oder OpenAI können zu Wettlaufsituationen oder partiellen Einfügungen führen Verwenden Sie synchronen Code oder ein gutes asynchrones Warteschlangensystem; Batch-Einfügungen schützen Sie davor
Unzuverlässige Tokenzählung bei nicht-englischen Texten Tokenizer können falsch zählen aufgrund von Mehrbyte-Zeichen oder ungewöhnlichen Skripten Testen Sie mit repräsentativen Sprachen, passen Sie die Stückgrößen entsprechend an

Vollständiges Codebeispiel: Alles Zusammenfügen

Dieses Modell kombiniert alle vorherigen Schritte in einem funktionalen 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

# Konfiguration
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"Indexiert: Chargen von {len(chunk_batch)} Stücken")

# Haupt-Pipeline
doc_text = open("messy_doc.txt").read()

print("Zerlegen des Dokuments...")
chunks = chunk_text(doc_text)
print(f"Generated {len(chunks)} pieces")

# Simulieren einer Beispielanfrage
query = "Wie wird die Verwendung von Tokens in ChromaDB optimiert?"

print("Filtern der Stücke vor dem Embedding...")
chunks_to_embed = filter_chunks(chunks, query)

print(f"Einbetten und Indizieren von {len(chunks_to_embed)} Stücken...")
embed_and_index(chunks_to_embed)

print("Pipeline abgeschlossen.")

Neuigkeiten

Wenn Sie dies erfolgreich implementiert haben, sollte Ihr nächster Schritt die Integration von классифицierter retrieval mit den GPT-Completions von OpenAI sein, um ein System zur Generierung, das durch Retrieval unterstützt wird (RAG) zu erstellen, das Antworten aus Ihrer Vektordatenbank bei minimierten Tokenkosten erhält.

Genauer gesagt, konzentrieren Sie sich auf die Kombination Ihrer ChromaDB-Anfragen mit einem Antwortgenerator, der den Kontext intelligent trimmt, wobei idealerweise die Umschreibung der Anfragen angewendet wird, um den Tokenverbrauch bei der Prompt-Engineering zu reduzieren.

FAQ

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

A: Weil die Tokenlimits der Embedding-API in der Regel auf einige tausend Tokens begrenzt sind – zu wenig für große Dokumente – und Sie linear pro Token bezahlen, also verschwenden Sie Geld und erhalten weniger präzise Embeddings, die die Genauigkeit der Retrieval beeinträchtigen.

F: Wie kann ich Dokumente verwalten, die sich häufig mit ChromaDB ändern?

A: Sie sollten delta embeddings implementieren – nur neue oder geänderte, die erneut eingebettet werden. Ein naiver Ansatz besteht darin, den Text jedes Stücks zu hashen und mit den gespeicherten IDs zu vergleichen, um zu wissen, was aktualisiert werden muss.

F: wie kann ich Tokenzählfehler in meiner Anwendung debuggen?

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

Empfehlungen für unterschiedliche Entwicklerprofile

Juniorentwickler: Beginnen Sie damit, die Tokenlimits und die Fragmentierung zu verstehen. Versuchen Sie nicht, alles gleichzeitig zu optimieren. Ihre Priorität sollte es sein, Dokumente in Stücke von ~500 Tokens zu zerlegen und sicherzustellen, dass Ihre API-Aufrufe fehlerfrei funktionieren.

Entwickler mit mittlerem Niveau: Implementieren Sie Caching und Batchverarbeitung später. Verwenden Sie TF-IDF, um auszuwählen, welche Stücke eingebettet werden sollen. Fügen Sie Caching hinzu, um keine Duplikate erneut einzubetten. Zu diesem Zeitpunkt sparen Sie tatsächlich Geld und Zeit.

Senior Engineers: Automatisieren Sie das End-to-End-Token-Tracking. Erstellen Sie Dashboards, die Sie warnen, wenn die Nutzung steigt. Erforschen Sie benutzerdefinierte Splitter, die auf Ihren Dokumenttyp abgestimmt sind. Integrieren Sie Nutzungsmessungen mit Kosten-Dashboards und experimentieren Sie mit der Prompt-Engineering für das Trimming von Kontext.

Daten ab dem 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