Skip to main content
Le skill e gli agenti sono attualmente in fase alfa. La funzionalità funziona ma è ancora in evoluzione.
Le app possono definire capacità di IA che risiedono all’interno dello spazio di lavoro — istruzioni di skill riutilizzabili e agenti con prompt di sistema personalizzati.
Le skill definiscono istruzioni e capacità riutilizzabili che gli agenti IA possono utilizzare all’interno del tuo spazio di lavoro. Usa defineSkill() per definire skill con convalida integrata:
src/skills/example-skill.ts
Punti chiave:
  • name è una stringa identificativa univoca per la skill (kebab-case consigliato).
  • label è il nome di visualizzazione leggibile mostrato nell’UI.
  • content contiene le istruzioni della skill — questo è il testo che l’agente IA utilizza.
  • icon (opzionale) imposta l’icona visualizzata nell’UI.
  • description (opzionale) fornisce contesto aggiuntivo sullo scopo della skill.
Gli agenti sono assistenti IA che vivono all’interno del tuo spazio di lavoro. Usa defineAgent() per creare agenti con un prompt di sistema personalizzato:
src/agents/example-agent.ts
Punti chiave:
  • name è la stringa identificativa univoca dell’agente (kebab-case consigliato).
  • label è il nome visualizzato nell’UI.
  • prompt è il prompt di sistema che definisce il comportamento dell’agente.
  • description (opzionale) fornisce contesto su ciò che fa l’agente.
  • icon (opzionale) imposta l’icona visualizzata nell’UI.
  • modelId (opzionale) sostituisce il modello di IA predefinito utilizzato dall’agente.
  • responseFormat (facoltativo) controlla la forma dell’output dell’agente. Per il testo in formato libero, il valore predefinito è { type: 'text' }. Usa { type: 'json', schema } per forzare un output JSON strutturato.
Per impostazione predefinita, un agente restituisce testo in formato libero. Per ottenere un output strutturato, imposta responseFormat su { type: 'json' } e fornisci uno schema:
src/agents/structured-agent.ts
Note sullo schema:
  • Lo schema è un oggetto piatto: il type di ogni proprietà deve essere un primitivo (string, number o boolean). Gli oggetti annidati e gli array non sono supportati.
  • description (facoltativo) su ogni proprietà guida il modello su cosa inserire lì.
  • required (facoltativo) elenca le proprietà che il modello deve sempre restituire.
  • additionalProperties: false (facoltativo) vieta qualsiasi proprietà non dichiarata in properties.
runAgent() permette a una funzione di logica di eseguire uno degli agenti della tua app (con le sue skill e i suoi strumenti). Identifica l’agente tramite l’universalIdentifier che hai passato a defineAgent(). Passa una stringa prompt oppure una cronologia di conversazione messages, ma non entrambe:
src/logic-functions/run-enricher.ts
Per bot multi-turno (Slack, Discord, Teams, …), passa la cronologia del thread come messages invece di un singolo prompt:
src/logic-functions/reply-in-thread.ts
Punti chiave:
  • Fornisci esattamente uno tra prompt (string) o messages (da 1 a 100 elementi di { role: 'user' | 'assistant', content: string }).
  • L’agente viene eseguito in modo sincrono e può leggere/aggiornare direttamente i record tramite i propri strumenti — runAgent() viene risolta una volta completata l’esecuzione.
  • Un’app può eseguire solo i propri agenti.
  • Il ruolo predefinito dell’app deve concedere il flag di autorizzazione AI — aggiungi SystemPermissionFlag.AI ai suoi permissionFlagUniversalIdentifiers (oppure imposta canAccessAllTools: true). In mancanza di ciò, runAgent() non riesce con un errore di autorizzazione.
  • Imposta un valore generoso per timeoutSeconds sulla funzione di logica — l’esecuzione degli agenti può richiedere diversi secondi.
  • success è true e result è non nullo quando l’esecuzione viene completata; in caso di errore success è false, result è null ed error contiene il motivo (ad esempio, quando lo spazio di lavoro esaurisce i crediti AI durante l’esecuzione).
src/roles/default-role.ts
Evita i loop: se chiami runAgent() da un trigger di evento del database *.updated e l’agente aggiorna lo stesso record, limita il trigger con updatedFields a un campo che l’agente non scrive mai (ad esempio l’URL di origine), oppure controlla che almeno uno dei campi di destinazione sia ancora vuoto prima di chiamare runAgent().

Esecuzione per conto di un membro dello spazio di lavoro

Passa runAsWorkspaceMemberId quando l’esecuzione viene attivata da una persona — ad esempio un chatbot che risponde a un messaggio — in modo che l’agente agisca come quel membro invece che come l’app:
src/logic-functions/answer-question.ts
L’esecuzione quindi agisce con il ruolo proprio del membro: può fare tutto ciò che quel membro può fare e niente di più, i record che crea sono attribuiti a lui e si applicano i suoi permessi a livello di riga. Il ruolo dell’agente non partecipa — è l’impostazione predefinita dell’app per le esecuzioni senza nessuno dietro. Ometti il campo per le esecuzioni autonome (attività pianificate, trigger di eventi del database): queste mantengono il ruolo proprio dell’agente. L’applicazione che agisce rimane collegata al contesto dell’esecuzione per la tracciabilità, senza restringere i permessi del membro.La tua app è responsabile di mappare la persona che ha attivato l’esecuzione a un membro dello spazio di lavoro. Per specificarne uno è necessario un token di accesso dell’app e ciò che un token può specificare dipende dal fatto che sia o meno associato a un utente:
  • Un token senza alcun utente associato può specificare qualsiasi membro. Una funzione logica viene eseguita con uno, e così anche i token generati tramite client_credentials o da una chiave API.
  • Un token emesso per conto di un utente, come quello che riceve un front component, può specificare solo il membro dell’utente stesso.
Qualsiasi altra cosa — una semplice sessione utente, una chiave API senza un token dell’app — non può specificare affatto un membro.
runAgent() genera un errore quando il membro dello spazio di lavoro non può essere risolto — un membro sconosciuto o rimosso, o uno senza ruolo. Non ricorre mai al ruolo proprio dell’agente, poiché ciò concederebbe più accesso di quanto richiesto dal chiamante.