前言前边写了很多和AI相关模块的设计可能会有些糊涂这个软件里AI到底是怎么调用的这边博客用来详细阐述AI的具体调用实现也算是我自己的一个相关总结和反思。一、AI Orchestrator这是AI能力编排服务协调整个AI能力调用流程包括事件管理、余额检查、模型调用和计费。包含一个处理AI能力请求的函数process给这个函数提供用户id和AI能力请求首先会获取这个AI能力具体是什么TTS还是LLM等然后调用获取对应能力的函数在注册表中寻找创建一个状态为待处理的AI事件预估所需Credits检查并预扣用户的余额预扣成功才把AI事件状态变为处理中防止进行本次活动之后发现用户余额不足。调用能力执行然后根据实际用量调整扣费将AI事件状态改为成功。这个类还定义了四种AI能力的便捷调用方法①TTS便捷调用参数列表封装文本以及声音将参数和AI能力类型TTS构建请求对象然后调用process函数提取结果中的音频url。②STT便捷调用参数列表封装音频url以及参考语言将参数和AI能力类型STT构建请求对象然后调用process函数提取结果中的文本。③LLM便捷调用参数列表封装消息列表具体格式为 [{role: user/assistant/system, content: ...}]将参数和AI能力类型STT构建请求对象然后调用process函数提取结果中的字符串回复。④文生图便捷调用参数列表封装提示词以及图片尺寸将参数和AI能力类型STT构建请求对象然后调用process函数提取结果中的图片url。二、AI能力注册表注册表在一开始就查找所有实现AI能力的统一接口的类然后获取他们的AI能力类型进行注册这样让Orchestrator只依赖注册表不用写复杂的if-else语句。然后通过get方法返回具体AI能力实现类的实例对象。三、AI能力的统一接口所有AI能力都应满足这个接口这个接口定义了四个函数分别是能力标识类型、具体执行、预估价格、计量单位这样防止了不同AI能力的函数不同实现了统一调用AI同时也方便创建新的AI能力。四、AI模型适配器注册表注册表在一开始就查找所有实现ModelAdapter接口的类获取他们的模型然后从他们的配置文件中获取模型能力等配置进行注册分别注册两个Map一个用来注册模型的能力比如modelsByCapability { LLM: [GPT4Adapter, QwenAdapter, WenxinAdapter], TTS: [AliyunTtsAdapter, AzureTtsAdapter], STT: [AliyunSttAdapter] }还有一个用来注册模型的名字用于检索modelsByName { gpt-4: GPT4Adapter实例, qwen-max: QwenAdapter实例, aliyun-tts: AliyunTtsAdapter实例 }然后初始化API密钥池为了管理调用AI模型所需的所有API密钥实现负载均衡、故障转移和智能调度。这个模型注册表还包括根据模型能力来获取该能力的所有模型以及获取可用模型配置文件可用以及模型自己认为可用等函数。五、模型适配器统一接口每个具体模型需要实现此接口具体包括获取模型名称、获取供应商名称、调用具体模型、检查模型是否可用、计算本次调用成本。六、API密钥池管理组件每个密钥状态包含五个属性真实的API密钥是否可用连续失败3次后变为false限流恢复时间连续失败次数记录连续失败次数成功时归零最后使用时间。采取轮询负载均衡策略每次调用一个模型的时候首先获取所有可用的api然后利用轮询选择密钥如果一个密钥被调用三次都失败了则把它熔断同时对于频繁调用的密钥进行限流防止频繁使用被限制。七、模型路由器7.1 接口设置一个模型路由器接口输入需要的AI能力以及可用模型列表返回最合适的模型所有的AI能力模型将实现这个接口。7.2 LLM路由器想法很简单如果请求包含图片则选用qwen-vl-plus如果不包含图片则选用qwen-plus但为了防止这两个模型出错还设置了备选方案当这两个模型在可用模型列表找不到的时候就使用可用模型列表的第一个模型。7.3 TTS、文生图路由器采用最简单的策略直接选择第一个可用的模型。八、具体AI能力8.1 LLM能力LlmCapability是AiCapability接口的具体实现负责处理所有大语言模型对话请求.LLm的请求是消息列表首先提取请求中的消息然后在模型注册表中寻找类型是LLm的可用模型通过路由器选择最合适的模型从ApiKeyPool获取可用密钥然后构建模型请求调用真正的模型调用成功标记密钥成功调用失败标记密钥失败最后获取对应的响应。剩下的TTS、STT、文生图能力流程与LLM类似不赘述了。8.2 语音评测能力这个流程和前边的几个类似唯一的不同在于它设置了很严格的验证输入它需要检验文本是否为空以及长度限制在这里分为两类一类是朗读句子一类是朗读章节这两类文本长度限制不同还需要检查音频文件是否为空以及大小限制同时还有音标检验音标检验是在验证音标注解的格式是否正确这是讯飞ISE API特有的功能用于指导用户如何正确发音。都通过检验后才开始走流程。九、具体AI模型适配器9.1 LLM模型9.1.1 Qwen-Plus 模型适配器首先提取请求中的消息然后转换消息格式从Map格式转换为DashScope的Message格式因为阿里云DashScope SDK的API设计要求传入的是强类型的ListMessage而不是灵活的ListMap[{role: system,content: 你是一个热情好客的导游专门介绍北京的历史文化。},{role: user,content: 你好我想去北京旅游。},{role: assistant,content: 欢迎来到北京我是您的导游故宫、长城等都是必去景点。},{role: user,content: 请详细介绍一下故宫的开放时间。}]构建Generation请求参数把DashScope的Message格式转换成阿里云DashScope API能够识别的具体参数。然后真正发送请求到阿里云DashScope API并接收响应层层提取回复内容将回复封装到响应中返回给前端。9.1.2 Qwen-VL-Plus 模型适配器整体流程与Qwen-Plus相似唯一不同是Qwen-Plus请求内容是string而Qwen-VL-Plus请求类型是objectcontent可以是复杂结构所以需要把不同格式的content统一转换成DashScope 多模态 API要求的列表格式如果是纯文本需要转化为list如果是含有图片和纯文本则不需要转换本身就是list。此外阿里云的多模态对话API每次调用只能接收一条消息而不是完整的对话历史所以每次只发送最后一条消息。9.2 image模型适配器-Qwen-Image-Plus首先提取请求中的提示词构建一个符合阿里云多模态API要求的消息对象然后构建参数包括水印设置、提示词扩展、负面提示词、图片尺寸等。构建Generation请求参数然后真正发送请求到阿里云DashScope API并接收响应层层提取回复的图片url将回复封装到响应中返回给前端。9.3 STT模型适配器-Qwen3-ASR-Flash首先提取请求中的audioUrl、语言、逆文本标准化用于控制是否将识别出的口语化数字转换成书面格式然后分别构建用户消息和系统消息用户消息封装着用户提供的音频文件系统消息用于配置定制化识别的上下文。然后配置语音识别的参数因为阿里云ASR API无法直接识别提取出来的语言、逆文本标准化。构建DashScope请求参数然后真正发送请求到阿里云DashScope API并接收响应层层提取回复的文本将回复封装到响应中返回给前端。9.4 TTS模型适配器-Qwen3-TTS-Flash首先提取请求中的文本、声音、语言类型然后直接构建DashScope请求参数然后真正发送请求到阿里云DashScope API并接收响应层层提取回复的音频url把阿里云TTS生成的临时音频文件转存到自己的OSS上获取一个永久有效的访问链接。将回复封装到响应中返回给前端。