Zum Hauptinhalt springen
Connic
Build

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.

Zuletzt aktualisiert

Database Tools und Retrieval Tools

Connic bietet Agenten zwei Speichersysteme. Sie erfüllen unterschiedliche Aufgaben und werden häufig gemeinsam eingesetzt.

Database Toolsdiese Seite

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.

Retrieval Toolssiehe Docs

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.

Wrapper-Funktionen können Namen wie save_order und fetch_orders bereitstellen und dabei Collection-Namen sowie Feldzuordnungen fest vorgeben.

tools/order_tools.py
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:

agents/order-processor.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_order

Direkte Verwendung

Für einfache Agenten oder Prototypen lassen sich die Datenbank-Tools direkt in der YAML deklarieren; der Agent kann die Filter selbst erstellen.

agents/db-agent.yaml
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_collections

Tool-Referenz

db_find
Fragt Dokumente mit Filtern aus einer Collection ab. Unterstützt Sortierung, Paginierung, Feldprojektion und das Auflisten eindeutiger Werte.

Parameter

ParameterTypDefaultBeschreibung
collectionstrerforderlichName der abzufragenden Collection
filterdict{}Filter-Dictionary. Siehe Operatoren unten.
sortdictNoneSortierreihenfolge. 1 = ASC, -1 = DESC. Verwende das Unterstrichpräfix für Systemfelder, zum Beispiel {"_created_at": -1}
limitint100Maximale Zahl zurückgegebener Dokumente. Festes Limit: 1000.
skipint0Zahl der zu überspringenden Dokumente. Wird für die Paginierung verwendet.
fieldslistNonePfade der Felder, die zurückgegeben werden sollen, zum Beispiel ["id", "status", "amount"]. Für vollständige Dokumente weglassen.
distinctstrNoneGibt, 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

tools/queries.py
result = await db_find("orders")
# Returns all orders (up to 100)

result = await db_find("orders", filter={"status": "pending"})
# Returns only pending orders
tools/queries.py
# 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.

OperatorBedeutungBeispiel
{field: value}Gleichheit (Kurzform){"status": "active"}
$eqGleich{"amount": {"$eq": 100}}
$neUngleich{"status": {"$ne": "cancelled"}}
$gtGrößer als{"amount": {"$gt": 50}}
$gteGrößer als oder gleich{"priority": {"$gte": 3}}
$ltKleiner als{"score": {"$lt": 0.5}}
$lteKleiner als oder gleich{"age": {"$lte": 30}}
$inWert in Liste{"status": {"$in": ["paid", "shipped"]}}
$ninWert nicht in Liste{"status": {"$nin": ["cancelled"]}}
$andAlle Bedingungen erfüllt{"$and": [{"a": 1}, {"b": 2}]}
$orMindestens eine Bedingung erfüllt{"$or": [{"status": "new"}, {"urgent": true}]}
$notBedingung negieren{"$not": {"status": "inactive"}}
$norKeine Bedingung erfüllt{"$nor": [{"status": "cancelled"}, {"flagged": true}]}
$exists: trueFeld vorhanden{"email": {"$exists": true}}
$exists: falseFeld nicht vorhanden{"phone": {"$exists": false}}
$containsArray enthält Wert{"tags": {"$contains": "urgent"}}
$elemMatchArray-Element erfüllt Bedingungen{"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}}
$regexEntspricht 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.

db_insert
Fügt ein oder mehrere Dokumente in eine Collection ein. Die Collection und das Environment-Schema werden beim ersten Insert automatisch erstellt.

Parameter

ParameterTypDefaultBeschreibung
collectionstrerforderlichCollection-Name. Muss mit einem Buchstaben beginnen; nur Kleinbuchstaben, Ziffern und Unterstriche.
documentsdict | list[dict]erforderlichEin 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

tools/inserts.py
# 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
tools/inserts.py
# 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 needed
db_update
Aktualisiert alle Dokumente, die einem Filter entsprechen. Das update-Dictionary wird mit jedem passenden Dokument zusammengeführt. Nicht in update genannte Felder bleiben erhalten.

Parameter

ParameterTypDefaultBeschreibung
collectionstrerforderlichCollection-Name
filterdicterforderlichFilter-Dictionary zur Auswahl der zu aktualisierenden Dokumente. Ein leeres Dictionary {} aktualisiert ALLE Dokumente.
updatedicterforderlichTeildokument 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

tools/updates.py
# Update a specific document
result = await db_update(
    "orders",
    filter={"order_id": "ORD-001"},
    update={"status": "shipped"},
)
# result["updated_count"] -> 1
tools/updates.py
# 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-is

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.

OperatorBedeutungBeispiel
{field: value}Gleichheit (Kurzform){"status": "active"}
$eqGleich{"amount": {"$eq": 100}}
$neUngleich{"status": {"$ne": "cancelled"}}
$gtGrößer als{"amount": {"$gt": 50}}
$gteGrößer als oder gleich{"priority": {"$gte": 3}}
$ltKleiner als{"score": {"$lt": 0.5}}
$lteKleiner als oder gleich{"age": {"$lte": 30}}
$inWert in Liste{"status": {"$in": ["paid", "shipped"]}}
$ninWert nicht in Liste{"status": {"$nin": ["cancelled"]}}
$andAlle Bedingungen erfüllt{"$and": [{"a": 1}, {"b": 2}]}
$orMindestens eine Bedingung erfüllt{"$or": [{"status": "new"}, {"urgent": true}]}
$notBedingung negieren{"$not": {"status": "inactive"}}
$norKeine Bedingung erfüllt{"$nor": [{"status": "cancelled"}, {"flagged": true}]}
$exists: trueFeld vorhanden{"email": {"$exists": true}}
$exists: falseFeld nicht vorhanden{"phone": {"$exists": false}}
$containsArray enthält Wert{"tags": {"$contains": "urgent"}}
$elemMatchArray-Element erfüllt Bedingungen{"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}}
$regexEntspricht 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.

db_upsert
Aktualisiert das erste Dokument, das filter entspricht, oder fügt ein neues ein, wenn kein Dokument passt.

Parameter

ParameterTypDefaultBeschreibung
collectionstrerforderlichCollection-Name. Wird beim ersten Schreibvorgang automatisch erstellt.
filterdicterforderlichNicht 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.
updatedicterforderlichFelder, 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_onlydictNoneFelder, die NUR beim Einfügen eines neuen Dokuments geschrieben werden. Beim Aktualisieren werden sie ignoriert.

Rückgabewert

{"upserted_id": "<uuid>", "operation": "inserted" | "updated"}

Beispiele

tools/upserts.py
# 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>"
tools/upserts.py
# 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.

OperatorBedeutungBeispiel
{field: value}Gleichheit (Kurzform){"status": "active"}
$eqGleich{"amount": {"$eq": 100}}
$neUngleich{"status": {"$ne": "cancelled"}}
$gtGrößer als{"amount": {"$gt": 50}}
$gteGrößer als oder gleich{"priority": {"$gte": 3}}
$ltKleiner als{"score": {"$lt": 0.5}}
$lteKleiner als oder gleich{"age": {"$lte": 30}}
$inWert in Liste{"status": {"$in": ["paid", "shipped"]}}
$ninWert nicht in Liste{"status": {"$nin": ["cancelled"]}}
$andAlle Bedingungen erfüllt{"$and": [{"a": 1}, {"b": 2}]}
$orMindestens eine Bedingung erfüllt{"$or": [{"status": "new"}, {"urgent": true}]}
$notBedingung negieren{"$not": {"status": "inactive"}}
$norKeine Bedingung erfüllt{"$nor": [{"status": "cancelled"}, {"flagged": true}]}
$exists: trueFeld vorhanden{"email": {"$exists": true}}
$exists: falseFeld nicht vorhanden{"phone": {"$exists": false}}
$containsArray enthält Wert{"tags": {"$contains": "urgent"}}
$elemMatchArray-Element erfüllt Bedingungen{"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}}
$regexEntspricht 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.

db_delete
Löscht alle Dokumente, die einem Filter entsprechen. Ein nicht leerer Filter ist erforderlich, um das versehentliche Löschen einer ganzen Collection zu verhindern.

Parameter

ParameterTypDefaultBeschreibung
collectionstrerforderlichCollection-Name
filterdicterforderlichFilter-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

tools/deletes.py
# 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.

OperatorBedeutungBeispiel
{field: value}Gleichheit (Kurzform){"status": "active"}
$eqGleich{"amount": {"$eq": 100}}
$neUngleich{"status": {"$ne": "cancelled"}}
$gtGrößer als{"amount": {"$gt": 50}}
$gteGrößer als oder gleich{"priority": {"$gte": 3}}
$ltKleiner als{"score": {"$lt": 0.5}}
$lteKleiner als oder gleich{"age": {"$lte": 30}}
$inWert in Liste{"status": {"$in": ["paid", "shipped"]}}
$ninWert nicht in Liste{"status": {"$nin": ["cancelled"]}}
$andAlle Bedingungen erfüllt{"$and": [{"a": 1}, {"b": 2}]}
$orMindestens eine Bedingung erfüllt{"$or": [{"status": "new"}, {"urgent": true}]}
$notBedingung negieren{"$not": {"status": "inactive"}}
$norKeine Bedingung erfüllt{"$nor": [{"status": "cancelled"}, {"flagged": true}]}
$exists: trueFeld vorhanden{"email": {"$exists": true}}
$exists: falseFeld nicht vorhanden{"phone": {"$exists": false}}
$containsArray enthält Wert{"tags": {"$contains": "urgent"}}
$elemMatchArray-Element erfüllt Bedingungen{"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}}
$regexEntspricht 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.

db_count
Zählt Dokumente in einer Collection. Schnell, da keine Dokumente geladen werden.

Parameter

ParameterTypDefaultBeschreibung
collectionstrerforderlichCollection-Name
filterdict{}Optionaler Filter. Zählt alle Dokumente, wenn er weggelassen wird.

Rückgabewert

{"count": N}

Beispiele

tools/counts.py
# 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_size

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.

OperatorBedeutungBeispiel
{field: value}Gleichheit (Kurzform){"status": "active"}
$eqGleich{"amount": {"$eq": 100}}
$neUngleich{"status": {"$ne": "cancelled"}}
$gtGrößer als{"amount": {"$gt": 50}}
$gteGrößer als oder gleich{"priority": {"$gte": 3}}
$ltKleiner als{"score": {"$lt": 0.5}}
$lteKleiner als oder gleich{"age": {"$lte": 30}}
$inWert in Liste{"status": {"$in": ["paid", "shipped"]}}
$ninWert nicht in Liste{"status": {"$nin": ["cancelled"]}}
$andAlle Bedingungen erfüllt{"$and": [{"a": 1}, {"b": 2}]}
$orMindestens eine Bedingung erfüllt{"$or": [{"status": "new"}, {"urgent": true}]}
$notBedingung negieren{"$not": {"status": "inactive"}}
$norKeine Bedingung erfüllt{"$nor": [{"status": "cancelled"}, {"flagged": true}]}
$exists: trueFeld vorhanden{"email": {"$exists": true}}
$exists: falseFeld nicht vorhanden{"phone": {"$exists": false}}
$containsArray enthält Wert{"tags": {"$contains": "urgent"}}
$elemMatchArray-Element erfüllt Bedingungen{"items": {"$elemMatch": {"sku": "A-100", "qty": {"$gte": 2}}}}
$regexEntspricht 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.

db_list_collections
Listet alle Collections im aktuellen Environment mit Dokumentanzahl und Speichergröße auf. Benötigt keine Parameter.

Rückgabewert

{"collections": [...], "total": N}
Jede Collection enthält name, document_count und size_bytes.

Beispiel

tools/collections.py
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