Zum Hauptinhalt springen
Skills und Agenten befinden sich derzeit in der Alpha-Phase. Die Funktion ist funktionsfähig, entwickelt sich jedoch noch weiter.
Apps können KI-Funktionen definieren, die im Arbeitsbereich verfügbar sind — wiederverwendbare Skill-Anweisungen und Agenten mit benutzerdefinierten System-Prompts.
Skills definieren wiederverwendbare Anweisungen und Fähigkeiten, die KI-Agenten in Ihrem Arbeitsbereich verwenden können. Verwenden Sie defineSkill(), um Skills mit eingebauter Validierung zu definieren:
src/skills/example-skill.ts
import { defineSkill } from 'twenty-sdk/define';

export default defineSkill({
  universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
  name: 'sales-outreach',
  label: 'Sales Outreach',
  description: 'Guides the AI agent through a structured sales outreach process',
  icon: 'IconBrain',
  content: `You are a sales outreach assistant. When reaching out to a prospect:
1. Research the company and recent news
2. Identify the prospect's role and likely pain points
3. Draft a personalized message referencing specific details
4. Keep the tone professional but conversational`,
});
Hauptpunkte:
  • name ist eine eindeutige Kennung (als Zeichenfolge) für den Skill (kebab-case empfohlen).
  • label ist der menschenlesbare Anzeigename, der in der UI angezeigt wird.
  • content enthält die Skill-Anweisungen — dies ist der Text, den der KI-Agent verwendet.
  • icon (optional) legt das in der UI angezeigte Symbol fest.
  • description (optional) liefert zusätzlichen Kontext zum Zweck des Skills.
Agenten sind KI-Assistenten, die innerhalb Ihres Arbeitsbereichs leben. Verwenden Sie defineAgent(), um Agenten mit einem benutzerdefinierten System-Prompt zu erstellen:
src/agents/example-agent.ts
import { defineAgent } from 'twenty-sdk/define';

export default defineAgent({
  universalIdentifier: 'b3c4d5e6-f7a8-9012-bcde-f34567890123',
  name: 'sales-assistant',
  label: 'Sales Assistant',
  description: 'Helps the sales team draft outreach emails and research prospects',
  icon: 'IconRobot',
  prompt: 'You are a helpful sales assistant. Help users with their questions and tasks.',
});
Hauptpunkte:
  • name ist eine eindeutige Kennung (als Zeichenfolge) für den Agenten (kebab-case empfohlen).
  • label ist der in der UI angezeigte Anzeigename.
  • prompt ist der System-Prompt, der das Verhalten des Agenten definiert.
  • description (optional) liefert Kontext dazu, was der Agent tut.
  • icon (optional) legt das in der UI angezeigte Symbol fest.
  • modelId (optional) überschreibt das vom Agenten verwendete Standard-KI-Modell.
  • responseFormat (optional) steuert die Form der Ausgabe des Agenten. Standardmäßig ist { type: 'text' } für Freitext. Verwenden Sie { type: 'json', schema }, um eine strukturierte JSON-Ausgabe zu erzwingen.
Standardmäßig gibt ein Agent freien Text zurück. Um eine strukturierte Ausgabe zu erhalten, setzen Sie responseFormat auf { type: 'json' } und geben Sie ein schema an:
src/agents/structured-agent.ts
import { defineAgent } from 'twenty-sdk/define';

export default defineAgent({
  universalIdentifier: 'c4d5e6f7-a8b9-0123-cdef-456789012345',
  name: 'lead-scorer',
  label: 'Lead Scorer',
  prompt: 'Score the lead and explain your reasoning.',
  responseFormat: {
    type: 'json',
    schema: {
      type: 'object',
      properties: {
        score: { type: 'number', description: 'Lead score from 0 to 100' },
        summary: { type: 'string', description: 'Short reasoning for the score' },
      },
      required: ['score', 'summary'],
      additionalProperties: false,
    },
  },
});
Schema-Hinweise:
  • Das Schema ist ein flaches Objekt: Der type jeder Eigenschaft muss ein primitiver Typ sein (string, number oder boolean). Verschachtelte Objekte und Arrays werden nicht unterstützt.
  • description (optional) an jeder Eigenschaft leitet das Modell an, was dort eingetragen werden soll.
  • required (optional) listet die Eigenschaften auf, die das Modell immer zurückgeben muss.
  • additionalProperties: false (optional) verbietet alle Eigenschaften, die nicht in properties deklariert sind.
runAgent() ermöglicht es einer Logikfunktion, einen der Agenten Ihrer App auszuführen (mit seinen Fähigkeiten und Tools). Identifizieren Sie den Agenten über den universalIdentifier, den Sie an defineAgent() übergeben haben:
src/logic-functions/run-enricher.ts
import { runAgent } from 'twenty-sdk/logic-function';

const { result, error, success } = await runAgent({
  agentUniversalIdentifier: 'b3c4d5e6-f7a8-9012-bcde-f34567890123',
  prompt: 'Enrich House Ad <recordId>: fill empty fields from its listing URL.',
});
Hauptpunkte:
  • Der Agent wird synchron ausgeführt und kann selbst Datensätze über seine eigenen Tools lesen/aktualisieren — runAgent() wird aufgelöst, sobald die Ausführung abgeschlossen ist.
  • Eine App kann nur ihre eigenen Agenten ausführen.
  • Die Standardrolle der App muss das Berechtigungsflag AI gewähren — fügen Sie SystemPermissionFlag.AI zu ihren permissionFlagUniversalIdentifiers hinzu (oder setzen Sie canAccessAllTools: true). Ohne dieses Flag schlägt runAgent() mit einem Berechtigungsfehler fehl.
  • Setzen Sie ein großzügiges timeoutSeconds für die Logikfunktion — Agentenläufe können mehrere Sekunden dauern.
  • success ist true und result ist nicht null, wenn der Lauf abgeschlossen ist; bei einem Fehler ist success false, result ist null und error enthält den Grund (zum Beispiel, wenn dem Workspace während des Laufs die AI-Credits ausgehen).
src/roles/default-role.ts
import { defineApplicationRole, SystemPermissionFlag } from 'twenty-sdk/define';

export default defineApplicationRole({
  universalIdentifier: 'b648f87b-1d26-4961-b974-0908fd991061',
  label: 'Default function role',
  // runAgent() requires the AI permission flag on the app's default role.
  permissionFlagUniversalIdentifiers: [SystemPermissionFlag.AI],
});
Vermeiden Sie Schleifen: Wenn Sie runAgent() von einem *.updated-Datenbankereignis-Trigger aus aufrufen und der Agent denselben Datensatz aktualisiert, schränken Sie den Trigger mit updatedFields auf ein Feld ein, das der Agent niemals beschreibt (z. B. die Quell-URL), oder prüfen Sie, ob eines der Zielfelder noch leer ist, bevor Sie runAgent() aufrufen.