使用 LangChain JS 來寫 LLM 程式

| | 0 Comments| 10:12
Categories:

之前在《使用 llama.cpp 自己架一個 OpenAI 相容伺服器》介紹了怎麼用 llama.cpp 來架設一個輕量化的 OpenAI API 相容伺服器,而接下來呢,則是來簡單介紹一下怎麼透過 LangChain 這個框架、來使用這個 LLM 的伺服器吧。

首先,LangChain 的官網是:https://www.langchain.com/,他的概念基本上有點像是提供了許多不同的功能模組(也有不少社群提供的)、讓開發者透過把各種功能模組串起來、組成自己需要的 LLM 應用程式。理論上透過 LangChain 提供的功能,可以快速地組出自己需要的功能;像是官方就有提供 RAG、agent 等功能的範例可以參考(能不能弄出自己想要的結果就是另一回事了)。

不過另一方面,目前 LangChain 也還在開發中,版本還在 0.2 版而已,所以之後的 API 可能都會有變動,現在寫的程式之後能不能用也不知道。 XD
所以如果是要拿來開發服務或是產品的話,這點可能是要考量的。

另外,對於只是想要測試的人來說,其實有不少模組實際上都需要使用第三方的雲端服務、需要有 API key 才能用,所以其實使用上不見得可以真的很方便地上手。 :p

接下來,就來先看 LangChain 的架構吧~

在架構圖裡面,LangChain 是左下角的一塊,實質上包括了核心(Core)和社群(community)兩個部分(感覺上社群的東西好像還比較多?);而這部分都有提供 Python 和 JavaScript 兩種語言的套件,對於不會 Python 的人算是提供了另一種選擇。

而除了 LangChain 外,其實他的框架外還有 LangSmith 和 LangServe 這些東西,不過這邊暫時都不會去使用就是了;另外,雖然架構圖裡沒有,但是他後來還有一個 LangGraph,這部分倒是之後可能會拿來用的東西了。


而由於 Heresy 個人對於 Python 完全不熟,所以這邊就是拿相對熟悉一點的 JavaScript 來玩看看了~

LangChain JavaScript 版的文件是在 https://js.langchain.com/,裡面有 Tutorials 和 How-To Guides,算是相對容易上手的了~

而 Heresy 這邊的測試環境,則是使用 deno 這個 JavaScript 的執行環境(官網),為了能使用相對乾淨的環境來測試,這邊是使用 docker 的版本,使用的映象檔是 denoland/deno,執行的指令是:

docker run -it --rm --network host denoland/deno bash

進入容器後,為了安裝套件,這邊還是會先去安裝 npm 這個套件管理工具(也可以用別的):

apt update && apt upgrade -y
apt install npm -y

之後,則是建立一個工作用的資料夾「llm_test」,之後要在裡面安裝需要的套件。

mkdir llm_test
cd llm_test

接下來,則是來寫一個最簡單的測試程式,來確認可以成功地連上之前自己架設的 llama.cpp 伺服器了!

這邊在進入 deno 的環境前,會先需要透過 npm 安裝套件:

npm install langchain @langchain/openai

接下來就可以執行 deno、進入 JavaScript 的互動環境,然後執行下面的指令:

const conf = {apiKey: "na", configuration: {baseURL: http://127.0.0.1:8080/v1}};
 
import { ChatOpenAI } from "@langchain/openai";
const llm = new ChatOpenAI(conf);
await llm.invoke("what is llama 3?");

這邊的內容很簡單,只有四行:

  • 第一行是定義一個 conf、用來設定 OpenAI API Server 的參數。
    由於自己自架設的,所以需要指定 baseURL 來指到自己架設的伺服器,網址的部分要視狀況修改;而如果伺服器的部分有設定需要 API key 的話,這邊的 apiKey 也要修改,沒有的話亂打就可以了(但是可能一定要給)。

  • 把 LangChain 的 OpenAI 模組匯入使用。
    如果是使用 node.js 的話,可能得改成用 require 的。

  • 建立 ChatOpenAI 的物件 llm,這邊要把之前的設定參數傳進去。

  • 透過 invoke() 來送出提示(prompt)。

之後,如果都正常的話,就會得到 OpenAI API 伺服器的推論結果了。它的結果應該會是像下面的形式:

AIMessage {
lc_serializable: true,
lc_kwargs: {
content: “# What is LLaMA\n” +
“\n” +
“LLaMA is a large language model developed by Meta Research in 2022. It was trained “… 691 more characters,
tool_calls: [],
invalid_tool_calls: [],
additional_kwargs: { function_call: undefined, tool_calls: undefined },
response_metadata: {}
},
lc_namespace: [ “langchain_core”, “messages” ],
content: “# What is LLaMA\n” +
“\n” +
“LLaMA is a large language model developed by Meta Research in 2022. It was trained “… 691 more characters,
name: undefined,
additional_kwargs: { function_call: undefined, tool_calls: undefined },
response_metadata: {
tokenUsage: { completionTokens: 201, promptTokens: 19, totalTokens: 220 },
finish_reason: “stop”
},
tool_calls: [],
invalid_tool_calls: [],
usage_metadata: { input_tokens: 19, output_tokens: 201, total_tokens: 220 }
}

如果要想要看到完整的內容的回覆內容的話,則可以寫成:

let res = await llm.invoke("what is LLaMA 3?");
console.log(res.content);

而如果想要詢問其他內容的話,就只要替換 invoke() 的內容就可以了。


最基本的使用大概就是這樣了。

當然啦,由於這是最為簡單的操作,所以功能也相當有限;他理所當然地不會去找模型外的資料,同時也沒有前後文的記憶能力。

在這樣簡單的操作的狀況下,Heresy 試過幾個大語言模型給的回覆其實常常都還滿糟糕的,直接去 ChatGPT 或 Copilot 玩的效果都好很多。

而且不知道是相容性、或是參數設定的問題還是怎樣,在產生回復的時候常常後面會出現很多重複的文字,直到長度到達上限,變成在無謂地浪費時間…

感覺上,真的要玩到「能用」可能還得研究好一段時間了。 XD


參考:LangChain是什麼?AI開發者必須了解的LLM開源框架

Leave a Reply

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *