Database Tools
Die integrierte persistente Datenbank speichert Dokumente in benannten Collections. Tools fügen Daten ein, fragen sie mit Filtern ab, aktualisieren und löschen sie. Eigenes Hosting, Migrationen und Einrichtung des Schemas entfallen.
Auf dieser Seite
Database Tools und Retrieval Tools
Connic bietet Agenten zwei Speichersysteme. Sie erfüllen unterschiedliche Aufgaben und werden häufig gemeinsam eingesetzt.
Speichert strukturierte Daten und findet sie anhand exakter Feldwerte. Frage beliebige Felder in beliebigen Collections mit Operatoren wie $gt, $in oder $and ab.
Unterstützt exakte Abfragen, Feldfilter und Zählungen sowie das Erstellen, Aktualisieren und Löschen von Datensätzen.
Speichert Text und findet ihn anhand seiner Bedeutung. Eine Suche nach „Stornierungsregeln“ kann ein Dokument mit dem Titel „Rückgabe- und Erstattungsrichtlinie“ finden.
Sortiert unstrukturierten Text wie Dokumentation, FAQs und Notizen nach Relevanz.
Custom Tool Wrapper
Wrapper-Funktionen können Namen wie save_order und fetch_orders bereitstellen und dabei Collection-Namen sowie Feldzuordnungen fest vorgeben.
from connic.tools import db_insert, db_find, db_update, db_delete, db_count
async def save_order(
order_id: str,
customer_email: str,
product: str,
amount: float,
) -> dict:
"""Save a new order to the database."""
return await db_insert("orders", {
"order_id": order_id,
"customer_email": customer_email,
"product": product,
"amount": amount,
"status": "pending",
})
async def fetch_orders(
customer_email: str | None = None,
status: str | None = None,
limit: int = 20,
) -> list:
"""Fetch orders, optionally filtered by customer or status."""
filter_dict = {}
if customer_email:
filter_dict["customer_email"] = customer_email
if status:
filter_dict["status"] = status
result = await db_find(
"orders",
filter=filter_dict,
sort={"amount": -1},
limit=limit,
)
return result["documents"]
async def update_status(order_id: str, new_status: str) -> dict:
"""Update the status of a specific order."""
return await db_update(
"orders",
filter={"order_id": order_id},
update={"status": new_status},
)
async def cancel_order(order_id: str) -> dict:
"""Cancel a pending order."""
return await db_update(
"orders",
filter={"order_id": order_id, "status": "pending"},
update={"status": "cancelled"},
)Verwende die eigenen Tools im Agent YAML:
version: "1.0"
name: order-processor
model: connic/gpt-5.6-luna
description: "Manages orders using the built-in database"
system_prompt: |
You are an order management assistant. Use your tools to
create, look up, update, and delete orders.
tools:
- order_tools.save_order
- order_tools.fetch_orders
- order_tools.update_status
- order_tools.cancel_orderDirekte Verwendung
Für einfache Agenten oder Prototypen lassen sich die Datenbank-Tools direkt in der YAML deklarieren; der Agent kann die Filter selbst erstellen.
version: "1.0"
name: db-agent
model: connic/gpt-5.6-luna
description: "Works with project database records"
system_prompt: |
Use database tools to read and update project records.
tools:
- db_insert
- db_find
- db_update
- db_upsert
- db_delete
- db_count
- db_list_collectionsTool-Referenz
Parameter
| Parameter | Typ | Default | Beschreibung |
|---|---|---|---|
| collection | str | erforderlich | Name der abzufragenden Collection |
| filter | dict | {} | Filter-Dictionary. Siehe Operatoren unten. |
| sort | dict | None | Sortierreihenfolge. 1 = ASC, -1 = DESC. Verwende das Unterstrichpräfix für Systemfelder, zum Beispiel {"_created_at": -1} |
| limit | int | 100 | Maximale Zahl zurückgegebener Dokumente. Festes Limit: 1000. |
| skip | int | 0 | Zahl der zu überspringenden Dokumente. Wird für die Paginierung verwendet. |
| fields | list | None | Pfade der Felder, die zurückgegeben werden sollen, zum Beispiel ["id", "status", "amount"]. Für vollständige Dokumente weglassen. |
| distinct | str | None | Gibt, falls gesetzt, eindeutige Werte für dieses Feld zurück. sort/limit/skip/fields werden ignoriert. |
Rückgabewert
Ohne distinct: {"documents": [...], "count": N}
Mit distinct: {"values": [...], "count": N}
Jedes Dokument enthält Anwendungsdaten sowie die Systemfelder _id (UUID), _created_at und _updated_at. Systemfelder verwenden beim Lesen, Filtern und Sortieren immer das Unterstrichpräfix.
Beispiele
result = await db_find("orders")
# Returns all orders (up to 100)
result = await db_find("orders", filter={"status": "pending"})
# Returns only pending orders# Sort, paginate, and project
result = await db_find(
"orders",
filter={"amount": {"$gt": 100}},
sort={"amount": -1}, # Highest amount first
limit=20,
skip=40, # Page 3 of 20
fields=["order_id", "customer_email", "amount"],
)
documents = result["documents"]
# Nested field query
result = await db_find("users", filter={"address.city": "Berlin"})
# Multiple conditions
result = await db_find("orders", filter={
"$and": [
{"status": {"$in": ["paid", "shipped"]}},
{"amount": {"$gte": 50}},
]
})
# Distinct values (ignores sort/limit/fields)
result = await db_find("orders", distinct="status")
statuses = result["values"] # ["cancelled", "paid", "pending", "shipped"]Filteroperatoren
Systemfelder haben einen Unterstrich als Präfix: _id (UUID), _created_at, _updated_at. Verwende id (ohne Unterstrich) für ein benutzerdefiniertes Feld in Dokumenten. Verschachtelte Felder verwenden Punktnotation, zum Beispiel address.city.
| Operator | Bedeutung | Beispiel |
|---|---|---|
| {field: value} | Gleichheit (Kurzform) | {"status": "active"} |
| $eq | Gleich | {"amount": {"$eq": 100}} |
| $ne | Ungleich | {"status": {"$ne": "cancelled"}} |
| $gt | Größer als | {"amount": {"$gt": 50}} |
| $gte | Größer als oder gleich | {"priority": {"$gte": 3}} |
| $lt | Kleiner als | {"score": {"$lt": 0.5}} |
| $lte | Kleiner als oder gleich | {"age": {"$lte": 30}} |
| $in | Wert in Liste | {"status": {"$in": ["paid", "shipped"]}} |
| $nin | Wert nicht in Liste | {"status": {"$nin": ["cancelled"]}} |
| $and | Alle Bedingungen erfüllt | {"$and": [{"a": 1}, {"b": 2}]} |
| $or | Mindestens eine Bedingung erfüllt | {"$or": [{"status": "new"}, {"urgent": true}]} |
| $not | Bedingung negieren | {"$not": {"status": "inactive"}} |
| $nor | Keine Bedingung erfüllt | {"$nor": [{"status": "cancelled"}, {"flagged": true}]} |
| $exists: true | Feld vorhanden | {"email": {"$exists": true}} |
| $exists: false | Feld nicht vorhanden | {"phone": {"$exists": false}} |
| $contains | Array enthält Wert | {"tags": {"$contains": "urgent"}} |
| $elemMatch | Array-Element erfüllt Bedingungen | {"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}} |
| $regex | Entspricht Regex (ohne Beachtung der Groß-/Kleinschreibung) | {"name": {"$regex": "^John"}} |
Mehrere Operatoren für ein Feld werden mit AND kombiniert: {"article_id": {"$exists": true, "$nin": [...]}}. Negationsoperatoren ($ne, $nin) finden auch Dokumente, in denen das Feld fehlt. Ergänze "$exists": true, um nur Dokumente mit diesem Feld zu berücksichtigen. $in und $nin vergleichen Werte als Text; verwende deshalb Strings für die Listenwerte. Jede Liste für $in oder $nin akzeptiert höchstens 1.000 Werte.
Parameter
| Parameter | Typ | Default | Beschreibung |
|---|---|---|---|
| collection | str | erforderlich | Collection-Name. Muss mit einem Buchstaben beginnen; nur Kleinbuchstaben, Ziffern und Unterstriche. |
| documents | dict | list[dict] | erforderlich | Ein einzelnes Dokument oder eine Liste von Dokumenten. Jedes Dokument kann beliebige Felder enthalten. |
Rückgabewert
{"inserted": [...], "inserted_count": N}
Jedes eingefügte Dokument der Liste enthält Anwendungsdaten sowie die Systemfelder _id (automatisch generierte UUID), _created_at und _updated_at.
Beispiele
# Insert one document
result = await db_insert("customers", {
"name": "Alice",
"email": "alice@example.com",
"plan": "pro",
})
# result["inserted"][0]["_id"] -> auto-generated UUID
# result["inserted_count"] -> 1# Insert multiple documents at once
result = await db_insert("events", [
{"type": "login", "user": "alice", "ts": "2026-01-01T10:00:00Z"},
{"type": "purchase", "user": "alice", "amount": 49.99},
{"type": "logout", "user": "alice", "ts": "2026-01-01T10:45:00Z"},
])
# result["inserted_count"] -> 3
# Collection is created automatically on first insert
# No setup or schema definition neededupdate-Dictionary wird mit jedem passenden Dokument zusammengeführt. Nicht in update genannte Felder bleiben erhalten.Parameter
| Parameter | Typ | Default | Beschreibung |
|---|---|---|---|
| collection | str | erforderlich | Collection-Name |
| filter | dict | erforderlich | Filter-Dictionary zur Auswahl der zu aktualisierenden Dokumente. Ein leeres Dictionary {} aktualisiert ALLE Dokumente. |
| update | dict | erforderlich | Teildokument mit zu setzenden Feldern. Wird mit vorhandenen Dokumenten zusammengeführt. Setze ein Feld auf null, um es zu entfernen. |
Rückgabewert
{"updated_ids": [...], "updated_count": N}
Beispiele
# Update a specific document
result = await db_update(
"orders",
filter={"order_id": "ORD-001"},
update={"status": "shipped"},
)
# result["updated_count"] -> 1# Update multiple documents at once
result = await db_update(
"orders",
filter={"status": "pending", "amount": {"$gt": 500}},
update={"status": "priority", "flagged": True},
)
# result["updated_ids"] -> ["uuid1", "uuid2", ...]
# result["updated_count"] -> N
# The update dict is MERGED into existing documents
# Fields not mentioned in update are kept as-isFilteroperatoren
Systemfelder haben einen Unterstrich als Präfix: _id (UUID), _created_at, _updated_at. Verwende id (ohne Unterstrich) für ein benutzerdefiniertes Feld in Dokumenten. Verschachtelte Felder verwenden Punktnotation, zum Beispiel address.city.
| Operator | Bedeutung | Beispiel |
|---|---|---|
| {field: value} | Gleichheit (Kurzform) | {"status": "active"} |
| $eq | Gleich | {"amount": {"$eq": 100}} |
| $ne | Ungleich | {"status": {"$ne": "cancelled"}} |
| $gt | Größer als | {"amount": {"$gt": 50}} |
| $gte | Größer als oder gleich | {"priority": {"$gte": 3}} |
| $lt | Kleiner als | {"score": {"$lt": 0.5}} |
| $lte | Kleiner als oder gleich | {"age": {"$lte": 30}} |
| $in | Wert in Liste | {"status": {"$in": ["paid", "shipped"]}} |
| $nin | Wert nicht in Liste | {"status": {"$nin": ["cancelled"]}} |
| $and | Alle Bedingungen erfüllt | {"$and": [{"a": 1}, {"b": 2}]} |
| $or | Mindestens eine Bedingung erfüllt | {"$or": [{"status": "new"}, {"urgent": true}]} |
| $not | Bedingung negieren | {"$not": {"status": "inactive"}} |
| $nor | Keine Bedingung erfüllt | {"$nor": [{"status": "cancelled"}, {"flagged": true}]} |
| $exists: true | Feld vorhanden | {"email": {"$exists": true}} |
| $exists: false | Feld nicht vorhanden | {"phone": {"$exists": false}} |
| $contains | Array enthält Wert | {"tags": {"$contains": "urgent"}} |
| $elemMatch | Array-Element erfüllt Bedingungen | {"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}} |
| $regex | Entspricht Regex (ohne Beachtung der Groß-/Kleinschreibung) | {"name": {"$regex": "^John"}} |
Mehrere Operatoren für ein Feld werden mit AND kombiniert: {"article_id": {"$exists": true, "$nin": [...]}}. Negationsoperatoren ($ne, $nin) finden auch Dokumente, in denen das Feld fehlt. Ergänze "$exists": true, um nur Dokumente mit diesem Feld zu berücksichtigen. $in und $nin vergleichen Werte als Text; verwende deshalb Strings für die Listenwerte. Jede Liste für $in oder $nin akzeptiert höchstens 1.000 Werte.
filter entspricht, oder fügt ein neues ein, wenn kein Dokument passt.Parameter
| Parameter | Typ | Default | Beschreibung |
|---|---|---|---|
| collection | str | erforderlich | Collection-Name. Wird beim ersten Schreibvorgang automatisch erstellt. |
| filter | dict | erforderlich | Nicht leerer Filter zur Identifikation des Zieldokuments, typischerweise ein natürlicher Schlüssel wie {"order_id": "ORD-001"}. Top-Level-Gleichheitsschlüssel werden beim Insert automatisch in das Dokument kopiert; Operator-Konstrukte ($gt, $in, $and, Punktnotation) nicht. |
| update | dict | erforderlich | Felder, die sowohl beim Aktualisieren als auch beim Einfügen verwendet werden. Beim Aktualisieren werden die Werte mit dem vorhandenen Dokument zusammengeführt; null entfernt ein Feld. Beim Einfügen werden Felder mit dem Wert null weggelassen. |
| insert_only | dict | None | Felder, die NUR beim Einfügen eines neuen Dokuments geschrieben werden. Beim Aktualisieren werden sie ignoriert. |
Rückgabewert
{"upserted_id": "<uuid>", "operation": "inserted" | "updated"}
Beispiele
# Create the order, or bump its status if it already exists.
result = await db_upsert(
"orders",
filter={"order_id": "ORD-001"},
update={"status": "shipped"},
)
# result["operation"] -> "inserted" or "updated"
# result["upserted_id"] -> "<uuid>"# insert_only fields apply ONLY when a new document is inserted.
# Use it for "first-seen" metadata that should not get overwritten
# on subsequent calls.
result = await db_upsert(
"user_profiles",
filter={"email": "alice@example.com"},
update={"last_seen_at": "2026-05-12T08:00:00Z"},
insert_only={"source": "signup_form", "created_by": "auth-worker"},
)Filteroperatoren
Systemfelder haben einen Unterstrich als Präfix: _id (UUID), _created_at, _updated_at. Verwende id (ohne Unterstrich) für ein benutzerdefiniertes Feld in Dokumenten. Verschachtelte Felder verwenden Punktnotation, zum Beispiel address.city.
| Operator | Bedeutung | Beispiel |
|---|---|---|
| {field: value} | Gleichheit (Kurzform) | {"status": "active"} |
| $eq | Gleich | {"amount": {"$eq": 100}} |
| $ne | Ungleich | {"status": {"$ne": "cancelled"}} |
| $gt | Größer als | {"amount": {"$gt": 50}} |
| $gte | Größer als oder gleich | {"priority": {"$gte": 3}} |
| $lt | Kleiner als | {"score": {"$lt": 0.5}} |
| $lte | Kleiner als oder gleich | {"age": {"$lte": 30}} |
| $in | Wert in Liste | {"status": {"$in": ["paid", "shipped"]}} |
| $nin | Wert nicht in Liste | {"status": {"$nin": ["cancelled"]}} |
| $and | Alle Bedingungen erfüllt | {"$and": [{"a": 1}, {"b": 2}]} |
| $or | Mindestens eine Bedingung erfüllt | {"$or": [{"status": "new"}, {"urgent": true}]} |
| $not | Bedingung negieren | {"$not": {"status": "inactive"}} |
| $nor | Keine Bedingung erfüllt | {"$nor": [{"status": "cancelled"}, {"flagged": true}]} |
| $exists: true | Feld vorhanden | {"email": {"$exists": true}} |
| $exists: false | Feld nicht vorhanden | {"phone": {"$exists": false}} |
| $contains | Array enthält Wert | {"tags": {"$contains": "urgent"}} |
| $elemMatch | Array-Element erfüllt Bedingungen | {"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}} |
| $regex | Entspricht Regex (ohne Beachtung der Groß-/Kleinschreibung) | {"name": {"$regex": "^John"}} |
Mehrere Operatoren für ein Feld werden mit AND kombiniert: {"article_id": {"$exists": true, "$nin": [...]}}. Negationsoperatoren ($ne, $nin) finden auch Dokumente, in denen das Feld fehlt. Ergänze "$exists": true, um nur Dokumente mit diesem Feld zu berücksichtigen. $in und $nin vergleichen Werte als Text; verwende deshalb Strings für die Listenwerte. Jede Liste für $in oder $nin akzeptiert höchstens 1.000 Werte.
Parameter
| Parameter | Typ | Default | Beschreibung |
|---|---|---|---|
| collection | str | erforderlich | Collection-Name |
| filter | dict | erforderlich | Filter-Dictionary. Darf nicht leer sein. Verwende _id für die System-UUID. Verwende _id mit $exists: true, um alle Dokumente zu löschen. |
Rückgabewert
{"deleted_ids": [...], "deleted_count": N}
Beispiele
# Delete a document by _id (UUID from db_insert/db_find)
result = await db_delete("orders", {"_id": "550e8400-e29b-41d4-a716-446655440000"})
# result["deleted_count"] -> 1
# Delete all documents in a collection
result = await db_delete("orders", {"_id": {"$exists": True}})
# Delete by a data field
result = await db_delete("orders", {"order_id": "ORD-001"})
# Delete with compound filter
result = await db_delete("logs", {
"$and": [
{"status": "archived"},
{"_created_at": {"$lt": "2025-01-01"}},
]
})
# result["deleted_ids"] -> ["uuid1", ...]Filteroperatoren
Systemfelder haben einen Unterstrich als Präfix: _id (UUID), _created_at, _updated_at. Verwende id (ohne Unterstrich) für ein benutzerdefiniertes Feld in Dokumenten. Verschachtelte Felder verwenden Punktnotation, zum Beispiel address.city.
| Operator | Bedeutung | Beispiel |
|---|---|---|
| {field: value} | Gleichheit (Kurzform) | {"status": "active"} |
| $eq | Gleich | {"amount": {"$eq": 100}} |
| $ne | Ungleich | {"status": {"$ne": "cancelled"}} |
| $gt | Größer als | {"amount": {"$gt": 50}} |
| $gte | Größer als oder gleich | {"priority": {"$gte": 3}} |
| $lt | Kleiner als | {"score": {"$lt": 0.5}} |
| $lte | Kleiner als oder gleich | {"age": {"$lte": 30}} |
| $in | Wert in Liste | {"status": {"$in": ["paid", "shipped"]}} |
| $nin | Wert nicht in Liste | {"status": {"$nin": ["cancelled"]}} |
| $and | Alle Bedingungen erfüllt | {"$and": [{"a": 1}, {"b": 2}]} |
| $or | Mindestens eine Bedingung erfüllt | {"$or": [{"status": "new"}, {"urgent": true}]} |
| $not | Bedingung negieren | {"$not": {"status": "inactive"}} |
| $nor | Keine Bedingung erfüllt | {"$nor": [{"status": "cancelled"}, {"flagged": true}]} |
| $exists: true | Feld vorhanden | {"email": {"$exists": true}} |
| $exists: false | Feld nicht vorhanden | {"phone": {"$exists": false}} |
| $contains | Array enthält Wert | {"tags": {"$contains": "urgent"}} |
| $elemMatch | Array-Element erfüllt Bedingungen | {"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}} |
| $regex | Entspricht Regex (ohne Beachtung der Groß-/Kleinschreibung) | {"name": {"$regex": "^John"}} |
Mehrere Operatoren für ein Feld werden mit AND kombiniert: {"article_id": {"$exists": true, "$nin": [...]}}. Negationsoperatoren ($ne, $nin) finden auch Dokumente, in denen das Feld fehlt. Ergänze "$exists": true, um nur Dokumente mit diesem Feld zu berücksichtigen. $in und $nin vergleichen Werte als Text; verwende deshalb Strings für die Listenwerte. Jede Liste für $in oder $nin akzeptiert höchstens 1.000 Werte.
Parameter
| Parameter | Typ | Default | Beschreibung |
|---|---|---|---|
| collection | str | erforderlich | Collection-Name |
| filter | dict | {} | Optionaler Filter. Zählt alle Dokumente, wenn er weggelassen wird. |
Rückgabewert
{"count": N}
Beispiele
# Count all documents
result = await db_count("orders")
total = result["count"]
# Count with filter
result = await db_count("orders", {"status": "active"})
active = result["count"]
# Useful for checking before paginating
result = await db_count("events", {"user": "alice"})
pages = (result["count"] + page_size - 1) // page_sizeFilteroperatoren
Systemfelder haben einen Unterstrich als Präfix: _id (UUID), _created_at, _updated_at. Verwende id (ohne Unterstrich) für ein benutzerdefiniertes Feld in Dokumenten. Verschachtelte Felder verwenden Punktnotation, zum Beispiel address.city.
| Operator | Bedeutung | Beispiel |
|---|---|---|
| {field: value} | Gleichheit (Kurzform) | {"status": "active"} |
| $eq | Gleich | {"amount": {"$eq": 100}} |
| $ne | Ungleich | {"status": {"$ne": "cancelled"}} |
| $gt | Größer als | {"amount": {"$gt": 50}} |
| $gte | Größer als oder gleich | {"priority": {"$gte": 3}} |
| $lt | Kleiner als | {"score": {"$lt": 0.5}} |
| $lte | Kleiner als oder gleich | {"age": {"$lte": 30}} |
| $in | Wert in Liste | {"status": {"$in": ["paid", "shipped"]}} |
| $nin | Wert nicht in Liste | {"status": {"$nin": ["cancelled"]}} |
| $and | Alle Bedingungen erfüllt | {"$and": [{"a": 1}, {"b": 2}]} |
| $or | Mindestens eine Bedingung erfüllt | {"$or": [{"status": "new"}, {"urgent": true}]} |
| $not | Bedingung negieren | {"$not": {"status": "inactive"}} |
| $nor | Keine Bedingung erfüllt | {"$nor": [{"status": "cancelled"}, {"flagged": true}]} |
| $exists: true | Feld vorhanden | {"email": {"$exists": true}} |
| $exists: false | Feld nicht vorhanden | {"phone": {"$exists": false}} |
| $contains | Array enthält Wert | {"tags": {"$contains": "urgent"}} |
| $elemMatch | Array-Element erfüllt Bedingungen | {"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}} |
| $regex | Entspricht Regex (ohne Beachtung der Groß-/Kleinschreibung) | {"name": {"$regex": "^John"}} |
Mehrere Operatoren für ein Feld werden mit AND kombiniert: {"article_id": {"$exists": true, "$nin": [...]}}. Negationsoperatoren ($ne, $nin) finden auch Dokumente, in denen das Feld fehlt. Ergänze "$exists": true, um nur Dokumente mit diesem Feld zu berücksichtigen. $in und $nin vergleichen Werte als Text; verwende deshalb Strings für die Listenwerte. Jede Liste für $in oder $nin akzeptiert höchstens 1.000 Werte.
Rückgabewert
{"collections": [...], "total": N}
Jede Collection enthält name, document_count und size_bytes.
Beispiel
result = await db_list_collections()
for col in result["collections"]:
print(f"{col['name']}: {col['document_count']} docs, {col['size_bytes'] // 1024} KB")
# Result:
# orders: 1543 docs, 200 KB
# customers: 320 docs, 40 KB
# events: 8721 docs, 890 KB