AI Connect/How to create/Automatisierungen und Dienstkonten

Automatisierungen und Dienstkonten

Frag die KI über Vinkius

Sorgen Sie dafür, dass Cron-Jobs, Webhooks, CI-Pipelines und nächtliche Stapelprozesse ihren eigenen AI-Connect-SDK-Benutzer besitzen, Systeme headless mit statischen Zugangsdaten verbinden und mit Isolation und Budget pro Job handeln, ganz ohne Browser. Prozesse werden zu regierten Akteuren, nicht zu stummen Schlüsseln in einer Konfigurationsdatei.

Die wertvollste KI in Ihrem Unternehmen läuft unbeaufsichtigt. Ein nächtlicher Job, der das Hauptbuch abgleicht, ein Webhook, der einen neuen Lead im CRM vorqualifiziert, ein CI-Schritt, der ein Issue bei einer fehlgeschlagenen Bereitstellung öffnet. Bis heute hatte die Infrastruktur für diese Arbeit genau eine Gestalt: ein God-Key in einer Env-Datei, ohne Identität, ohne Messung, ohne Widerruf, und ein Sicherheitsreview, das mit einem Achselzucken endet.

Das AI Connect SDK ersetzt diese Gestalt durch das, was keine Konnektivitätsplattform zuvor angeboten hat: ein Prozess ist ein Benutzer, mit der eigenen external_id, eigenen Connectors, eigenen statischen Anmeldedaten, gestützt auf Tausende KI-Verbindungen ab Tag eins. Geben Sie jeder Automatisierung ihre eigene Identität, verbinden Sie sie einmal und lassen Sie sie dauerhaft Fähigkeiten aufrufen, isoliert, gemessen und auditierbar. Jeder Cron-Job wird zu einem verantwortlichen Mitarbeiter mit eigenem Ausweis, eigenem Budget und eigenem Offboarding. Das ist ein Satz, den Sie bis zu dieser Plattform über kein Integrationsprodukt auf dem Markt schreiben konnten.

Agent loop · one turn
One user turn of the quickstart, exactly as the console serves it. Click a step or press Run.
vinkius.user('alice_123').capabilities({ include: ['github'] })
HTTPGET /apps/vk_app_xxx/users/alice_123/tools?connector=github
const capabilities = await vinkius
  .user('alice_123')
  .capabilities({ include: ['github'] });
CapabilitySet (6)
  github__list_issues        read-only
  github__create_issue       POST /repos/{owner}/{repo}/issues
  github__list_pull_requests read-only
  github__search_code        read-only
  ...
Step 1 of 6
The agent loop, step by step. Press Run and follow one user turn: capabilities load, convert to tools, the model calls github__create_issue, the SDK executes on that user connection and the result feeds back. Every step shows the real SDK call and its HTTP request.
Real systemsledger · CRM · issuescron · nightlyown external_idwebhookown external_idCI pipelineown external_idstatic credentialsfrom your secret managerbrowsernever neededidempotent actions
Processes as users: headless jobs with their own static credentials act on real systems, idempotent and metered, with no browser anywhere.

Was der Ansatz Prozess-als-Benutzer bietet

EigenschaftWarum sie für unbeaufsichtigte Jobs zählt
Headless by designStatische Token-Connectoren (api_key, token) erfordern keinen interaktiven Consent, credentials.set() ist der gesamte Ablauf.
Kein Browser jeEin Cron-Container mit nur fetch und Ihrem Application Key führt das gesamte SDK aus.
Blast-Radius pro JobDie eigene Verbindung jeder Automatisierung bedeutet: ein offengelegter Schlüssel kompromittiert einen Job, nicht die ganze Landschaft.
Unabhängige MessungToken pro Verbindung zeigen genau, was der nächtliche Abgleichjob kostet.
Deterministische WiederholungenEin Idempotency-Schlüssel garantiert, dass ein wiederholter Aufruf genau einmal angewendet wird.

Diese Jobs halten echte Anmeldedaten ohne Menschen im Ablauf. Halten Sie jedes Snippet serverseitig, beziehen Sie statische Token aus Ihrem Secret Manager (niemals aus einem Repository oder einer Modell-Eingabeaufforderung) und geben Sie jeder Automatisierung die kleinste Connector-Menge, mit der sie funktionieren kann.

1. Eine Automatisierung, eine ID, ein Connector-Set

Benennen Sie den Job nach dem, was er tut, und behandeln Sie diesen Namen als den Akteur, dem die Verbindungen gehören.

typescript
const JOB = 'svc-nightly-reconcile'; // stabil, URL-sicher, unter 255 Zeichen, ohne / \ oder Leerzeichen
const JOB_CONNECTORS = ['netsuite', 'stripe', 'sheets'];

2. Provisionieren eines Dienstkontos (einmalig beim Setup)

Dies läuft einmal während des Onboardings, ein Betreiber oder ein Bootstrap-Skript liefert die statischen Token. Danach nutzt der Job die Verbindung nur.

typescript
// scripts/bootstrap-reconcile.ts
import { Vinkius } from '@vinkius/connect';

const vinkius = new Vinkius({
  appId: process.env.VINKIUS_APP_ID!,
  apiKey: process.env.VINKIUS_APP_KEY!, // aus dem Secret Manager
});

async function provision(jobId: string, tokens: Record<string, Record<string, string>>) {
  const user = vinkius.user(jobId);
  await user.ensure({ kind: 'service-account', job: 'nightly-reconcile' });

  for (const [slug, values] of Object.entries(tokens)) {
    const connector = user.connector(slug);
    await connector.connect();                 // holen-oder-erstellen, idempotent
    await connector.credentials.set(values);   // nur schreibbar; z. B. { API_KEY: … }
  }

  return Promise.all(
    Object.keys(tokens).map(async (slug) => ({
      slug,
      status: await user.connector(slug).status(), // erwarten Sie "ready"
    })),
  );
}

await provision('svc-nightly-reconcile', {
  netsuite: await secrets.read('netsuite.reconcile'),
  stripe: await secrets.read('stripe.reconcile'),
  sheets: await secrets.read('sheets.reconcile'),
});

credentials.set() gibt die gespeicherten Werte nie zurück, und status() meldet nur, welche Schlüssel konfiguriert sind. Ein Prozess kann prüfen, dass seine Connectoren bereit sind, ohne jemals das, was er erhalten hat, abfließen lassen zu können, der Anmeldedatensatz ist nutzbar, nicht lesbar.

3. Der unbeaufsichtigte Job selbst

Der geplante Prozess braucht keinen Browser, keinen Consent, keinen anwesenden Benutzer. Er lädt seine Fähigkeiten und handelt.

typescript
// jobs/nightly-reconcile.ts
import { Vinkius } from '@vinkius/connect';

const vinkius = new Vinkius({
  appId: process.env.VINKIUS_APP_ID!,
  apiKey: process.env.VINKIUS_APP_KEY!,
});

async function run() {
  const job = vinkius.user('svc-nightly-reconcile');
  const capabilities = await job.capabilities({ include: ['netsuite', 'stripe'] });

  const fetchOpen = capabilities.findCapability('stripe__list_invoices');
  const postEntry = capabilities.findCapability('netsuite__create_journal_entry');

  if (!fetchOpen || !postEntry) {
    await alertOps('reconcile: Eine Fähigkeit ist nicht verfügbar, ist ein Anmeldedatensatz abgelaufen?');
    return;
  }

  const invoices = await fetchOpen.execute({ status: 'open', limit: 200 });
  if (invoices.isError) throw new Error('stripe-Liste fehlgeschlagen: ' + invoices.content[0]?.text);

  const entry = await postEntry.execute(
    { lines: toJournalLines(invoices) },
    { idempotencyKey: `reconcile:${runDate()}` }, // eine logische Ausführung = ein Buchungssatz
  );
  if (entry.isError) await alertOps('Reconcile-Buchungssatz abgelehnt: ' + entry.content[0]?.text);
}

run().catch(async (error) => {
  await alertOps(`reconcile abgestürzt: ${error.message}`);
});

idempotencyKey ist das Automationsmerkmal. Ein Wiederholungsversuch, ein doppelter Cron-Auslöser, ein Redeploy mitten im Lauf, keiner davon bucht den Buchungssatz ein zweites Mal, denn der Server dedupliziert Wiederholungen mit demselben Schlüssel. Leiten Sie den Schlüssel aus dem Geschäftsereignis ab (das Ausführungsdatum, die Ticket-ID, die Webhook-Zustellungs-ID), niemals von Date.now().

4. Webhooks: ein Akteur, eine Zustellung pro Schlüssel

Für ereignisgesteuerte Automatisierungen behalten Sie üblicherweise einen Dienstkonto-Benutzer, doch jeder mutierende Aufruf wird über die Zustellungs-ID geschlüsselt, damit ein wiederholter Webhook genau einmal angewendet wird.

typescript
// POST /webhooks/lead  (verifiziert)
async function handleLeadWebhook(payload: { id: string; email: string }) {
  const user = vinkius.user('svc-lead-intake');

  if ((await user.connector('hubspot').status()) !== 'ready') {
    await alertOps('lead-intake CRM nicht bereit');
    return;
  }

  const caps = await user.capabilities({ include: ['hubspot'] });
  await caps.findCapability('hubspot__create_contact')?.execute(
    { email: payload.email },
    { idempotencyKey: `lead:${payload.id}` }, // wiederholte Zustellung -> kein Duplikat
  );
}

5. CI-Pipelines und Einmal-Ausführer

Ein CI-Job authentifiziert sich genauso wie ein Cron: derselbe Application Key, eine eigene external_id, statische Anmeldedaten, die in der Umgebung provisioniert werden. Der Unterschied ist die Lebensdauer, Sie rufen disconnect() für flüchtige Ausführer auf, wenn die Pipeline abgebaut wird.

typescript
async function openIssueOnFailedDeploy(runId: string, repo: string) {
  const caps = await vinkius.user('ci-deploy-bot').capabilities({ include: ['github'] });

  await caps.findCapability('github__create_issue')?.execute(
    { owner: 'acme', repo, title: `Deploy ${runId} fehlgeschlagen` },
    { idempotencyKey: `deploy:${runId}` },
  );
}

6. Sauber rotieren und außer Dienst stellen

Weil alles von einer einzigen external_id abhängt, ist das Außerbetriebnehmen einer Automatisierung deterministisch.

typescript
async function decommission(jobId: string) {
  const user = vinkius.user(jobId);
  for (const conn of await user.connectors()) {
    await user.connector(conn.slug).disconnect();
  }
}

Um einen Anmeldedatensatz zu rotieren, rufen Sie credentials.set() erneut mit dem neuen Wert auf, die Verbindung bleibt dieselbe und keine Fähigkeitsreferenz bricht.

Zuverlässigkeit und strukturierte Ausgabe für unbeaufsichtigte Prozesse

Ein unbeaufsichtigter Prozess ist genau dort, wo die eingebaute Robustheit des SDK am meisten zählt. Drei Garantien werden automatisch geerbt:

Automatischer Wiederholungsversuch mit Schutz vor dem Thundering-Herd-Effekt. Idempotente Lesezugriffe (und jeder Schreibzugriff mit einem idempotencyKey) werden automatisch wiederholt: nur bei vorübergehenden 429/502/503/504 und Netzwerkfehlern, mit vollem Jitter-Backoff, der ein Retry-After des Servers beachtet. Ihr Cron braucht keine eigene Wiederholungsschleife.

Idempotenz ist der Sicherheitsmechanismus. In einem Stapeljob sind ein Fehler und ein erneuter Durchlauf üblich. Ein stabiler idempotencyKey beseitigt die Mehrdeutigkeit, ob der erneute Durchlauf die Wirkung dupliziert hat, denn der Server dedupliziert Wiederholungen anhand dieses Schlüssels. Stellen Sie den Schlüssel bei einem mutierenden Aufruf bereit, und das SDK wiederholt selbst ein nicht-idempotentes POST sicher.

Verarbeiten Sie Ergebnisse als Objekte, nicht als Text. Wenn ein Connector strukturierte Daten zurückgibt, liefert result.structuredContent sie bereits geparst, ohne fragiles Text-Extrahieren in der Pipeline:

typescript
const invoices = await fetchOpen.execute({ status: 'open', limit: 200 });
const list = invoices.structuredContent as { invoices: Array<{ id: string; amount: number }> };

const total = list.invoices.reduce((sum, i) => sum + i.amount, 0);

Koppeln Sie lange Stapelläufe an ein angemessenes timeoutMs pro Aufruf und an ein signal, das beim Prozess-Shutdown abgebrochen wird, und der Job endet vorhersagbar während einer schrittweisen Bereitstellung.

Produktions-Checkliste

  • [ ] Geben Sie jeder Automatisierung eine eigene, für Menschen lesbare external_id (kein übergroßes geteiltes Konto).
  • [ ] Beziehen Sie jedes statische Token aus Ihrem Secret Manager; committen Sie es niemals und nehmen Sie es niemals in einen Prompt auf.
  • [ ] Provisionieren Sie einmal beim Setup; Laufzeiten lesen nur status(), sie speichern niemals Secrets neu.
  • [ ] Leiten Sie auf jedem mutierenden Job einen stabilen idempotencyKey aus dem Geschäftsereignis ab.
  • [ ] Warnen Sie bei status() !== 'ready' und isError, damit ein stiller Fehler kein unsichtbarer wird.
  • [ ] Rufen Sie disconnect() für flüchtige Dienstkonten als Teil des Abbaus auf.

Sie haben nun Automatisierungen, die ihre eigene Identität besitzen, echte Systeme headless verbinden und nach Zeitplan oder Ereignis handeln, ohne die gesamte OAuth-Mechanik und ohne die Drift der Frage „Wem gehört dieser Token?", die ein übergroßes geteiltes Konto mit sich bringt. Ihr unbeaufsichtigter Landschaftsteil ist von dem Teil des Systems, über den Audits klagen, zu dem Teil mit der besten Governance-Geschichte geworden, weil jeder Prozess darin endlich einen Namen hat.

What you just got

Not a pitch: the properties this build inherits automatically.

Isolation by construction

Connections and capabilities resolve only inside one external_id. No cross-actor leakage is possible, and you wrote none of that enforcement.

Write-only credentials

Your server stores secrets and can read back which fields are configured, never the values. Not your code, the model, or a dashboard can exfiltrate them.

Metered, revocable spend

Every connection owns a vk_live_* token, so cost and revocation are per connection. One call to disconnect() is a complete, auditable stop.

Any model runtime

One CapabilitySet converts to OpenAI, Anthropic, Gemini, Vercel AI SDK, LangChain, LlamaIndex, Workers AI or neutral JSON Schema. Only the last line changes.

Production safety built in

idempotencyKey, timeoutMs and AbortSignal per call; automatic full-jitter retries on transient failures; typed VinkiusError branches. No bespoke harness.

Headless and deterministic

A cron container with only fetch and your key runs it. An idempotencyKey from the business event makes a re-run a non-event.

Give it to your AI agent

An Agent Skill (SKILL.md) for this build. Preview the first lines below, then copy or download it into your repo under .claude/skills/: Claude Code, Cursor or any Agent-Skills-compatible agent follows it to implement this pattern correctly.

Download SKILL.md6 · Available in your language
What unattended automations inherit, plus the SKILL.md, in your language, for your coding agent.

Nächste Schritte