AI 工具系统架构设计:基于 OpenAI 的工具注入与调用实现
前言
在现代 AI 应用中,工具调用(Tool Calling)是一个核心功能,它允许 AI 模型调用外部函数来完成特定任务。本文将深入分析一个基于 OpenAI 的工具系统实现,该系统采用了依赖注入、处理器模式等设计模式,提供了完整的工具管理和调用能力。
系统架构概览
核心组件关系图

三层架构设计
AI 服务层(OpenAIService): 负责与 OpenAI API 通信和响应处理
工具管理层(ToolService): 管理工具处理器和调用分发
工具处理层(ToolHandlers): 实现具体的工具业务逻辑
AI 服务层实现
服务接口设计
/**
* AI服务接口
* 定义所有AI服务提供商必须实现的方法
*/
export interface IAIService {
/**
* 创建聊天完成
*/
createChatCompletion(request: IOpenAIRequest): Promise<any>;
/**
* 创建流式聊天完成
*/
createChatCompletionStream(request: IOpenAIRequest): Promise<any>;
}设计优势:
多态支持:可以轻松切换不同的 AI 服务提供商
接口隔离:客户端只依赖接口,不依赖具体实现
扩展性强:新增 AI 服务商只需实现接口即可
OpenAI 服务实现
export class OpenAIService implements IAIService {
/**
* 依赖注入OpenAI客户端
*/
constructor(private client = openaiClient) {
logger.info("OpenAI服务已初始化");
}
async createChatCompletion(request: IOpenAIRequest & { userId: string }) {
try {
// 1. 调用OpenAI API,注入工具定义
const response = await this.client.chat.completions.create({
model: request.model,
messages: request.messages,
temperature: request.temperature,
max_tokens: request.max_tokens,
top_p: request.top_p,
frequency_penalty: request.frequency_penalty,
presence_penalty: request.presence_penalty,
tools: recordTools, // 注入可用工具
});
// 2. 检查并处理工具调用
if (response.choices[0].message?.tool_calls) {
const toolResults = await toolService.processToolCalls(
response.choices[0].message.tool_calls,
{ userId: request.userId }
);
// 3. 增强响应内容
const originalMessage = response.choices[0].message;
const successfulRecords = toolResults.filter((r) => r.success);
if (successfulRecords.length > 0) {
const content = originalMessage.content || "";
const recordInfo =
"\n\n【系统通知】已将以下内容添加到您的时间轴:\n" +
successfulRecords.map((r) => `- ${r.content}`).join("\n");
response.choices[0].message.content = content + recordInfo;
}
}
return response;
} catch (error) {
logger.error("OpenAI API请求失败", error);
throw new Error("与OpenAI通信失败");
}
}
}关键特性分析
1. 工具注入机制
tools: recordTools; // 将工具定义注入到OpenAI请求中这里的 recordTools 是预定义的工具配置,告诉 OpenAI 可以调用哪些函数。
2. 工具调用检测
if (response.choices[0].message?.tool_calls) {
// 检测到工具调用,进行处理
}OpenAI 会在需要时返回 tool_calls 数组,包含需要执行的工具信息。
3. 响应增强
系统会在 AI 的原始回复后添加工具执行结果的通知,提升用户体验。
工具管理层设计
ToolService 核心架构
export class ToolService {
private handlers: IToolHandler[] = [];
constructor() {
// 注册所有工具处理器
this.handlers.push(new RecordToolHandler());
// 支持动态添加更多处理器
}
async processToolCalls(toolCalls: any[], context: any): Promise<any[]> {
const results = [];
for (const toolCall of toolCalls) {
const toolName = toolCall.function.name;
const handler = this.handlers.find((h) => h.canHandle(toolName));
if (handler) {
const result = await handler.handleToolCall(toolCall, context);
results.push(result);
} else {
results.push({
success: false,
message: `未找到工具 ${toolName} 的处理器`,
});
}
}
return results;
}
}设计模式分析
1. 策略模式(Strategy Pattern)
每个工具处理器实现相同的接口,可以动态选择处理策略:
export interface IToolHandler {
handleToolCall(toolCall: any, context: any): Promise<any>;
canHandle(toolName: string): boolean;
}2. 责任链模式(Chain of Responsibility)
通过 find() 方法查找能处理特定工具的处理器,实现了责任链的变种。
3. 工厂模式(Factory Pattern)
ToolService 充当工具处理器的工厂,根据工具名称创建对应的处理实例。
OpenAI 工具调用参数详解
tool_calls 数据结构
当 OpenAI 检测到需要调用工具时,会在响应中返回如下结构:
// OpenAI 返回的 tool_calls 示例
{
choices: [
{
message: {
tool_calls: [
{
index: 0,
id: "call_abc123",
type: "function",
function: {
name: "record",
arguments: '{"content": "用户今天学习了AI工具调用"}',
},
},
],
},
},
];
}参数字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
index | number | 工具调用在数组中的索引 |
id | string | 唯一标识符,用于跟踪调用 |
type | string | 调用类型,通常为 "function" |
function.name | string | 要调用的函数名称 |
function.arguments | string | JSON 字符串格式的函数参数 |
参数解析流程
async handleToolCall(toolCall: any, context: any): Promise<any> {
try {
// 1. 解析JSON参数
const args = JSON.parse(toolCall.function.arguments);
// 2. 参数验证
if (!args.content) {
return {
success: false,
message: "记录缺少内容参数",
};
}
// 3. 获取上下文信息
const userId = context.userId;
// 4. 执行业务逻辑
const result = await TimeLineService.addTimeline({
userId: parseInt(userId),
content: args.content,
createdAt: new Date(),
updatedAt: new Date(),
});
// 5. 返回执行结果
return {
success: true,
message: "记录已添加到时间轴",
content: args.content,
};
} catch (err) {
logger.error("处理record工具调用失败", err);
return {
success: false,
message: "添加时间轴记录失败",
};
}
}工具处理器实现
处理器接口设计
export interface IToolHandler {
/**
* 处理工具调用
* @param toolCall OpenAI返回的工具调用对象
* @param context 执行上下文(用户ID等)
* @returns 处理结果
*/
handleToolCall(toolCall: any, context: any): Promise<any>;
/**
* 判断是否能处理指定工具
* @param toolName 工具名称
* @returns 是否支持处理
*/
canHandle(toolName: string): boolean;
}RecordToolHandler 实现解析
export class RecordToolHandler implements IToolHandler {
canHandle(toolName: string): boolean {
return toolName === "record";
}
async handleToolCall(toolCall: any, context: any): Promise<any> {
try {
// 参数解析
const args = JSON.parse(toolCall.function.arguments);
// 业务逻辑执行
const timeline = await TimeLineService.addTimeline({
userId: parseInt(context.userId),
content: args.content,
createdAt: new Date(),
updatedAt: new Date(),
});
// 成功响应
return {
success: true,
message: "记录已添加到时间轴",
content: args.content,
};
} catch (err) {
// 错误处理
return {
success: false,
message: "添加时间轴记录失败",
};
}
}
}完整执行流程
1. 工具调用时序图

2. 详细执行步骤
用户发送消息:用户向 AI 发送包含可能需要工具调用的消息
AI 分析需求:OpenAI 分析消息内容,判断是否需要调用工具
返回工具调用:如需要,OpenAI 返回
tool_calls数组工具服务处理:
ToolService遍历所有工具调用查找处理器:根据工具名称查找对应的处理器
执行工具逻辑:处理器执行具体的业务逻辑
收集结果:汇总所有工具执行结果
响应增强:在 AI 回复中添加工具执行通知
返回用户:将增强后的响应返回给用户
扩展新工具的标准流程
1. 创建工具处理器
export class NewToolHandler implements IToolHandler {
canHandle(toolName: string): boolean {
return toolName === "new_tool";
}
async handleToolCall(toolCall: any, context: any): Promise<any> {
try {
const args = JSON.parse(toolCall.function.arguments);
// 实现具体业务逻辑
const result = await SomeService.processNewTool(args, context);
return {
success: true,
message: "新工具执行成功",
data: result,
};
} catch (error) {
return {
success: false,
message: "新工具执行失败",
};
}
}
}2. 注册工具处理器
constructor() {
this.handlers.push(new RecordToolHandler());
this.handlers.push(new NewToolHandler()); // 添加新的处理器
}3. 定义工具配置
export const newTools = [
{
type: "function",
function: {
name: "new_tool",
description: "新工具的描述",
parameters: {
type: "object",
properties: {
param1: {
type: "string",
description: "参数1的描述",
},
},
required: ["param1"],
},
},
},
];错误处理与监控
1. 多层错误处理
// OpenAI Service 层
try {
const response = await this.client.chat.completions.create(params);
} catch (error) {
logger.error("OpenAI API请求失败", error);
throw new Error("与OpenAI通信失败");
}
// Tool Service 层
if (handler) {
const result = await handler.handleToolCall(toolCall, context);
} else {
results.push({
success: false,
message: `未找到工具 ${toolName} 的处理器`,
});
}
// Handler 层
try {
// 业务逻辑
} catch (err) {
logger.error("处理工具调用失败", err);
return { success: false, message: "执行失败" };
}2. 日志监控
系统在关键节点都加入了详细的日志记录:
工具调用开始:记录工具名称和参数
执行结果:记录成功/失败状态
错误详情:记录具体错误信息和堆栈
总结
这个 AI 工具系统的设计具有以下优势:
架构优势
松耦合设计:各层之间通过接口交互,降低耦合度
高可扩展性:新增工具只需实现接口并注册
统一管理:工具调用统一由
ToolService管理错误隔离:单个工具失败不影响其他工具
技术亮点
依赖注入:便于测试和替换实现
策略模式:灵活的工具处理策略
完善的错误处理:多层错误处理和日志记录
响应增强:提升用户体验的智能通知
应用场景
企业 AI 助手:需要调用内部系统 API
个人助理应用:集成日程、笔记等功能
客服机器人:调用订单、库存等业务系统
内容管理平台:自动化内容处理和发布
这种架构为构建功能丰富的 AI 应用提供了坚实的基础,既保证了系统的稳定性,又具备了良好的扩展能力。