Zum Hauptinhalt springen
connic

Rechnungsverarbeitung

Von connic
FinanzenEinsteiger

Ein KI-Agent extrahiert strukturierte Daten aus Rechnungen. Ein deterministischer Tool-Agent validiert Summen und erzeugt prüfbare JSON-Ergebnisse. Bei Fehlern sind Wiederholungsversuche möglich.

Mit der CLI installieren
$ connic init my-project \
  --templates=invoice
Publisher
Von connic
Schwierigkeitsgrad
Einsteiger
Funktioniert mit
HTTP Webhook, AWS S3, E-Mail
Quelle
GitHub

Was das Template macht

Eine sequenzielle Pipeline extrahiert mithilfe eines LLM-Agenten mit Rechenwerkzeugen strukturierte Daten aus unaufbereitetem Rechnungstext oder Bildern. Anschließend validiert ein deterministischer Tool-Agent die Summen ohne Token-Kosten. Middleware ergänzt Audit-Trails mit Request-IDs und Kosten-Tracking. Die Pipeline unterstützt Retries bei vorübergehenden Fehlern.

Architektur
Webhook / S3 / E-Mail
invoice-pipeline
invoice-extractor
invoice-validator
Automatisierung der Kreditorenbuchhaltung
Die Pipeline verarbeitet eingehende Lieferantenrechnungen, extrahiert Positionen und Summen und validiert sie vor der Buchung im ERP.
Belegerfassung
Belege aus Fotos oder PDFs werden in strukturierte Daten für Spesenabrechnungen und Abstimmungen umgewandelt.
Rechnungsprüfung
Die Pipeline prüft jede Rechnung auf Abweichungen zwischen angegebenen und berechneten Summen und protokolliert jeden Schritt im Audit Trail.

Jede Datei landet in deinem Projekt

connic init kopiert diese Dateien in deine Codebase. Dort änderst du sie wie den Rest deines Codes.

agents/invoice/
tools/
middleware/
schemas/
tests/
agents/invoice/invoice-extractor.yaml

LLM-Agent mit Modell, Prompt und Tools.

version: "1.0"

name: invoice-extractor
type: llm
model: connic/gemini-3.7-flash
description: "Extracts structured line items, totals, and metadata from raw invoice text or images"

system_prompt: |
  You are a senior accountant processing invoices. Your job is to extract every
  billable detail from the provided invoice into a clean, machine-readable format.

  Extraction rules:
  - Identify the vendor name, invoice number, issue date, and due date.
  - Extract every line item with description, quantity, unit price, and line total.
  - Use the calculator tools to independently verify that line items sum to the
    stated subtotal and that tax is applied correctly.
  - If the invoice contains multiple tax rates, break them out separately.
  - Flag discrepancies between your calculated totals and the stated totals.
  - For multi-page invoices, ensure no line items are missed.
  - Currency should be the ISO 4217 code (EUR, USD, GBP, etc.).

  When calculations don't match, still output the vendor-stated values but set
  the "discrepancy" field to true with an explanation.

temperature: 0.1
output_schema: invoice
timeout: 45

retry_options:
  attempts: 5
  max_delay: 60

tools:
  - invoice_tools.add
  - invoice_tools.multiply
  - invoice_tools.calculate_tax
agents/invoice/invoice-pipeline.yaml

Führt seine Agenten nacheinander aus, jeden mit der Ausgabe des vorherigen.

version: "1.0"

name: invoice-pipeline
type: sequential
description: "Extract structured invoice data, then validate totals automatically"

agents:
  - invoice-extractor
  - invoice-validator
agents/invoice/invoice-validator.yaml

Tool-Agent, der eine Python-Funktion aufruft, ohne Modell-Tokens.

version: "1.0"

name: invoice-validator
type: tool
description: "Deterministic validation of invoice math without LLM - zero token cost"
tool_name: invoice_tools.validate_totals
tools/invoice_tools.py

Python-Funktionen, die die Agenten als Tools aufrufen.

"""Invoice processing tools for extraction and validation."""

from typing import Any


def add(a: float, b: float) -> float:
    """Add two numbers together.

    Args:
        a: The first number
        b: The second number

    Returns:
        The sum of a and b
    """
    return a + b


def multiply(a: float, b: float) -> float:
    """Multiply two numbers.

    Args:
        a: The first number
        b: The second number

    Returns:
        The product of a and b
    """
    return a * b


def calculate_tax(amount: float, rate: float = 0.19) -> dict[str, float]:
    """Calculate tax for a given amount.

    Args:
        amount: The base amount to calculate tax on
        rate: The tax rate as a decimal (default: 0.19 for 19% VAT)

    Returns:
        Dict with net, tax, and gross amounts
    """
    tax = round(amount * rate, 2)
    return {"net": amount, "tax": tax, "gross": round(amount + tax, 2)}


def validate_totals(
    payload: dict[str, Any] | None = None,
    context: dict[str, Any] | None = None,
) -> dict[str, Any]:
    """Validate that invoice totals are mathematically correct.

    Runs as a tool agent after invoice-extractor, so it receives the extracted
    invoice as its payload.

    Args:
        payload: The extracted invoice, with keys: subtotal, tax_amount, total,
            and optional tax_rate (default 0.19) and tolerance (default 0.02).
        context: Auto-injected run context.

    Returns:
        Dict with valid (bool), checks performed, and any discrepancies
    """
    payload = payload or {}
    subtotal = payload.get("subtotal", 0.0)
    tax_amount = payload.get("tax_amount", 0.0)
    total = payload.get("total", 0.0)
    tax_rate = payload.get("tax_rate", 0.19)
    tolerance = payload.get("tolerance", 0.02)

    expected_tax = round(subtotal * tax_rate, 2)
    expected_total = round(subtotal + expected_tax, 2)

    tax_ok = abs(tax_amount - expected_tax) <= tolerance
    total_ok = abs(total - expected_total) <= tolerance
    line_total_ok = abs(total - (subtotal + tax_amount)) <= tolerance

    checks = {
        "tax_matches_rate": tax_ok,
        "total_matches_calculation": total_ok,
        "line_total_consistent": line_total_ok,
    }

    if all(checks.values()):
        return {"valid": True, "checks": checks, "message": "All totals verified"}

    discrepancies = []
    if not tax_ok:
        discrepancies.append(
            f"Tax: expected {expected_tax} at {tax_rate*100}%, got {tax_amount}"
        )
    if not total_ok:
        discrepancies.append(
            f"Total: expected {expected_total}, got {total}"
        )
    if not line_total_ok:
        discrepancies.append(
            f"Subtotal + tax ({subtotal + tax_amount}) != total ({total})"
        )

    return {"valid": False, "checks": checks, "discrepancies": discrepancies}
middleware/invoice-extractor.py

Läuft vor und nach dem gleichnamigen Agenten.

"""Middleware for the invoice-extractor agent.

Adds audit metadata and enforces basic input validation.
"""

import uuid
from typing import Any


async def before(content: dict[str, Any], context: dict[str, Any]) -> dict[str, Any]:
    """Attach a unique request ID and audit timestamp for traceability."""
    context["request_id"] = str(uuid.uuid4())
    context["source"] = "invoice-pipeline"
    return content


async def after(response: str, context: dict[str, Any]) -> str:
    """Log extraction cost for billing reconciliation."""
    token_usage = context.get("token_usage", {})
    duration = context.get("duration_ms", 0)
    context["audit_log"] = {
        "request_id": context.get("request_id"),
        "tokens_used": token_usage.get("output_tokens", 0) + token_usage.get("input_tokens", 0),
        "duration_ms": duration,
    }
    return response
schemas/invoice.json

JSON-Schema für die strukturierte Ausgabe eines Agenten.

{
  "type": "object",
  "description": "Structured invoice extraction result",
  "properties": {
    "vendor": {
      "type": "string",
      "description": "Vendor or company name"
    },
    "invoice_number": {
      "type": "string",
      "description": "Invoice reference number"
    },
    "issue_date": {
      "type": "string",
      "description": "Invoice date (YYYY-MM-DD)"
    },
    "due_date": {
      "type": "string",
      "description": "Payment due date (YYYY-MM-DD)"
    },
    "currency": {
      "type": "string",
      "description": "ISO 4217 currency code"
    },
    "line_items": {
      "type": "array",
      "description": "Itemized charges",
      "items": {
        "type": "object",
        "properties": {
          "description": {"type": "string"},
          "quantity": {"type": "number"},
          "unit_price": {"type": "number"},
          "amount": {"type": "number"}
        },
        "required": ["description", "amount"]
      }
    },
    "subtotal": {
      "type": "number",
      "description": "Sum of line items before tax"
    },
    "tax_rate": {
      "type": "number",
      "description": "Tax rate as decimal (e.g. 0.19)"
    },
    "tax_amount": {
      "type": "number",
      "description": "Total tax charged"
    },
    "total": {
      "type": "number",
      "description": "Grand total including tax"
    },
    "discrepancy": {
      "type": "boolean",
      "description": "True if calculated totals don't match stated totals"
    },
    "discrepancy_note": {
      "type": "string",
      "description": "Explanation of any calculation mismatches"
    }
  },
  "required": ["vendor", "total", "currency", "line_items"]
}
tests/invoice-extractor.yaml

2 Testfälle für connic test.

version: "1.0"

# The calculator tools (add, multiply, calculate_tax) are pure math with no
# side effects, so they run for real and deterministically - no mocks needed.
defaults:
  runs: 1
  timeout_s: 90

tests:
  - name: extracts_single_line_invoice
    payload: '{"text":"Invoice from Acme GmbH. Number INV-001. 3 widgets at 10.00 EUR each. VAT 19%. Total 35.70 EUR. Verify the tax with the calculator tools."}'
    expected_result: output.total > 0 and output.vendor != ""
    expected_tool_calls:
      - invoice_tools.calculate_tax

  - name: extracts_multi_line_invoice
    payload: '{"text":"Invoice from Globex Ltd. Number INV-002. Line 1: 2 chairs at 50.00 EUR each. Line 2: 4 lamps at 12.50 EUR each. VAT 19%. Verify each line total and the tax using the calculator tools."}'
    expected_result: output.total > 0 and output.vendor != ""
    expected_tool_calls:
      - invoice_tools.multiply
      - invoice_tools.add
tests/invoice-pipeline.yaml

1 Testfall für connic test.

version: "1.0"

# End-to-end through the sequential pipeline: the extractor pulls structured
# numbers from the invoice text, then the validator tool agent runs a pure-math
# pass on them. Both the calculator tools and validate_totals are deterministic
# and run for real - no mocks needed.
defaults:
  runs: 1
  timeout_s: 120

tests:
  - name: consistent_invoice_validates
    payload: '{"text":"Invoice from Acme GmbH. Number INV-001. 3 widgets at 10.00 EUR each. Subtotal 30.00 EUR. VAT 19% = 5.70 EUR. Total 35.70 EUR."}'
    expected_result: output.valid == true

Installieren und bereitstellen

Installiere das Template, erstelle ein connic-Projekt und starte das Deployment über ein verbundenes Git-Repository oder die CLI.

Voraussetzungen
  • Python 3.10+
  • Ein connic-Konto mit einem angelegten Projekt
  • Projektguthaben für ein connic/* KI-Modell oder Zugangsdaten für einen BYOK Provider
Deployment mit Git
Verbinde das Repository unter Projekt Settings → Git & Environments, ordne einen Branch einem Environment zu und pushe.
Deployment mit der CLI
Erstelle unter Projekt Settings → API Keys & MCP Auth einen API Key, führe im Projektordner connic login aus und danach connic deploy. Änderungen probierst du vorher mit connic dev und connic test aus.
Verbinden und konfigurieren
Füge für die Rechnungsverarbeitung in Echtzeit eine synchrone HTTP-Webhook-Verbindung hinzu. Sende die Rechnungsdaten per POST an die Webhook-URL und erhalte das strukturierte Extraktionsergebnis als Antwort. Ein connic/* KI-Modell nutzen oder BYOK-Zugangsdaten unter Projekt Settings → LLM Provider hinterlegen.
~/my-project
SDK
$ pip install connic-composer-sdk
Projekt
$ connic init my-project --templates=invoice
connic Init
──────────────────────────────
→ Created directory: my-project
→ Creating project structure...
✓ agents/, tools/, middleware/, schemas/
→ Fetching templates from connic-awesome-agents...
✓ Fetched
→ Merging templates...
✓ Added template: invoice
→ Next steps:
1. Run `connic lint` to validate your project
2. Run `connic dev` to choose a dev environment with hot reload
3. Run `connic deploy` when ready
✓ Initialized with templates: invoice
Deploy
$ connic deploy
→ Validating project files...
✓ Lint passed: 3 agent(s) validated (invoice-extractor, invoice-validator, invoice-pipeline)
✓ Lint passed
✓ Deployment created.

Weitere Agent Templates

Zum Marketplace