详细教程:向 ONLYOFFICE AI 智能体中添加自定义 AI 函数
这篇文章是一份详细的技术教程,核心内容是指导开发者如何为 ONLYOFFICE 的 AI 智能体创建并添加自定义的 AI 函数,从而扩展其自动化处理文档的能力。
借助全新 AI 智能体,ONLYOFFICE 为当下快速发展的数字世界提供了前沿工具。作为开源项目,我们真诚邀请开发者、学生和办公自动化爱好者参与我们的活动,一起探索 AI 与文档协作的无限可能,为广大用户贡献更多高效便捷的办公技巧。
本文将详细介绍,开发者如何为 ONLYOFFICE 的 AI 智能体创建并添加自定义的 AI 函数,从而扩展其自动化处理文档的能力。
什么是 AI 函数?AI 函数有什么用途?
AI 函数是 AI 智能体的核心构建模块,本质上是给 AI 助手的一系列指令。
它的作用包括:
- 告诉 AI 模型应该发送什么请求。
- 指定要对文档(文字、表格、幻灯片)执行什么操作。
借助 AI 函数,您可以扩展并控制 AI 与文档内容的交互方式。
如何使用 AI 函数
-
在 AI 插件中选择并添加模型。
-
按下 CTRL + / 打开 AI 智能体对话框。
- 输入提示并按 Enter。
示例:commentText 函数
commentText 函数可让您直接在文档中添加由 AI 生成的批注。工作流程如下:
- 选中要添加批注的单词;
- 打开 AI 智能体对话框(CTRL + /);
- 输入指令,例如:“解释这段文字”;
- 按下 Enter。
- AI 智能体将运行 commentText 函数,并在文档中插入相关批注:
为什么要为 AI 智能体添加自定义函数?
- 扩展能力:让 AI 智能体能够执行官方未预置的、符合个人或团队特殊需求的任务。
- 提升效率:将复杂的文档处理操作自动化,整合到自己的工作流中。
添加自定义 AI 函数的全局指南
添加自定义函数的过程包括两大阶段:
- 函数注册——在智能体环境中注册 AI 函数及其元数据。
- 函数执行——实现核心逻辑,包括向 AI 模型发送请求,以及利用我们的 Office API 处理文档内容。
下面将详细介绍这两个阶段。
函数注册
要添加新函数,我们需执行 RegisteredFunction 对象。它允许我们为函数添加元数据和逻辑。以下示例展示了如何为文档编辑器添加 commentText 函数:
let func = new RegisteredFunction();
func.name = "commentText";
func.params = [ "type (string): 是以批注形式添加还是以脚注形式添加,默认为批注形式)"
]; func.examples = [ "如需以批注形式解释选中文本,请回复:\n" +
"[functionCalling (commentText)]: {\"prompt\" : \"Explain this text\", \"type\": \"comment\"}",
"如需为选中文本添加脚注,请回复:\n" +
"[functionCalling (commentText)]: {\"prompt\" : \"Add a footnote to this text\", \"type\": \"footnote\"}",
"如需为选中文本添加批注,请回复:\n" +
"[functionCalling (commentText)]: {\"prompt\" : \"Comment this text\"}",
"如需以脚注形式解释选中文本,请回复:\n" +
"[functionCalling (commentText)]: {\"prompt\" : \"Explain this text\", \"type\": \"footnote\"}"
]
其中:
- func.name:AI 调用此函数时使用的名称(如 “commentText”)。
- func.params:函数期望从 AI 处获得的参数列表。例如:
– prompt (string):批注的描述或指令,为字符串格式。
– type (string):您需要指定插入“批注” 还是 “脚注”类型,为字符串格式。
- func.examples:提供给 AI 的正确函数调用示例。
- func.description:向 AI 说明该函数的用途。
AI 使用这些参数。RegisteredFunction() 对象被定义在 helperFunc.js 文件中。
函数执行逻辑
注册函数后,我们要编写当 AI 被调用时该函数真正执行的逻辑。
- 使用 Asc.Editor.callCommand() 获取选中的文本。
func.call = async function(params) {
let type = params.type;
let isFootnote = "footnote" === type;
// 使用 Office-JS API 在编辑器上下文中执行代码块。
let text = await Asc.Editor.callCommand(function(){
let doc = Api.GetDocument();
// 获取当前选中的文本范围。
let range = doc.GetRangeBySelect();
let text = range ? range.GetText() : "";
if (!text)
{ text = doc.GetCurrentWord(); // 选中当前单词,以便为其添加批注。
doc.SelectCurrentWord(); } return text;
});
- 通过组合 params.prompt 与所选文本,为 AI 构建提示。
let argPromt = params.prompt + ":\n" + text;
-
使用 AI.Request.create 初始化 AI.Request.create 对象(该对象在 engine.js 文件中被定义),用于向 AI 模型发送请求。
// 初始化与 AI 模型通信(例如对话、翻译)的请求引擎。
let requestEngine = AI.Request.create(AI.ActionType.Chat);
if (!requestEngine)
return;
- 调用 chatRequest() 发送请求,并在回调中接收结果
// 向 AI 模型发送提示,并通过回调处理响应。可流式输出或等待完整结果。
let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
if (!data)
return;
- 使用 AddFootnote() 或 AddComment() 将回复插入为脚注或批注。
AddFootnote 执行:
if (isFootnote)
{ let addFootnote = true;
// 向 AI 模型发送提示,并通过回调处理响应。可流式输出或等待完整结果。
let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
if (!data)
return;
// 标记编辑器中某个逻辑组或块级操作的结束。
await checkEndAction();
Asc.scope.data = data; Asc.scope.model = requestEngine.modelUI.name; if (addFootnote)
{ // 使用文档模型 API 在编辑器上下文中执行代码块。
await Asc.Editor.callCommand(function(){
// 返回主文档对象,提供对所有编辑、结构和选择接口的访问。
Api.GetDocument().AddFootnote(); }); addFootnote = false;
} // 将 AI 生成的结果插入到当前光标或选区所在位置。
await Asc.Library.PasteText(data);
});
AddComment 执行:
let commentId = null;
// 向 AI 模型发送提示,并通过回调处理响应。可流式输出或等待完整结果。
let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
if (!data)
return;
// 标记编辑器中某个逻辑组或块级操作的结束。
await checkEndAction();
Asc.scope.data = data; Asc.scope.model = requestEngine.modelUI.name; Asc.scope.commentId = commentId; // 使用文档模型 API 在编辑器上下文中执行代码块。
commentId = await Asc.Editor.callCommand(function(){
// 返回主文档对象,提供对所有编辑、结构和选择接口的访问。
let doc = Api.GetDocument();
let commentId = Asc.scope.commentId;
if (!commentId)
{ // 获取当前选中的文本范围,可对其进行修改或添加批注。
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;
}); }); }
注意!
为确保整个修改块在请求完成后可以被撤销,我们在 commentText 函数中统一使用了 StartAction 与 EndAction 方法。
带完整注释的 commentText 函数:
(function(){
// 定义 commentText 函数 —— 让 AI 根据返回结果为选中文本插入批注或脚注。
WORD_FUNCTIONS.commentText = function()
{
// 创建一个新的函数对象,该对象将被注册并暴露给 AI。
let func = new RegisteredFunction();
func.name = "commentText";
// 列出函数期望的参数,这些参数由 AI 智能体以 JSON 对象的形式传入。
func.params = [ "type (string): 以批注或以脚注形式添加(默认为 批注形式)"
]; // 提供示例,JSON 输入,指导 AI 如何正确调用此函数。
func.examples = [ "如需将选中文本以批注形式解释,请回复:\n" +
"[functionCalling (commentText)]: {\"prompt\" : \"Explain this text\", \"type\": \"comment\"}",
"如需为选中文本添加脚注,请回复:\n" +
"[functionCalling (commentText)]: {\"prompt\" : \"Add a footnote to this text\", \"type\": \"footnote\"}",
"如需为选中文本添加批注,请回复:\n" +
"[functionCalling (commentText)]: {\"prompt\" : \"Comment this text\"}",
"如需将选中文本以脚注形式解释,请回复:\n" +
"[functionCalling (commentText)]: {\"prompt\" : \"Explain this text\", \"type\": \"footnote\"}"
]; // 当 AI 调用该函数时实际执行的逻辑。
func.call = async function(params) {
let type = params.type;
let isFootnote = "footnote" === type;
// 使用 Office-JS API 在编辑器上下文中执行代码块。
let text = await Asc.Editor.callCommand(function(){
let doc = Api.GetDocument();
// 获取当前选中的文本范围。
let range = doc.GetRangeBySelect();
let text = range ? range.GetText() : "";
if (!text)
{ text = doc.GetCurrentWord(); // 选中当前单词,以便为其添加批注。
doc.SelectCurrentWord(); } return text;
}); let argPromt = params.prompt + ":\n" + text;
// 初始化与 AI 模型通信的请求引擎(如对话、翻译)。
let requestEngine = AI.Request.create(AI.ActionType.Chat);
if (!requestEngine)
return;
let isSendedEndLongAction = false;
// 标记编辑器中某个逻辑组或块级操作的结束。
async function checkEndAction() {
if (!isSendedEndLongAction) {
// 标记编辑器中某个逻辑组或块级操作的结束。
await Asc.Editor.callMethod("EndAction", ["Block", "AI (" + requestEngine.modelUI.name + ")"]);
isSendedEndLongAction = true
} } // 在编辑器中启动一个块级操作,用于撤销/重做。
await Asc.Editor.callMethod("StartAction", ["Block", "AI (" + requestEngine.modelUI.name + ")"]);
// 在编辑器中启动一个块级操作,用于撤销/重做。
await Asc.Editor.callMethod("StartAction", ["GroupActions"]);
if (isFootnote)
{ let addFootnote = true;
// 向 AI 模型发送提示,并通过回调处理响应。
let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
if (!data)
return;
// 标记编辑器中某个块级操作的结束。
await checkEndAction();
Asc.scope.data = data; Asc.scope.model = requestEngine.modelUI.name; if (addFootnote)
{ // 使用 Office-JS API 在编辑器上下文中执行代码块。
await Asc.Editor.callCommand(function(){
Api.GetDocument().AddFootnote(); }); addFootnote = false;
} // 将 AI 生成的结果插入到当前光标或选区所在位置。
await Asc.Library.PasteText(data);
}); } else
{ let commentId = null;
// 向 AI 模型发送提示,并通过回调处理响应。
let result = await requestEngine.chatRequest(argPromt, false, async function(data) {
if (!data)
return;
// 标记编辑器中某个块级操作的结束。
await checkEndAction();
Asc.scope.data = data; Asc.scope.model = requestEngine.modelUI.name; Asc.scope.commentId = commentId; // 使用 Office-JS API 在编辑器上下文中执行代码块。
commentId = await Asc.Editor.callCommand(function(){
let doc = Api.GetDocument();
let commentId = Asc.scope.commentId;
if (!commentId)
{ // 获取当前选中的文本范围。
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;
}); }); } // 标记编辑器中某个块级操作的结束。
await checkEndAction();
// 标记编辑器中某个块级操作的结束。
await Asc.Editor.callMethod("EndAction", ["GroupActions"]);
}; return func;
}
ONLYOFFICE 作为开源项目,始终致力于紧跟现代技术,确保智能 AI 智能体持续演进,以满足当今数字世界需求。通过创建自定义函数,您可以极大扩展 AI 智能体的能力,满足更多办公需求。
我们期待来自用户的更多创意与想法。更多相关功能您可以通过 GitHub 上的 ONLYOFFICE AI 智能体学习和了解。
如有任何疑问、建议或反馈,欢迎随时与我们联系。我们希望帮助您将愿景变为现实,祝愿您在探索 AI 功能的过程中一帆风顺。
所有评论(0)