AI插件开发框架plugin-kit-ai:标准化构建大模型智能体应用
1. 项目概述与核心价值
最近在折腾AI应用开发,特别是想快速把大语言模型的能力集成到自己的产品里,发现了一个挺有意思的开源项目:
777genius/plugin-kit-ai
。乍一看这个名字,你可能会觉得它又是一个“AI插件套件”,市面上类似的工具包确实不少。但在我花了几周时间深入研究和实际部署后,发现它的设计理念和实现方式,恰好切中了当前AI应用开发中的一个核心痛点——如何高效、标准化地构建和管理那些需要与外部工具、数据源或API交互的“智能体”或“插件”。
简单来说,
plugin-kit-ai
是一个为AI应用(尤其是基于大语言模型的聊天机器人、智能助手)提供插件化能力的基础设施框架。它不是一个具体的AI模型,也不是一个开箱即用的聊天界面,而是一套“脚手架”和“协议”。它的核心价值在于,当你希望你的AI不仅能聊天,还能执行具体任务(比如查天气、发邮件、分析数据、操作数据库)时,它帮你解决了最繁琐的那部分工作:定义插件接口、处理授权、管理插件生命周期、以及将自然语言指令安全、准确地映射到具体的插件功能调用上。
这个项目特别适合两类开发者:一是正在基于OpenAI的GPTs、Claude的Custom Actions或是开源模型如Llama、Qwen构建智能助手的团队,他们需要一套统一的插件开发规范;二是那些希望将自己的服务(如内部CRM系统、数据分析工具)快速“AI化”,暴露成智能体可以理解和调用的功能的开发者。我自己用它来统一管理团队内部几个数据分析工具的访问入口,效果比之前各写各的胶水代码要清晰和稳定得多。
2. 核心架构与设计哲学拆解
2.1 为什么需要“插件套件”而不仅仅是“写个API”?
在接触
plugin-kit-ai
之前,我们团队的做法很直接:为每个需要AI调用的功能写一个独立的API接口,然后在提示词(Prompt)里告诉AI:“如果你想查用户数据,就调用
/api/v1/user/query
这个接口,参数是
user_id
”。这种做法在小规模时可行,但很快会遇到几个棘手问题:
- 接口描述混乱 :每个API的输入输出格式、参数含义都需要在提示词里用自然语言描述,容易产生歧义,AI理解不准。
- 安全性难以保障 :直接在提示词里暴露接口地址和参数结构不安全,且难以做精细的权限控制(比如插件A只能由管理员触发)。
- 扩展性差 :每增加一个新功能,就要修改提示词和后台调度逻辑,代码耦合度高。
- 缺乏标准化 :不同的开发者写的插件,风格迥异,没有统一的错误处理、日志记录和状态管理。
plugin-kit-ai
的解决方案是引入了一层“抽象”和“协议”。它定义了一套标准化的方式来描述一个插件(Plugin):这个插件叫什么名字、能干什么、需要哪些参数、返回什么格式的数据。同时,它还提供了一个运行时(Runtime),负责接收AI模型(或用户)的请求,根据请求内容自动匹配和调用合适的插件,并将结果格式化后返回。这就像为你的各种后台服务提供了一个统一的、AI友好的“适配器”或“驱动面板”。
2.2 核心组件与工作流
项目的架构清晰地区分了几个核心角色,理解它们之间的关系是上手的关键:
-
插件(Plugin)
: 功能的基本单元。一个插件对应一个具体的可执行能力,例如
GetWeather、SendEmail、QueryDatabase。每个插件都需要按照框架定义的格式进行“声明”,包括其名称、描述、输入参数模式(JSON Schema)等。这个声明是机器可读的,AI模型可以据此理解插件的用途和调用方式。 -
插件工具包(Plugin Kit)
: 可以理解为一个插件的集合或注册中心。开发者将多个相关的插件组织成一个工具包。
plugin-kit-ai框架的核心就是帮助开发者创建、管理这些工具包,并将它们暴露给AI运行时。 -
AI 运行时/适配器(Runtime/Adapter)
: 这是框架与具体AI模型交互的桥梁。它负责两件事:
- 工具描述提供 : 将注册的所有插件,按照特定AI模型(如OpenAI的GPT函数调用、Claude的Tool Use)要求的格式进行封装,并注入到对话的上下文或系统提示中。
- 调用分发与执行 : 当AI模型在对话中决定要调用某个插件时,它会返回一个结构化的调用请求。运行时接收到这个请求后,会找到对应的插件实例,传入参数,执行其核心逻辑,并将执行结果返回给AI模型,由模型组织成自然语言回复给用户。
整个工作流可以概括为: “声明插件 -> 注册到工具包 -> 运行时提供给AI模型 -> AI模型决策调用 -> 运行时执行并返回结果” 。这个流程将AI的“思考决策”与插件的“具体执行”解耦,使得两者可以独立开发和迭代。
3. 从零开始:快速上手与核心配置
3.1 环境准备与项目初始化
假设你有一个Node.js(建议16+)的开发环境,我们从最基础的开始。首先,克隆仓库并安装依赖。虽然项目文档可能提供了多种方式,但最直接的是通过npm或yarn安装其核心包。
# 假设项目提供了npm包,通常核心包名可能是 `@777genius/plugin-kit-ai` 或类似
# 这里我们以克隆源码并链接的方式为例,这更利于理解和调试
git clone https://github.com/777genius/plugin-kit-ai.git
cd plugin-kit-ai
npm install # 或 yarn install
注意 :在实际使用中,你可能更倾向于将它作为依赖安装到你自己的AI应用项目中:
npm install @777genius/plugin-kit-ai。但为了深入理解,先浏览源码结构很有帮助。通常项目会包含核心库(packages/core)、示例(examples)和可能的一些适配器(adapters)。
3.2 创建你的第一个插件:一个简单的问候插件
让我们抛开复杂的例子,先实现一个最简单的插件,感受一下框架的约定。在
plugin-kit-ai
的范式里,一个插件通常是一个符合特定接口的类或对象。
假设我们在自己的项目目录
my-ai-app
中操作:
-
安装核心库 :
cd my-ai-app npm install @777genius/plugin-kit-ai -
编写插件代码 (
src/plugins/GreetingPlugin.ts) :import { BasePlugin, PluginExecuteResult } from '@777genius/plugin-kit-ai'; // 定义插件的输入参数类型 interface GreetingInput { name: string; language?: 'en' | 'zh'; // 可选参数,默认为英文 } export class GreetingPlugin extends BasePlugin<GreetingInput> { // 插件唯一标识,用于运行时查找 static pluginId = 'greeting'; // 插件名称,用于展示 get name(): string { return 'Greeting'; } // 插件描述,AI模型会根据这个理解插件功能 get description(): string { return 'Generate a friendly greeting message to the user.'; } // 定义输入参数的JSON Schema,这是AI模型理解如何调用插件的关键 get parameters() { return { type: 'object', properties: { name: { type: 'string', description: 'The name of the person to greet.', }, language: { type: 'string', enum: ['en', 'zh'], description: 'The language of the greeting. Default is "en".', }, }, required: ['name'], // 指定必填参数 }; } // 插件的核心执行逻辑 async execute(input: GreetingInput): Promise<PluginExecuteResult> { const { name, language = 'en' } = input; let message: string; if (language === 'zh') { message = `你好,${name}!欢迎使用本系统。`; } else { message = `Hello, ${name}! Welcome to the system.`; } // 返回执行结果,success为true表示执行成功 return { success: true, output: message, // 可以附加一些结构化数据 data: { greetedName: name, languageUsed: language }, }; } } -
创建插件工具包并注册 (
src/pluginKit.ts) :import { PluginKit } from '@777genius/plugin-kit-ai'; import { GreetingPlugin } from './plugins/GreetingPlugin'; // 创建一个插件工具包实例 const myPluginKit = new PluginKit({ name: 'MyFirstPluginKit', version: '1.0.0', }); // 将我们的问候插件注册到工具包中 myPluginKit.registerPlugin(new GreetingPlugin()); // 后续还可以注册更多插件... // myPluginKit.registerPlugin(new WeatherPlugin()); // myPluginKit.registerPlugin(new CalculatorPlugin()); export default myPluginKit; -
与AI模型集成(以OpenAI API为例) :
import OpenAI from 'openai'; import myPluginKit from './pluginKit'; import { OpenAIRuntimeAdapter } from '@777genius/plugin-kit-ai/adapters/openai'; // 假设有此适配器 const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); // 1. 获取工具包中所有插件的“工具描述”,格式符合OpenAI函数调用规范 const tools = myPluginKit.getToolsForOpenAI(); // 2. 在调用ChatCompletion时,将这些工具描述传入 async function chatWithAI(userMessage: string) { const response = await openai.chat.completions.create({ model: 'gpt-3.5-turbo', messages: [{ role: 'user', content: userMessage }], tools: tools, // 关键:让AI知道有哪些工具可用 tool_choice: 'auto', // 让AI自动决定是否调用工具 }); const message = response.choices[0].message; // 3. 检查AI是否决定调用工具 if (message.tool_calls && message.tool_calls.length > 0) { const toolCall = message.tool_calls[0]; const pluginId = toolCall.function.name; // 例如 'greeting' const args = JSON.parse(toolCall.function.arguments); // 例如 { name: 'Alice' } // 4. 通过插件工具包找到对应插件并执行 const result = await myPluginKit.executePlugin(pluginId, args); // 5. 将执行结果作为新的上下文消息,再次发送给AI,让它生成最终回复 const secondResponse = await openai.chat.completions.create({ model: 'gpt-3.5-turbo', messages: [ { role: 'user', content: userMessage }, message, // AI之前的回复(包含工具调用) { role: 'tool', tool_call_id: toolCall.id, content: JSON.stringify(result.output), }, ], }); return secondResponse.choices[0].message.content; } // 如果AI没有调用工具,直接返回其回复 return message.content; } // 测试 (async () => { const reply = await chatWithAI('请向张三问好。'); console.log(reply); // 输出: “你好,张三!欢迎使用本系统。” })();
通过这个简单的例子,你应该能清晰地看到
plugin-kit-ai
扮演的角色:它标准化了插件的定义(
GreetingPlugin
类),管理了插件的集合(
PluginKit
实例),并提供了与AI模型交互的“翻译”层(将插件转换为OpenAI的
tools
格式,并处理调用结果)。你作为开发者,只需要关注每个插件内部的
execute
逻辑即可。
4. 深入核心:高级特性与最佳实践
4.1 插件参数验证与安全性
在
GreetingPlugin
的例子中,我们简单定义了参数。在实际生产环境中,参数验证至关重要。
plugin-kit-ai
通常依赖
parameters
返回的JSON Schema进行初步验证。但
我强烈建议在
execute
方法内部进行二次验证
,尤其是涉及数据库查询、文件操作或外部API调用时。
async execute(input: WeatherInput): Promise<PluginExecuteResult> {
const { city, countryCode = 'CN' } = input;
// 示例:额外的业务逻辑验证
if (!isValidCity(city, countryCode)) {
return {
success: false,
output: `无法识别城市: ${city}, 国家码: ${countryCode}`,
error: new Error('Invalid city or country code'),
};
}
// 防止滥用:限制查询频率(伪代码)
const key = `weather:${city}:${countryCode}`;
if (await cache.get(key)) {
return { success: false, output: '请求过于频繁,请稍后再试。' };
}
await cache.set(key, true, 60); // 60秒内禁止重复查询
// ... 调用真实天气API ...
}
此外,
插件级别的权限控制
是另一个安全重点。你可以在插件基类或注册时添加元数据,比如
requiredRole: ['admin', 'user']
,然后在运行时(
execute
被调用前)检查当前用户的权限。
plugin-kit-ai
框架本身可能提供钩子(Hooks)或中间件(Middleware)机制来支持这一点,你需要查阅其文档或源码来实施。
4.2 异步操作、状态管理与错误处理
插件执行可能是耗时的I/O操作(网络请求、复杂计算)。
plugin-kit-ai
的
execute
方法设计为
async
,天然支持异步。关键在于要做好
超时控制
和
错误兜底
。
import { timeout } from 'promise-timeout'; // 使用第三方超时库
async execute(input: QueryInput): Promise<PluginExecuteResult> {
try {
// 设置超时,避免插件长时间阻塞
const result = await timeout(this.performComplexQuery(input), 10000); // 10秒超时
return {
success: true,
output: `查询成功,共找到 ${result.count} 条记录。`,
data: result,
};
} catch (error) {
// 区分超时错误和其他业务错误
if (error.name === 'TimeoutError') {
return {
success: false,
output: '查询超时,请稍后重试或简化查询条件。',
error,
};
}
// 记录详细错误日志,但返回用户友好的信息
console.error(`[Plugin:${this.name}] Execute failed:`, error);
return {
success: false,
output: '系统执行查询时遇到问题,请联系管理员。',
error, // 框架可能会记录这个error
};
}
}
对于需要维护状态的插件(例如一个多轮对话的订餐插件),框架本身可能不直接管理状态。常见的做法是将状态存储在外部(如数据库、Redis),并通过每次调用传入的
sessionId
或
conversationId
来关联和恢复状态。
4.3 与不同AI模型和平台的适配
plugin-kit-ai
的强大之处在于其适配器设计。除了OpenAI,它可能还支持Claude、通义千问、Llama.cpp的服务器等。核心思想是:
插件工具包是模型无关的
,适配器负责将统一的插件描述“翻译”成目标模型能理解的格式。
-
OpenAI / Azure OpenAI
: 使用
function calling或更新的tools格式。 -
Anthropic Claude
: 使用
tools(Tool Use) 格式。 -
开源模型 (通过LMStudio, ollama等)
: 通常也遵循类似的
function calling规范,但可能需要适配器做细微调整。 - 国内大模型平台 : 如百度文心、讯飞星火等,它们也逐步提供了类似的功能调用接口,需要编写特定的适配器。
在项目中,你可能会找到一个
adapters
目录,里面包含了这些适配器的实现。使用起来可能像这样:
// 使用OpenAI适配器
import { OpenAIRuntime } from '@777genius/plugin-kit-ai/adapters/openai';
const openaiRuntime = new OpenAIRuntime(myPluginKit, openaiClient);
// 使用Claude适配器
import { ClaudeRuntime } from '@777genius/plugin-kit-ai/adapters/claude';
const claudeRuntime = new ClaudeRuntime(myPluginKit, claudeClient);
// 运行时处理消息,它会自动处理工具描述注入和调用分发
const response = await openaiRuntime.chat(messages);
这种设计让你可以轻松切换后端AI模型,而无需重写插件逻辑。
5. 实战:构建一个多功能个人助理插件集
让我们构想一个更实际的场景:一个集成了日历、待办、笔记和快速搜索功能的个人助理插件集。
5.1 设计插件清单
我们规划四个插件:
-
ViewCalendar: 查看今日/本周日程。 -
AddTodoItem: 添加一个待办事项。 -
SearchNotes: 在全站笔记中搜索关键词。 -
QuickWebSearch: 快速进行网络搜索(调用外部搜索API)。
5.2 实现
AddTodoItem
插件详解
这个插件涉及数据写入,更具代表性。
// src/plugins/todo/AddTodoPlugin.ts
import { BasePlugin, PluginExecuteResult } from '@777genius/plugin-kit-ai';
import { TodoService } from '../services/TodoService'; // 假设的业务服务层
interface AddTodoInput {
title: string;
description?: string;
priority?: 'low' | 'medium' | 'high';
dueDate?: string; // ISO 8601 字符串
}
export class AddTodoPlugin extends BasePlugin<AddTodoInput> {
static pluginId = 'add_todo';
private todoService: TodoService;
constructor(todoService: TodoService) {
super();
this.todoService = todoService;
}
get name(): string { return 'AddTodoItem'; }
get description(): string {
return 'Add a new todo item to your personal task list.';
}
get parameters() {
return {
type: 'object',
properties: {
title: {
type: 'string',
description: 'The title or summary of the todo item. This is required.',
},
description: {
type: 'string',
description: 'Detailed description of the todo.',
},
priority: {
type: 'string',
enum: ['low', 'medium', 'high'],
description: 'Priority level of the task. Default is medium.',
},
dueDate: {
type: 'string',
format: 'date-time',
description: 'The due date and time in ISO 8601 format (e.g., 2023-10-27T15:00:00Z).',
},
},
required: ['title'],
};
}
async execute(input: AddTodoInput, context?: PluginContext): Promise<PluginExecuteResult> {
// 1. 参数预处理与默认值
const { title, description = '', priority = 'medium', dueDate } = input;
// 2. 业务验证
if (title.length > 200) {
return { success: false, output: '任务标题过长,请精简至200字以内。' };
}
if (dueDate && new Date(dueDate) < new Date()) {
return { success: false, output: '截止日期不能是过去的时间。' };
}
// 3. 从上下文获取用户身份(假设运行时注入)
const userId = context?.userId;
if (!userId) {
return { success: false, output: '无法识别用户身份,请先登录。' };
}
try {
// 4. 调用业务服务
const newTodo = await this.todoService.create({
userId,
title,
description,
priority,
dueDate: dueDate ? new Date(dueDate) : null,
status: 'pending',
});
// 5. 构造友好的成功消息
let output = `✅ 已成功添加待办事项:“${newTodo.title}”`;
if (newTodo.dueDate) {
const dueStr = new Date(newTodo.dueDate).toLocaleDateString();
output += `,截止日期为 ${dueStr}`;
}
output += '。';
return {
success: true,
output,
data: newTodo, // 返回结构化数据,可供后续插件或前端使用
};
} catch (error) {
console.error(`[AddTodoPlugin] Failed for user ${userId}:`, error);
return {
success: false,
output: '添加待办事项失败,可能是系统繁忙,请稍后重试。',
error,
};
}
}
}
5.3 集成与使用
将所有这些插件注册到一个工具包中,并创建一个简单的Express服务器来提供API端点。
// src/server.ts
import express from 'express';
import { PluginKit } from '@777genius/plugin-kit-ai';
import { OpenAIRuntime } from '@777genius/plugin-kit-ai/adapters/openai';
import OpenAI from 'openai';
import { AddTodoPlugin } from './plugins/todo/AddTodoPlugin';
import { ViewCalendarPlugin } from './plugins/calendar/ViewCalendarPlugin';
// ... 导入其他插件和服务
const app = express();
app.use(express.json());
// 初始化业务服务
const todoService = new TodoService(/* ...依赖注入... */);
const calendarService = new CalendarService(/* ... */);
// ...
// 创建插件工具包并注册插件
const assistantKit = new PluginKit({ name: 'PersonalAssistant' });
assistantKit.registerPlugin(new AddTodoPlugin(todoService));
assistantKit.registerPlugin(new ViewCalendarPlugin(calendarService));
// ...
// 初始化OpenAI客户端和运行时
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const runtime = new OpenAIRuntime(assistantKit, openai);
// API端点:聊天/执行插件
app.post('/api/chat', async (req, res) => {
try {
const { messages, userId } = req.body; // 从请求中获取对话历史和用户ID
// 创建插件执行的上下文,包含用户身份
const pluginContext = { userId };
// 使用运行时处理消息,它会自动处理插件调用
// 注意:你需要根据适配器的具体API来调用,这里是一个示意
const response = await runtime.chatCompletion({
messages,
model: 'gpt-4',
context: pluginContext, // 将上下文传递给运行时,以便在执行插件时使用
});
res.json({ reply: response });
} catch (error) {
console.error('Chat endpoint error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// API端点:获取当前可用的插件列表(用于前端展示或调试)
app.get('/api/plugins', (req, res) => {
const pluginManifests = assistantKit.getAllPluginManifests(); // 假设有这个方法
res.json({ plugins: pluginManifests });
});
app.listen(3000, () => console.log('Assistant server running on port 3000'));
这样,一个具备插件化能力的AI助手后端就搭建起来了。前端应用可以通过
/api/chat
发送用户消息,并收到集成了插件能力的智能回复。
6. 常见问题、调试技巧与性能优化
6.1 AI模型不调用插件?排查清单
这是开发初期最常见的问题。如果AI对你的指令(如“帮我添加一个明天下午三点开会的待办”)毫无反应,只是用文本回复,请按以下步骤排查:
-
检查工具描述是否成功注入
:在调用AI API的请求中,打印出
tools参数,确认其格式符合模型要求(特别是OpenAI的tools或functions格式)。确保描述清晰,description字段要足够详细,让AI理解插件的用途。 -
优化插件描述和参数描述
:AI根据描述决定是否调用。将
description写得像任务指令,例如:“Add a todo item to the user‘s task list.” 参数描述也要清晰,例如“title: A short, descriptive title for the todo item.”。 - 调整系统提示词(System Prompt) :在给AI的系统指令中,明确告诉它可以使用这些工具。例如:“你是一个有帮助的助手,可以调用工具来管理用户的日历、待办事项等。当用户请求涉及这些操作时,你应该主动调用相应的工具。”
-
检查模型能力
:确保你使用的模型支持函数/工具调用(如
gpt-3.5-turbo-1106及以上版本、gpt-4系列、claude-3系列)。 - 验证参数Schema :过于复杂或嵌套过深的JSON Schema可能导致AI解析困难。尽量保持参数结构扁平、简单。
6.2 插件被错误调用或参数解析不对?
- 启用详细日志 :在插件工具包和运行时中,开启调试日志,记录AI返回的原始工具调用请求,看参数是否与你预期一致。
-
参数类型匹配
:确保
parameters中定义的type(如string,number,boolean)与AI可能生成的值类型匹配。对于枚举值,使用enum明确列出选项。 - 提供示例(Few-shot) :在系统提示词中,可以提供一两个用户指令和正确调用插件的示例,引导AI学习。
6.3 性能优化与缓存策略
当插件数量增多或某些插件执行较慢时(如网络搜索),需要考虑性能。
- 插件懒加载 :不是所有插件都需要在启动时就实例化。可以按需加载插件模块,特别是对于那些不常用的插件。
-
结果缓存
:对于查询类、结果相对稳定的插件(如
GetWeather、QueryStockPrice),在插件内部或工具包层面实现缓存。可以使用内存缓存(如Node-cache)或分布式缓存(Redis)。注意设置合理的过期时间(TTL)。// 在插件execute方法内加入缓存逻辑 const cacheKey = `weather:${city}:${date}`; const cached = await cache.get(cacheKey); if (cached) return { success: true, output: cached, fromCache: true }; // ... 否则调用API ... await cache.set(cacheKey, result, 300); // 缓存5分钟 - 并发控制与限流 :对于可能被频繁调用或消耗资源的插件(如调用付费API),实现限流机制。可以在插件工具包层面添加一个中间件,对插件调用进行计数和限制。
-
超时设置
:如前所述,为每个插件的
execute方法设置全局或单独的超时时间,防止单个插件阻塞整个请求。
6.4 版本管理与插件热更新
在长期运行的服务中,插件可能需要升级。
plugin-kit-ai
框架本身可能不直接处理版本,但你可以通过以下模式实现:
-
插件标识符包含版本
:如
pluginId: 'add_todo_v2'。在注册新版本时,同时注册新旧版本,通过路由或配置决定AI使用哪个版本。 - 基于配置的热加载 :将插件配置(类路径、参数)放在外部文件或数据库中。工具包定期检查配置变化,动态加载新的插件类。这需要你的插件设计支持无状态或状态外部化。
- 蓝绿部署 :更稳健的方式是在服务层面进行蓝绿部署。准备一个包含新插件的新版本后端服务,切换流量,而不是在运行时热更新单个插件。
7. 扩展思考:从插件套件到智能体平台
plugin-kit-ai
提供了一个优秀的底层框架。在此基础上,你可以构建更复杂的智能体系统:
- 插件编排与工作流 : 单个插件能力有限,复杂的任务可能需要多个插件按顺序或条件执行。你可以在工具包之上实现一个“编排层”(Orchestrator),它接收一个高级目标(如“规划并预订一次出差”),然后自动分解为“查航班”、“订酒店”、“添加日历事件”等一系列插件调用。
- 插件发现与动态加载 : 构建一个插件市场或仓库,允许开发者提交符合规范的插件。你的主程序可以从远程加载插件描述并动态注册,极大地扩展系统能力。
-
上下文感知与记忆
: 让插件能访问对话历史或用户长期记忆(通过向量数据库)。例如,
SearchNotes插件可以结合用户当前对话的上下文,进行更精准的语义搜索。 - 可视化插件开发与调试工具 : 开发一个Web界面,让非技术人员也能通过表单配置的方式创建简单的插件(如一个调用内部API的插件),并实时测试插件与AI的交互效果。
我个人在项目中最大的体会是,
plugin-kit-ai
这类框架的价值在于它
强制你进行关注点分离和接口标准化
。它迫使你以“AI可理解”的方式去思考和封装你的业务功能,这个过程本身就会让系统架构变得更清晰。一开始可能会觉得多了一层抽象有些麻烦,但一旦跨过这个门槛,你会发现构建和维护AI功能的速度和质量都有了质的提升。尤其是在团队协作中,前端、后端、算法工程师可以基于这套清晰的协议并行开发,效率远超过去那种“写死”的集成方式。
更多推荐
所有评论(0)