دليل تفصيلي: إضافة دوال ذكاء اصطناعي مخصصة إلى مساعد ONLYOFFICE AI

٢١ أغسطس ٢٠٢٥بواسطة Moncif MEFTAH

مع مساعد AI الذكي الجديد، نقدم لكم أدوات متطورة لتلبية متطلبات العالم الرقمي سريع الخطى اليوم. وكمشروع مفتوح المصدر، فإننا نرحب بالابتكارات التي يقودها المستخدمون. في هذا المقال، سنوضح لكم كيفية إضافة دوال مخصصة إلى مساعد AI، مما يجعل عملكم مع المستندات أسرع وأسهل وأكثر ملاءمة.

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

ما هي دوال الذكاء الاصطناعي وما الغرض منها؟

دوال الذكاء الاصطناعي هي اللبنات الأساسية لوظائف مساعد AI. بشكل أساسي، هي تعليمات تخبر مساعد AI بما يلي:

  • ما هو الطلب الذي يجب إرساله إلى نموذج الذكاء الاصطناعي.
  • ما هي التعديلات التي يجب إجراؤها على مستندكم.

باستخدام دوال الذكاء الاصطناعي، يمكنكم توسيع نطاق تفاعل الذكاء الاصطناعي مع محتوى مستندكم والتحكم فيه.

كيفية استخدام دالة الذكاء الاصطناعي

  1. أضيفوا نموذجًا من اختياركم إلى اضافة AI.
  2. افتحوا مربع حوار مساعد AI بالضغط على CTRL + /.
  3. أدخلوا الموجه الخاص بكم واضغطوا على Enter.

مثال: دالة commentText

تسمح لكم دالة commentText بإضافة تعليقات مُنشأة بواسطة الذكاء الاصطناعي مباشرة إلى مستندكم. إليكم كيفية عملها:

  • حددوا كلمة تريدون ترك تعليق عليها.
  • افتحوا مربع حوار مساعد AI (CTRL + /).
  • اكتبوا تعليماتكم، على سبيل المثال: “اشرح هذا النص.”
  • اضغطوا على Enter.

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

سيقوم مساعد AI بتشغيل دالة commentText وإدراج التعليقات ذات الصلة في مستندكم:

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

لماذا تضيفون دوال مخصصة إلى مساعد AI الخاص بكم؟

تتيح لكم إضافة دوال ذكاء اصطناعي مخصصة توسيع إمكانيات مساعد AI الذكي وتخصيصه وفقًا لاحتياجاتكم الدقيقة. سواء كنتم تعملون مع المستندات أو جداول البيانات أو العروض التقديمية، فإن تعدد استخدامات المساعد، جنبًا إلى جنب مع قوة نماذج الذكاء الاصطناعي الحديثة، يساعدكم على تحويل الأفكار إلى واقع ودمجها بسلاسة في سير عملكم.

المنطق العام لإضافة دالة ذكاء اصطناعي مخصصة

تتضمن عملية إضافة دالة مخصصة مرحلتين رئيسيتين:

  • تسجيل الدالة – لتسجيل دالة الذكاء الاصطناعي وبياناتها الوصفية داخل بيئة المساعد.
  • تنفيذ الدالة – لتطبيق المنطق الأساسي، والذي يتضمن إرسال الطلبات إلى نموذج الذكاء الاصطناعي وتعديل محتوى المستند باستخدام Office API الخاص بنا.

الآن دعونا نلقي نظرة فاحصة على هاتين المرحلتين.

تسجيل الدالة

لإضافة دالة جديدة، نقوم بتطبيق عنصر RegisteredFunction. يسمح لنا بإضافة البيانات الوصفية والمنطق. إليكم مثال على إضافة دالة commentText لـمحرر المستندات:

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\"}"
     ]

حيث:

  • func.name: الاسم الذي سيستخدمه الذكاء الاصطناعي لاستدعاء هذه الدالة (مثل، “commentText”).
  • func.params: قائمة بالمعلمات التي تتوقعها الدالة من الذكاء الاصطناعي. على سبيل المثال:

 prompt (string): وصف أو تعليمات للتعليق.

–  type (string): “comment” أو “footnote” — يحدد ما سيتم إدراجه.

  • func.examples: أمثلة على استدعاءات الدالة الصحيحة للذكاء الاصطناعي.
  • func.description: تشرح للذكاء الاصطناعي الغرض من استخدام الدالة.

يستخدم الذكاء الاصطناعي هذه المعلمات. تم تعريف عنصر RegisteredFunction() في ملف helperFunc.js.

منطق تنفيذ الدالة

بعد تسجيل الدالة، نقوم بتطبيق المنطق الفعلي الذي يتم تنفيذه عندما يستدعي الذكاء الاصطناعي هذه الدالة.

  • استرداد النص المحدد باستخدام 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;
            });
  • بناء الموجه للذكاء الاصطناعي من خلال دمج params.prompt والنص المحدد.
let argPromt = params.prompt + ":\n" + text;
  • تهيئة عنصر AI.Request.create باستخدام AI.Request.create. تم تعريف هذا العنصر في ملف engine.js يسهل هذا العنصر إرسال طلب إلى نموذج الذكاء الاصطناعي.
// 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;
  • إرسال الطلب باستخدام chatRequest() واستلام النتيجة في دالة رد نداء (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;
  • إدراج الاستجابة كتعليق أو حاشية سفلية باستخدام AddFootnote() أو إدراج الاستجابة كتعليق أو حاشية سفلية باستخدام AddFootnote() أو AddComment()

تطبيق 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);
                });

تطبيق 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;
                    });
                });
            }

ملاحظة!
لضمان إمكانية التراجع عن كتلة التغييرات بأكملها بعد تنفيذ الطلب، نستخدم دالتي StartAction و EndAction عبر دالة commentText.

التطبيق الكامل لدالة commentText مع التعليقات:

(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;
    }

نحن ملتزمون بمواكبة التكنولوجيا الحديثة، وضمان استمرار تطور مساعد AI الذكي الخاص بنا جنبًا إلى جنب مع احتياجات العالم الرقمي اليوم. من خلال إنشاء دوال مخصصة خاصة بكم، يمكنكم توسيع قدراته لتناسب متطلباتكم الدقيقة والفريدة. نرحب بإبداعكم وأفكاركم.

إذا كانت لديكم أي أسئلة أو اقتراحات أو ملاحظات، فلا تترددوا في التواصل معنا. نحن دائمًا على استعداد للتعاون ومساعدتكم على تحقيق رؤيتكم! حظًا موفقًا في مساعيكم الاستكشافية!

ONLYOFFICE ١. أنشئ حسابك المجاني من

،٢. قم بعرض و تحرير أو التعاون على المستندات، الجداول ، العروض التقديمية