KI-Agenten in YAML.
Tools in Python.
Jeder Agent ist eine Datei mit KI-Modell, Prompt, Tools und Guardrails. Tools sind normale Python-Funktionen, und ihre Type Hints liefern das Schema für das Modell.
name: invoice-processor
model: connic/gpt-5.6-sol
system_prompt: |
Extract every field from the invoice
and check that the totals add up.
tools:
- invoices.parse_pdf
- invoices.extract_fields # tools/invoices.py
- invoices.save_invoice
output_schema: invoicedef extract_fields(text: str, currency: str = "EUR") -> dict:
"""Pull vendor, line items and totals from invoice text.
Args:
text: Plain text returned by parse_pdf
currency: Used when the invoice names no currency
"""
return read_invoice(text, default_currency=currency)Jede Erweiterung ist eine Datei neben dem Agenten.
Gib einer Middleware- oder Hook-Datei den Namen des Agenten, und connic lädt sie automatisch. Registrieren musst du nichts.
Läuft vor und nach jedem Run. Damit lädst du Daten aus deinen Systemen, hängst Dateien an oder loggst das Ergebnis.
from typing import Any, Dict
import httpx
async def before(content: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
"""Give the agent the customer's booking rules before it reads the invoice."""
customer_id = context.get("payload", {}).get("customer_id")
async with httpx.AsyncClient() as client:
resp = await client.get(f"https://erp.example.com/customers/{customer_id}/rules")
content["parts"].insert(0, {"text": f"Booking rules: {resp.text}"})
return content
async def after(response: str, context: Dict[str, Any]) -> str:
print(f"Run {context.get('run_id')} finished")
return responseLäuft um jeden Tool-Aufruf. Damit änderst du Parameter, schwärzt Ergebnisse oder stoppst einen Aufruf mit AbortTool.
import re
from typing import Any
from connic import AbortTool
IBAN = re.compile(r"\b[A-Z]{2}\d{2}[A-Z0-9]{11,30}\b")
async def before(tool_name: str, params: dict[str, Any]) -> dict[str, Any]:
if tool_name == "save_invoice" and params.get("total", 0) > 50_000:
raise AbortTool({"error": "Totals above 50,000 need a manual booking."})
return params
async def after(tool_name: str, params: dict[str, Any], result: Any) -> Any:
if tool_name == "parse_pdf":
result["text"] = IBAN.sub("[IBAN]", result["text"])
return resultDeine eigene Prüfung in Python. Sie steht in der Agentendatei neben den integrierten Guardrails.
import json
from connic import GuardrailResult
def check(content: str, context: dict) -> GuardrailResult:
"""Block answers whose line items do not add up to the total."""
invoice = json.loads(content)
line_sum = sum(line["amount"] for line in invoice["lines"])
if abs(line_sum - invoice["total"]) > 0.01:
return GuardrailResult(
passed=False,
message="Line items do not match the total.",
)
return GuardrailResult(passed=True)Das JSON Schema, an das sich jede finale Antwort halten muss.
{
"type": "object",
"description": "Extracted invoice data",
"properties": {
"vendor": { "type": "string" },
"invoice_date": { "type": "string", "description": "YYYY-MM-DD" },
"currency": { "type": "string" },
"lines": {
"type": "array",
"items": {
"type": "object",
"properties": {
"description": { "type": "string" },
"amount": { "type": "number" }
},
"required": ["description", "amount"]
}
},
"total": { "type": "number" }
},
"required": ["vendor", "lines", "total"]
}Payloads, Dateien und Assertions. connic test führt sie aus, und Deployments können sie voraussetzen.
version: "1.0"
tests:
- name: extracts_totals
payload: "Extract this invoice"
files:
- invoice_acme.pdf
expected_tool_calls:
- invoices.extract_fields
expected_result: output.total == 1249.5
- name: reads_currency
payload: "Extract this invoice"
files:
- invoice_globex_chf.pdf
expected_result: output.currency == "CHF"Vom leeren Ordner in die Produktivumgebung. Alles im Terminal.
connic dev lädt jede gespeicherte Änderung in ein isoliertes Dev Environment, und schon der nächste Run nutzt sie.
Git brauchst du nicht: connic deploy lädt den Projektordner hoch. Mit verbundenem Git reicht ein Push auf den Branch des Environments.
Jede Änderung am Verhalten ist ein Diff.
Ein neues KI-Modell, ein weiteres Tool, eine strengere Guardrail: Alles sind Dateiänderungen, und dein Team sieht sie im Review.
- Feste Modell-IDs
- Das genaue Modell steht im YAML. Es ändert sich nur, wenn jemand diese Zeile bearbeitet.
- Erst testen, dann aktivieren
- Liegen Suites in tests/, geht ein Deployment erst live, wenn jeder Testfall besteht.
- Rollback ohne neuen Build
- Aktivier ein früheres erfolgreiches Deployment im Dashboard, und es nimmt wieder Anfragen an.
Mit einem Befehl von LangChain oder Google ADK umsteigen.
connic migrate macht aus einem LangChain-, LangGraph- oder ADK-Projekt Agenten in YAML und Tools in Python. Was sich nicht umwandeln ließ, steht in MIGRATION_REPORT.md.
$ connic migrate --source ./support-bot --dest ./support-bot-connic → Scanning source project... ✓ Framework: langchain ✓ Agents found: 3 ✓ Tools found: 11 → Generating connic project... ✓ Generated at support-bot-connic → Running connic lint on the migrated project... Report: support-bot-connic/MIGRATION_REPORT.md ✓ Migration complete.