本文描述了底層的大語言模型(LLM)API。高階的LLM API參見AI服務。
1 LLM API的型別
1.1 LanguageModel
非常簡單—,接受一個String
作為輸入,並返回一個String
作為輸出。
該API現正逐漸被聊天API(第二種API型別)取代。
1.2 ChatLanguageModel
這種API接受一或多個ChatMessage
作為輸入,並返回一個AiMessage
作為輸出。 ChatMessage
通常包含文字,但有些LLM還支援混合文字和Image
的輸入。如OpenAI的gpt-4o-mini
和Google的gemini-1.5-pro
都屬於這種。
LangChain4j中,將不再擴充套件對LanguageModel
的支援,因此所有新功能採用ChatLanguageModel
API。
ChatLanguageModel
是LangChain4j中的底層API,提供了最大的功能和靈活性。還有高階API(如Chain
和AiServices
)。
除了ChatLanguageModel
和LanguageModel
,LangChain4j還支援以下型別的模型:
EmbeddingModel
:可將文字轉換為Embedding
ImageModel
:可生成和編輯Image
。ModerationModel
:可檢查文字中是否包含有害內容。ScoringModel
:可根據查詢對多段文字進行評分(或排名),以確定每段文字與查詢的相關性。這在RAG(檢索增強生成)中非常有用。
2 ChatLanguageModel API
public interface ChatLanguageModel {
String generate(String userMessage);
...
}
generate
接受一個String
作為輸入並返回一個String
作為輸出,類似LanguageModel
。這是一個便捷方法,可快速使用它,無需將String
包裝在UserMessage
中。
但這才是實際的聊天API:
...
Response<AiMessage> generate(ChatMessage... messages);
Response<AiMessage> generate(List<ChatMessage> messages);
...
這些generate
接受一或多個ChatMessage
作為輸入。ChatMessage
是一個表示聊天訊息的基礎介面。
3 ChatMessage的型別
目前有四種聊天訊息型別,每種訊息對應不同的“來源”:
UserMessage
:這是來自使用者的訊息。使用者可以是您的應用程式的終端使用者(人類)或應用程式本身。
根據LLM支援的模態,UserMessage
可以包含僅文字(String
)或文字和/或影像(Image
)。AiMessage
:AI生成的訊息,通常是對UserMessage
的響應。 如你所見,generate
返回一個包含在Response
中的AiMessage
。AiMessage
可包含文字響應(String
)或請求執行工具(ToolExecutionRequest
)。ToolExecutionResultMessage
:ToolExecutionRequest
的結果SystemMessage
:系統的訊息。通常,作為開發者應定義此訊息的內容。可在此編寫關於LLM在對話中的角色、應如何表現、以何種風格回答等指令。 LLM被訓練得更關注SystemMessage
,因此要小心,最好不要讓終端使用者隨意定義或注入一些輸入到SystemMessage
中。 它通常位於對話的開始。
如何在對話中組合它們?
最簡單的場景,可在generate
方法中提供一個UserMessage
例項。 這與第一個版本的generate
方法類似,它接受一個String
作為輸入。 主要區別在於它現在返回的不是String
,而是Response<AiMessage>
。
Response
是一個包裝了內容(負載)的物件,經常看到它作為*Model
類的返回型別。 除了內容(在這種情況下是AiMessage
),Response
還包含生成的元資訊:
TokenUsage
,統計了輸入(提供給generate
方法的所有ChatMessage
)中包含的token數及輸出(AiMessage
)中生成的token數,並給出總數(輸入 + 輸出)。需要這些資訊來計算每次呼叫LLM的成本FinishReason
,列舉型別,表示生成停止的各種原因。通常,如果LLM自行決定停止生成,則原因會是FinishReason.STOP
建立UserMessage
有多種方式,取決於內容。最簡單的
new UserMessage("Hi")或
UserMessage.from("Hi")`。
4 多個ChatMessage
為啥要提供多個ChatMessage
作為輸入,而不僅是一個? 因為LLM本質上是無狀態的,這意味著它們不會維護對話的狀態。 因此,如果你想支援多輪對話,則需要自己管理對話的狀態。
假設想構建一個聊天機器人。想象一下使用者和聊天機器人(AI)之間的簡單多輪對話:
- 使用者:你好,我叫JavaEdge
- AI:你好JavaEdge,我能幫你什麼?
- 使用者:我叫什麼名字?
- AI:JavaEdge
這就是與ChatLanguageModel
互動的樣子:
UserMessage firstUserMessage = UserMessage.from("Hello, my name is JavaEdge");
AiMessage firstAiMessage = model.generate(firstUserMessage).content(); // JavaEdge,我能幫你什麼?
UserMessage secondUserMessage = UserMessage.from("What is my name?");
AiMessage secondAiMessage = model.generate(firstUserMessage, firstAiMessage, secondUserMessage).content(); // JavaEdge
如你所見,在第二次呼叫generate
方法時,不僅提供了secondUserMessage
,還提供了對話中的前幾條訊息。
手動維護和管理這些訊息比較繁瑣,因此引入ChatMemory
。
關注我,緊跟本系列專欄文章,咱們下篇再續!
作者簡介:魔都架構師,多家大廠後端一線研發經驗,在分散式系統設計、資料平臺架構和AI應用開發等領域都有豐富實踐經驗。
各大技術社群頭部專家博主。具有豐富的引領團隊經驗,深厚業務架構和解決方案的積累。
負責:
- 中央/分銷預訂系統效能最佳化
- 活動&券等營銷中臺建設
- 交易平臺及資料中臺等架構和開發設計
- 車聯網核心平臺-物聯網連線平臺、大資料平臺架構設計及最佳化
- LLM Agent應用開發
- 區塊鏈應用開發
- 大資料開發挖掘經驗
- 推薦系統專案
目前主攻市級軟體專案設計、構建服務全社會的應用系統。
參考:
- 程式設計嚴選網
本文由部落格一文多發平臺 OpenWrite 釋出!