項目地址:alpbeta/ai-api-union
需求:實現兼容各大模型廠商api的流式對話和同步對話接口,本項目現兼容智譜、豆包、通義、通義版deepseek
設計
一個ChatController類對外暴露這兩個接口,入參都為ChatRequest請求類,屬性有會話id,大模型標識符和聊天消息列表,其中消息是一個實體類包含,消息id,關聯會話id,發送者角色,消息內容,創建時間。
流式對話返回的是響應式變成中的Flux類型,同步調用返回的是Sring類型。
一個ModelService接口,包含流式調用和同步調用兩個方法,入參為String字符串,出參與上述一致。
四個大模型api接口分別實現這個接口創建對應的實現類。
簡單工廠模式
創建一個工廠類,基于傳入的參數創建對應的大模型接口實現類。
工廠方法模式
創建一個工廠抽象類,繼承該接口創建各個大模型工廠類,各個大模型工廠類實現大模型接口實現類。
創建一個獲取工廠類,基于傳入的參數創建對應的大模型工廠,再創建對應大模型接口實現類
示意圖
實施
創建項目
通過 Spring Initializr 網站快速生成一個包含 Spring Boot 依賴的項目骨架,修改對應的partent版本,創建application.yml 激活dev環境,設置profiels.active:dev,創建application-dev.yml,修改端口為8090,server.port:8090(也可以不修改,默認.properties,偏向于yml)
創建測試controller
項目中如果沒有controller類,訪問8080端口時會報錯,找不到路徑;
創建一個ChatController類,增加@RestController @RequestMapping("api/chat")注解
創建testChat方法,方法前添加注解 @GetMapping("/testChat"), 入參為空,出參為String,方法內輸入return "test chat";
啟動項目,訪問http:localhost:8090/api/chat/testChat,頁面顯示上述方法返回的內容 test chat
創建dto包
創建Message實體類,ChatRequest請求類;
ChatRequest請求類,屬性有會話id,大模型標識符和聊天消息列表,其中消息是一個實體類包含,消息id,關聯會話id,發送者角色,消息內容,創建時間。基于這些內容創建對應的私有屬性,數據類型有Integer,String, TimeStamp, List,在類前加@Data注解,需先引入lombok依賴,引入該注解后,可以自動生成樣板代碼,如getter, setter, toString, equals, 無參構造函數,不需要顯示編寫這些方法,提高開發效率。
如需生成清晰的API文檔,需引入swagger依賴,或knif4j,再補充對應的配置文件,之后在實體類的類名和屬性前通過@Schema(description="xx")備注類和屬性名對應的含義。之后通過訪問http://項目ip:端口號/doc.html,可以訪問對應的接口文檔,如果接口的入參和出參有用到@Scheme注解的實體類,會顯示對應的備注內容。
創建項目實現接口類
在ChatController類增加syncChat和streamChat方法
兩個方法前增加PostMapping注解,路徑分別是("/syncChat")和("/stramChat")。入參增加@RequestBody注解,類型為ChatRequest。 出參分別是String和Flux
增加IModelService接口,包含synChat和stramChat方法,入參都為String,出參與上述保持一致
增加各大模型廠商api實現類
智譜接口實現類 ChatGLMServiceImpl,豆包接口實現類 ArkServiceImpl,通義接口實現類DashScopeServeceImpl,通義-deepseek實現類 DeepSeekServiceImple,都實現IModelService接口
引入各模型依賴,并在application.yml中配置api-key和modelname
分別在各模型接口類中實現同步調用和異步調用方法
實現豆包接口示例
在類前增加@Service注解表示為服務類bean容器,通過@Value注解,從配置文件中獲取api-key和modelName的值映射到該類對應屬性中。豆包大模型的火山引擎提供的ArkService服務類聲明為一個私有屬性,后續會使用該服務的方法。
該實現類除接口在的兩個方法,還增加了初始化和后處理方法,分別通過@PostConstruct和@PreDestory注解,在接口實現類Bean初始化完成后執行ArkService服務類的實例化,在Bean銷毀之前關閉ArkService的所有資源。
syncChat同步方法,使用該模型依賴提供的ChatMeaasge類創建消息列表對象,調用對應的add,role,content,build方法完成消息參數構建,再通過ChatCompletionRequest構建請求參數對象,通過arkService.creatChatCompletion方法輸入請求參數,獲取模型返回結果
stramChat異步調用方法,消息對象和請求對象構建方式與同步調用方式一致,通過arkService.streamChatCompletion方法獲取流式響應結果。返回類型為Flowable,需將其轉換成Flux,通過Flux.from(.map(response ->{return response...})).filter(content->!content.isEmpty())獲取返回結果
其他大模型實現類通過類似方法進行實現,通義與通義deepseek異步和同步返回的方法不一樣,前者通過result.getOutput().getText();獲取返回結果,后者方法調用更長一些
創建簡單工廠實現類
ModelSimpleFactory,基于傳入的參數返回不同的模型接口實現類,實現一個createModelService的方法。實現類用到@value注解從配置文件中獲取變量值,不能通過new的方式創建模型類,需通過反射機制,通過上下文的getbean方法創建:applicationContext.getBean。
在ChatController類補充syncChat和streamChat方法邏輯
獲取請求對象中的模型標識,消息列表。基于標識創建模型服務對象,將消息傳入模型服務返回響應的結果