SQS-Bestellverarbeitung
Bestellungen aus SQS-Queues werden mit Betrugserkennung, Bestandsprüfung und Concurrency-Keys validiert und abgewickelt. Ergebnisse werden in einer ausgehenden Queue veröffentlicht.
$ connic init my-project \
--templates=sqs-order-processorWas das Template macht
Die Pipeline verarbeitet E-Commerce-Bestellungen aus einer SQS-Queue und übernimmt Validierung sowie Auftragsabwicklung. Der Validator prüft die Vollständigkeit, berechnet Summen unabhängig, kontrolliert den Bestand und markiert Betrugssignale. Bestellungen mit derselben customer_id werden nacheinander verarbeitet, um Duplikate zu verhindern. Middleware weist fehlerhafte Payloads mit StopProcessing ab, bevor das LLM ausgeführt wird. Für genehmigte Bestellungen erzeugt ein deterministischer Tool-Agent Datensätze zur Auftragsabwicklung. Die Ergebnisse werden in einer ausgehenden SQS-Queue veröffentlicht.
- Bestellvalidierung
- Eingehende Bestellungen werden vor der Auftragsabwicklung auf fehlende Felder, Rechenfehler und Betrugssignale geprüft.
- Bestandsmanagement
- Die Validierung prüft den Lagerbestand und lehnt Bestellungen für nicht verfügbare Artikel ab.
- E-Commerce-Backend
- Die Pipeline verarbeitet große Bestellwarteschlangen, steuert die gleichzeitige Ausführung je Kunde und hält feste Zeitlimits ein.
Jede Datei landet in deinem Projekt
connic init kopiert diese Dateien in deine Codebase. Dort änderst du sie wie den Rest deines Codes.
Tool-Agent, der eine Python-Funktion aufruft, ohne Modell-Tokens.
version: "1.0"
name: order-fulfiller
type: tool
description: "Creates a fulfillment record for validated orders - deterministic, no LLM"
tool_name: order_tools.create_fulfillmentFührt seine Agenten nacheinander aus, jeden mit der Ausgabe des vorherigen.
version: "1.0"
name: order-pipeline
type: sequential
description: "Validate order, then create fulfillment record"
agents:
- order-validator
- order-fulfillerLLM-Agent mit Modell, Prompt und Tools.
version: "1.0"
name: order-validator
type: llm
model: connic/gpt-5.6-luna # or gemini/gemini-3.5-flash with Gemini BYOK configured
# Different provider so queued orders keep processing during a primary outage.
fallback_model: anthropic/claude-sonnet-5
description: "Validates incoming orders from SQS for completeness, fraud signals, and business rules"
system_prompt: |
You validate e-commerce orders received from an SQS queue.
If _sqs.approximate_receive_count > 1, this is a retry - the order may have
been partially processed before. Note this in the validation output.
Validation checks:
1. Completeness: all required fields present (customer_id, items, shipping_address,
payment_method). Flag missing fields.
2. Business rules:
- Order total must match sum of (item_price * quantity) + shipping + tax
- Maximum 50 items per order
- Maximum order value: 10,000 (currency units)
- Shipping address must include country, city, postal code
3. Fraud signals:
- Multiple high-value orders from same customer in short period
- Shipping address different from billing address (flag, don't reject)
- Known test card numbers or suspicious patterns
4. Use order_tools.calculate_order_total to independently verify the math.
5. Use order_tools.check_inventory to verify stock availability.
Output a validation result: approved, needs_review, or rejected.
For rejected orders, include specific reasons.
For needs_review, include what needs human attention.
temperature: 0.1
output_schema: order-validation
timeout: 30
concurrency:
key: "customer_id"
on_conflict: queue
tools:
- order_tools.calculate_order_total
- order_tools.check_inventoryPython-Funktionen, die die Agenten als Tools aufrufen.
"""Order processing tools for validation and fulfillment."""
import uuid
import time
import zlib
from typing import Any
def calculate_order_total(
items: list[dict[str, Any]],
shipping_cost: float = 0.0,
tax_rate: float = 0.0,
) -> dict[str, Any]:
"""Calculate the expected order total from line items.
Independently verifies order math so the LLM can detect discrepancies
with the stated total.
Args:
items: List of items, each with "price" and "quantity" keys
shipping_cost: Shipping fee
tax_rate: Tax rate as decimal (e.g. 0.19 for 19%)
Returns:
Dict with subtotal, tax, shipping, and total breakdown
"""
subtotal = sum(
item.get("price", 0) * item.get("quantity", 1)
for item in items
)
tax = round(subtotal * tax_rate, 2)
total = round(subtotal + tax + shipping_cost, 2)
return {
"subtotal": round(subtotal, 2),
"tax": tax,
"shipping": shipping_cost,
"total": total,
"item_count": sum(item.get("quantity", 1) for item in items),
}
def check_inventory(
items: list[dict[str, Any]],
) -> dict[str, Any]:
"""Check inventory availability for all order items.
Args:
items: List of items with "sku" and "quantity" keys
Returns:
Dict with all_available flag and per-item availability
"""
availability = []
all_available = True
for item in items:
sku = item.get("sku", "unknown")
quantity = item.get("quantity", 1)
available = True
# Deterministic per-SKU stock (crc32, not hash() which varies per process).
stock = 50 + zlib.crc32(sku.encode()) % 200
if stock < quantity:
available = False
all_available = False
availability.append({
"sku": sku,
"requested": quantity,
"in_stock": stock,
"available": available,
})
return {
"all_available": all_available,
"items": availability,
}
def create_fulfillment(
payload: dict[str, Any] | None = None,
context: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""Create a fulfillment record for an approved order.
Runs as a tool agent after order-validator, so it receives the validation
result as its payload. Only creates a record if the order was approved;
rejected or needs_review orders are returned with instructions.
Args:
payload: The validation result, with keys: order_id, validation_status
(approved, needs_review, or rejected), items, and shipping_address.
context: Auto-injected run context.
Returns:
Fulfillment record or rejection notice
"""
payload = payload or {}
order_id = payload.get("order_id")
validation_status = payload.get("validation_status")
items = payload.get("items")
shipping_address = payload.get("shipping_address")
if validation_status != "approved":
return {
"fulfilled": False,
"order_id": order_id,
"reason": f"Order status is '{validation_status}', not approved",
"action": "manual_review" if validation_status == "needs_review" else "notify_customer",
}
return {
"fulfilled": True,
"fulfillment_id": str(uuid.uuid4()),
"order_id": order_id,
"status": "pending_shipment",
"items_to_pick": len(items) if items else 0,
"shipping_address": shipping_address,
"created_at": time.time(),
}Läuft vor und nach dem gleichnamigen Agenten.
"""Middleware for order-validator.
Extracts order metadata into context and rejects obviously invalid payloads
before the LLM processes them.
"""
import json
from typing import Any
from connic import StopProcessing
async def before(content: dict[str, Any], context: dict[str, Any]) -> dict[str, Any]:
"""Extract order metadata and reject empty/malformed orders."""
parts = content.get("parts", [])
for part in parts:
if isinstance(part, dict) and "text" in part:
try:
payload = json.loads(part["text"])
if "order_id" not in payload:
raise StopProcessing(
'{"error": "Missing order_id", "status": "rejected"}'
)
context["order_id"] = payload["order_id"]
context["customer_id"] = payload.get("customer_id", "unknown")
items = payload.get("items", [])
if not items:
raise StopProcessing(
'{"error": "Order has no items", "status": "rejected", '
f'"order_id": "{payload["order_id"]}"' + '}'
)
except json.JSONDecodeError:
raise StopProcessing(
'{"error": "Invalid JSON payload", "status": "rejected"}'
)
return content
async def after(response: str, context: dict[str, Any]) -> str:
return responseJSON-Schema für die strukturierte Ausgabe eines Agenten.
{
"type": "object",
"description": "Order validation result",
"properties": {
"order_id": {
"type": "string"
},
"validation_status": {
"type": "string",
"enum": ["approved", "needs_review", "rejected"],
"description": "Overall validation decision"
},
"calculated_total": {
"type": "number",
"description": "Independently calculated order total"
},
"stated_total": {
"type": "number",
"description": "Total claimed in the order"
},
"total_matches": {
"type": "boolean",
"description": "Whether calculated and stated totals match"
},
"inventory_available": {
"type": "boolean",
"description": "Whether all items are in stock"
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {"type": "string", "enum": ["missing_field", "business_rule", "fraud_signal", "inventory"]},
"severity": {"type": "string", "enum": ["info", "warning", "error"]},
"message": {"type": "string"}
},
"required": ["type", "severity", "message"]
},
"description": "Validation issues found"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sku": {"type": "string"},
"quantity": {"type": "integer"},
"price": {"type": "number"}
}
}
},
"shipping_address": {
"type": "object",
"properties": {
"country": {"type": "string"},
"city": {"type": "string"},
"postal_code": {"type": "string"}
}
}
},
"required": ["order_id", "validation_status"]
}1 Testfall für connic test.
version: "1.0"
# End-to-end through the sequential pipeline: validator approves, then the
# order-fulfiller tool agent creates the fulfillment record. The validator's
# tools are mocked (deterministic approval); create_fulfillment is pure and
# runs for real, so the final output is the genuine fulfillment record.
defaults:
runs: 1
timeout_s: 90
mocks: order_mocks
tests:
- name: clean_order_is_fulfilled
payload: '{"order_id": "A200", "customer_id": "c9", "payment_method": "credit_card", "items": [{"sku": "SKU1", "price": 25, "quantity": 1}], "shipping_address": {"country": "DE", "city": "Berlin", "postal_code": "10115"}, "total": 25}'
expected_result: output.fulfilled == true and output.order_id == "A200"3 Testfälle für connic test.
version: "1.0"
# Custom tools mocked so nothing is written and no real inventory service is
# touched. strict_mocks guarantees the validator never reached for a tool we did
# not stub (it only calls custom tools, so this holds).
defaults:
runs: 1
timeout_s: 60
mocks: order_mocks
strict_mocks: true
tests:
- name: approves_clean_order
payload: '{"order_id": "A123", "customer_id": "c1", "payment_method": "credit_card", "items": [{"sku": "SKU1", "price": 10, "quantity": 2}], "shipping_address": {"country": "DE", "city": "Berlin", "postal_code": "10115"}, "total": 20}'
expected_result: output.validation_status == "approved"
expected_tool_calls:
- order_tools.calculate_order_total
- order_tools.check_inventory
- name: flags_total_mismatch
payload: '{"order_id": "A124", "customer_id": "c1", "items": [{"sku": "SKU1", "price": 10, "quantity": 2}], "shipping_address": {"country": "DE", "city": "Berlin", "postal_code": "10115"}, "total": 999}'
expected_result: output.validation_status != "approved"
expected_tool_calls:
- order_tools.calculate_order_total
- name: rejects_empty_order_in_middleware
# The before() middleware short-circuits empty orders before the LLM runs,
# so no validation tools are called.
payload: '{"order_id": "A125", "customer_id": "c1", "items": []}'
expected_result: output.status == "rejected"
expected_no_tool_calls:
- order_tools.calculate_order_total
- order_tools.check_inventoryInstallieren 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 eine eingehende SQS-Verbindung für die Bestell-Queue und eine ausgehende SQS-Verbindung für die Fulfillment-Queue hinzu. Hinterlege für beide AWS-Zugangsdaten. Ein connic/* KI-Modell nutzen oder BYOK-Zugangsdaten unter Projekt Settings → LLM Provider hinterlegen.
Weitere Agent Templates
Browser Automation Demo
Von connicDer Browser-Agent fragt E-Mail-Adresse, Passwort und Projekttitel ab, meldet sich bei connic an und erstellt das Projekt über das Dashboard.
ProduktivitätEinsteigerCompliance-Auditor
Von connicZeitgesteuerte Compliance-Prüfungen werten regulatorische Neuerungen aus der Websuche, per MCP abrufbare Dokumentation und frühere Prüfergebnisse aus dem Retrieval aus. Daraus entstehen Zusammenfassungen mit einer Bewertung.
ComplianceExpertePostgreSQL-Änderungsbenachrichtigung
Von connicLISTEN/NOTIFY überwacht PostgreSQL-Änderungen, klassifiziert Ereignisse nach Auswirkung und leitet Benachrichtigungen an das richtige Team weiter. Änderungen mit hoher Auswirkung werden für Audits gespeichert.
DevOpsFortgeschrittenRecherche-Assistent
Von connicDer Assistent zerlegt komplexe Recherchefragen in Teilaufgaben und startet spezialisierte Agenten parallel. Er führt Informationen aus dem Web und internen Quellen zu strukturierten Berichten zusammen und bewertet die Verlässlichkeit der Ergebnisse.
RechercheExperteRechnungsverarbeitung
Von connicEin 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.
FinanzenEinsteigerVoice-Kundensupport
Von connicEntwickle einen Voice-Agenten, der dein Kundenwissen in connic retrieval durchsucht und mit einem Mock-Tool die Ticketerstellung demonstriert.
KundensupportEinsteiger