Guida passo-passo: aggiungere funzioni AI personalizzate all’AI agent di ONLYOFFICE

20 agosto 2025Da Alice

Con il nostro nuovo agente AI intelligente, offriamo strumenti all’avanguardia per rispondere alle esigenze del mondo digitale frenetico di oggi. Essendo un progetto open source, accogliamo con piacere l’innovazione guidata dagli utenti. In questo post ti mostreremo come aggiungere funzioni personalizzate all’agente AI, rendendo il tuo lavoro con i documenti più veloce, semplice e comodo.

Step-by-step guide: adding custom AI functions to ONLYOFFICE AI agent

Cosa sono le funzioni AI e a cosa servono?

Le funzioni AI sono i mattoni fondamentali della funzionalità di un agente AI. In sostanza, sono istruzioni che dicono all’agente AI:

  • Quale richiesta inviare al modello AI.
  • Quali manipolazioni eseguire sul tuo documento.

Usando le funzioni AI, puoi estendere e controllare il modo in cui l’AI interagisce con il contenuto del tuo documento.

Come usare una funzione AI

  1. Aggiungi un modello a tua scelta al plugin AI.
  2. Apri la finestra di dialogo dell’agente AI premendo CTRL + /.
  3. Inserisci il tuo prompt e premi Invio.

Esempio: la funzione commentText

La funzione commentText ti permette di aggiungere commenti generati dall’AI direttamente al tuo documento. Ecco come funziona:

  • Seleziona una parola su cui vuoi lasciare un commento
  • Apri la finestra di dialogo dell’agente AI (CTRL + /).
  • Scrivi la tua istruzione, ad esempio: “Spiega questo testo.”
  • Premi Invio.

Step-by-step guide: adding custom AI functions to ONLYOFFICE AI agent

L’agente AI eseguirà la funzione commentText e inserirà i commenti pertinenti nel tuo documento:

Step-by-step guide: adding custom AI functions to ONLYOFFICE AI agent

Perché aggiungere funzioni personalizzate al tuo agente AI?

Aggiungere funzioni AI personalizzate ti consente di ampliare le capacità dell’agente intelligente e adattarlo esattamente alle tue esigenze. Che tu stia lavorando con documenti, fogli di calcolo o presentazioni, la versatilità dell’agente, unita alla potenza dei moderni modelli AI, ti aiuta a trasformare le idee in realtà e a integrarle senza problemi nel tuo flusso di lavoro.

Logica generale dell’aggiunta di una funzione AI personalizzata

Il processo di aggiunta di una funzione personalizzata prevede due fasi principali:

  • Registrazione della funzione – Registra la funzione AI e i suoi metadati all’interno dell’ambiente dell’agente.
  • Esecuzione della funzione – Implementa la logica principale, che include l’invio di richieste al modello AI e la manipolazione del contenuto del documento tramite la nostra Office API.

Ora diamo un’occhiata più da vicino a queste fasi.

Registrazione della funzione

Per aggiungere una nuova funzione implementiamo l’oggetto RegisteredFunction. Questo ci permette di aggiungere metadati e logica. Ecco un esempio di aggiunta della funzione commentText per l’editor di documenti:

let func = new RegisteredFunction();
        func.name = "commentText";
        func.params = [
            "type (string): whether to add as a 'comment' or as a 'footnote'    default is 'comment')"
        ];


        func.examples = [
            "If you need to explain selected text as a comment, respond with:\n" +
            "[functionCalling (commentText)]: {\"prompt\" : \"Explain this text\", \"type\": \"comment\"}",


            "If you need to add a footnote to selected text, respond with:\n" +
            "[functionCalling (commentText)]: {\"prompt\" : \"Add a footnote to this text\", \"type\": \"footnote\"}",


            "If you need to comment selected text, respond with:\n" +
            "[functionCalling (commentText)]: {\"prompt\" : \"Comment this text\"}",


            "If you need to explain selected text as a footnote, respond with:\n" +
            "[functionCalling (commentText)]: {\"prompt\" : \"Explain this text\", \"type\": \"footnote\"}"
     ]

Dove:

  • func.name: il nome che l’AI userà per chiamare questa funzione (ad es. “commentText”).
  • func.params: un elenco di parametri che la funzione si aspetta dall’AI. Ad esempio:

prompt (string): una descrizione o istruzione per il commento.

type (string): “comment” o “footnote” — specifica cosa inserire.

  • func.examples: esempi di chiamate corrette della funzione per l’AI.
  • func.description: spiega all’AI a cosa serve la funzione.

Questi parametri vengono utilizzati dall’AI. L’oggetto RegisteredFunction() è definito nel file helperFunc.js.

Logica di esecuzione della funzione

Dopo aver registrato la funzione implementiamo la logica effettiva che viene eseguita quando l’AI richiama questa funzione.

  • Recuperiamo il testo selezionato usando Asc.Editor.callCommand().
func.call = async function(params) {
            let type = params.type;
            let isFootnote = "footnote" === type;


// Executes a block of code inside the editor's context using the office=js API.
            let text = await Asc.Editor.callCommand(function(){
                let doc = Api.GetDocument();
// Gets the current selected text range.
                let range = doc.GetRangeBySelect();
                let text = range ? range.GetText() : "";
                if (!text)
                {
                    text = doc.GetCurrentWord();
// Selects the current word so comments can be applied to it.
                    doc.SelectCurrentWord();
                }


                return text;
            });
  • Costruiamo il prompt per l’AI combinando params.prompt e il testo selezionato.
let argPromt = params.prompt + ":\n" + text;
  • Inizializziamo l’oggetto AI.Request.create usando AI.Request.create. L’oggetto è definito nel file engine.js. Questo oggetto semplifica l’invio di una richiesta al modello AI.
// Initializes a request engine for communicating with the AI model (e.g. Chat, Translation).
            let requestEngine = AI.Request.create(AI.ActionType.Chat);
            if (!requestEngine)
                return;
  • Inviamo la richiesta usando chatRequest() e riceviamo il risultato in un callback.
// Sends a prompt to the AI model and processes the response via callback. Can stream or wait.
                let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
                    if (!data)
                        return;
  • Inseririamo la risposta come commento o nota a piè di pagina usando AddFootnote() o AddComment()

Implementazione di AddFootnote:

if (isFootnote)
            {
                let addFootnote = true;
// Sends a prompt to the AI model and processes the response via callback. Can stream or wait.
                let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
                    if (!data)
                        return;


// Marks the end of a logical group or block action in the editor.
                    await checkEndAction();
                    Asc.scope.data = data;
                    Asc.scope.model = requestEngine.modelUI.name;


                    if (addFootnote)
                    {
// Executes a block of code inside the editor's context using the document model API.
                        await Asc.Editor.callCommand(function(){
// Returns the main document object, which gives access to all editing, structure, and selection APIs.
                            Api.GetDocument().AddFootnote();
                        });
                        addFootnote = false;
                    }
// Inserts the AI-generated result into the document at the current selection or cursor.
                    await Asc.Library.PasteText(data);
                });

Implementazione AddComment:

let commentId = null;
// Sends a prompt to the AI model and processes the response via callback. Can stream or wait.
                let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
                    if (!data)
                        return;


// Marks the end of a logical group or block action in the editor.
                    await checkEndAction();
                    Asc.scope.data = data;
                    Asc.scope.model = requestEngine.modelUI.name;
                    Asc.scope.commentId = commentId;


// Executes a block of code inside the editor's context using the document model API.
                    commentId = await Asc.Editor.callCommand(function(){
// Returns the main document object, which gives access to all editing, structure, and selection APIs.
                        let doc = Api.GetDocument();


                        let commentId = Asc.scope.commentId;
                        if (!commentId)
                        {
// Gets the current selected text range, which can be modified or annotated.
                            let range = doc.GetRangeBySelect();
                            if (!range)
                                return null;


                            let comment = range.AddComment(Asc.scope.data, Asc.scope.model, "uid" + Asc.scope.model);
                            if (!comment)
                                return null;
                            doc.ShowComment([comment.GetId()]);
                            return comment.GetId();
                        }


                        let comment = doc.GetCommentById(commentId);
                        if (!comment)
                            return commentId;


                        comment.SetText(comment.GetText() + scope.data);
                        return commentId;
                    });
                });
            }

Nota!
Per garantire che l’intero blocco di modifiche possa essere annullato dopo l’esecuzione della richiesta, utilizziamo i metodi StartAction e EndAction all’interno della funzione commentText.

L’intera implementazione della funzione commentText con i commenti:

(function(){
// Defines the commentText function — lets AI insert a comment or footnote for selected text using AI response.
    WORD_FUNCTIONS.commentText = function()
    {
// Creates a new function object that will be registered and exposed to the AI.
        let func = new RegisteredFunction();
        func.name = "commentText";
// Lists the parameters expected by the function. These are passed as a JSON object by the AI agent.
        func.params = [
            "type (string): whether to add as a 'comment' or as a 'footnote' (default is 'comment')"
        ];


// Gives example JSON inputs to teach the AI how to correctly invoke this function.
        func.examples = [
            "If you need to explain selected text as a comment, respond with:\n" +
            "[functionCalling (commentText)]: {\"prompt\" : \"Explain this text\", \"type\": \"comment\"}",


            "If you need to add a footnote to selected text, respond with:\n" +
            "[functionCalling (commentText)]: {\"prompt\" : \"Add a footnote to this text\", \"type\": \"footnote\"}",


            "If you need to comment selected text, respond with:\n" +
            "[functionCalling (commentText)]: {\"prompt\" : \"Comment this text\"}",


            "If you need to explain selected text as a footnote, respond with:\n" +
            "[functionCalling (commentText)]: {\"prompt\" : \"Explain this text\", \"type\": \"footnote\"}"
        ];
        
// The actual logic that gets executed when the AI calls this function.
        func.call = async function(params) {
            let type = params.type;
            let isFootnote = "footnote" === type;


// Executes a block of code inside the editor's context using the office-js API.
            let text = await Asc.Editor.callCommand(function(){
                let doc = Api.GetDocument();
// Gets the current selected text range.
                let range = doc.GetRangeBySelect();
                let text = range ? range.GetText() : "";
                if (!text)
                {
                    text = doc.GetCurrentWord();
// Selects the current word so comments can be applied to it.
                    doc.SelectCurrentWord();
                }


                return text;
            });


            let argPromt = params.prompt + ":\n" + text;


// Initializes a request engine for communicating with the AI model (e.g. Chat, Translation).
            let requestEngine = AI.Request.create(AI.ActionType.Chat);
            if (!requestEngine)
                return;


            let isSendedEndLongAction = false;
// Marks the end of a logical group or block action in the editor.
            async function checkEndAction() {
                if (!isSendedEndLongAction) {
// Marks the end of a logical group or block action in the editor.
                    await Asc.Editor.callMethod("EndAction", ["Block", "AI (" + requestEngine.modelUI.name + ")"]);
                    isSendedEndLongAction = true
                }
            }


// Starts a block action in the editor, used for undo/redo 
            await Asc.Editor.callMethod("StartAction", ["Block", "AI (" + requestEngine.modelUI.name + ")"]);
// Starts a block action in the editor, used for undo/redo
            await Asc.Editor.callMethod("StartAction", ["GroupActions"]);


            if (isFootnote)
            {
                let addFootnote = true;
// Sends a prompt to the AI model and processes the response via callback
                let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
                    if (!data)
                        return;


// Marks the end of a block action in the editor.
                    await checkEndAction();
                    Asc.scope.data = data;
                    Asc.scope.model = requestEngine.modelUI.name;


                    if (addFootnote)
                    {
// Executes a block of code inside the editor's context using the  office-js API.
                        await Asc.Editor.callCommand(function(){
                            Api.GetDocument().AddFootnote();
                        });
                        addFootnote = false;
                    }
// Inserts the AI-generated result into the document at the current selection or cursor.
                    await Asc.Library.PasteText(data);
                });
            }
            else 
            {
                let commentId = null;
// Sends a prompt to the AI model and processes the response via callback.
                let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
                    if (!data)
                        return;


// Marks the end of a block action in the editor.
                    await checkEndAction();
                    Asc.scope.data = data;
                    Asc.scope.model = requestEngine.modelUI.name;
                    Asc.scope.commentId = commentId;


// Executes a block of code inside the editor's context using the office-js API.
                    commentId = await Asc.Editor.callCommand(function(){
                        let doc = Api.GetDocument();


                        let commentId = Asc.scope.commentId;
                        if (!commentId)
                        {
// Gets the current selected text range.
                            let range = doc.GetRangeBySelect();
                            if (!range)
                                return null;


                            let comment = range.AddComment(Asc.scope.data, Asc.scope.model, "uid" + Asc.scope.model);
                            if (!comment)
                                return null;
                            doc.ShowComment([comment.GetId()]);
                            return comment.GetId();
                        }


                        let comment = doc.GetCommentById(commentId);
                        if (!comment)
                            return commentId;


                        comment.SetText(comment.GetText() + scope.data);
                        return commentId;
                    });
                });
            }


// Marks the end of a  block action in the editor.
            await checkEndAction();
// Marks the end of a block action in the editor.
            await Asc.Editor.callMethod("EndAction", ["GroupActions"]);
        };


        return func;
    }

Ci impegniamo a tenere il passo con la tecnologia moderna, garantendo che il nostro smart AI agent continui a evolversi insieme alle esigenze del mondo digitale di oggi. Creando le tue funzioni personalizzate, puoi estenderne le capacità per adattarle ai tuoi requisiti specifici e unici. Inoltre, accogliamo con entusiasmo la tua creatività e le tue idee.

Se hai domande, suggerimenti o feedback, non esitare a contattarci. Siamo sempre pronti a collaborare e ad aiutarti a trasformare la tua visione in realtà! Buona fortuna e buon lavoro!

Crea il tuo account ONLYOFFICE gratuito

Visualizza, modifica e collabora su documenti, fogli, diapositive, moduli e file PDF online.