大家好,很高興又見面了,我是"高級前端進階",由我帶著大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點讚、收藏、轉發,您的支持是我不斷創作的動力。
今天給大家帶來的主題是AI.JSX,即一個使用 Javascript 和 JSX 構建 AI 應用程式的框架。話不多說,直接進入正題!
1.什麼是 AI.JSX
AI.JSX 是一個使用 Javascript 和 JSX 構建 AI 應用程式的框架。 雖然 AI.JSX 不是 React,但它的設計與 ReAct 非常相似,同時還支持與基於 React 的項目無縫集成。 藉助 AI.JSX,開發者不僅可以使用 JSX 來描述 UI,還可以使用它來描述大型語言模型(例如 ChatGPT)應如何集成到應用程式的其餘部分中。 最終形成一個強大的組合,從而使智能可以深入嵌入到應用程式堆棧中。
AI.JSX 旨在為開發者提供兩項開箱即用的重要功能:
- 一種直觀機制,用於編排多個 LLM 調用,以模塊化、可重複使用組件的形式表示
- 將 UI 組件與 AI 組件無縫交織的能力。 這意味著開發者可以依靠 LLM 從一組提供的 React 組件動態構建 UI
AI.JSX 也可用於創建獨立的 LLM 應用程式,該應用程式可以部署在支持 Node.JS 的任何地方,也可以用作更大的 React 應用程式的一部分。AI.JSX 具有以下優勢:
- 通過模塊化、可重複使用的組件進行提示工程(Prompt engineering)
- 能夠在模型提供者和 LLM 配置(例如溫度)之間輕鬆切換
- 內置對工具(ReAct 模式)、文檔問答、思維鏈等的支持
- 能夠直接將 LLM 調用與標準 UI 組件結合在一起,包括 LLM 從一組提供的組件渲染 UI 的能力
- 內置流媒體支持
- 對 NextJS 和 Create React App 的一流支持(更多功能即將推出)
- 全面支持 LangChainJS
目前 AI.JSX 在 Github 上通過 MIT 協議開源,雖然只有 1~2 個星期,已經有超過 130+的 star、是一個值得關注的前端開源項目。
2.AI.JSX 與 React 的區別
AI.JSX 不是 React,儘管它支持與 React 無縫集成。 AI.JSX 與 React 客戶端組件相比,它更類似於 React 伺服器組件。
相反,AI.JSX 是一個組件化的、類型安全的系統,用於編寫提示並控制基於 LLM 的應用程式的流程。
2.1 React 有狀態/ AI.JSX 無狀態
在 React 中, JSX 是一棵有狀態樹被安裝到 DOM 中。例如:
Function Counter() {
const [count, setCount] = useState(0);
return (
<>
Count: {count}
<button onClick={() => setCount((count) => count + 1)}>Increment</button>
</>
);
}
當渲染此組件時,它位於 DOM 中,維護狀態並在生命周期中變化。 在 AI.JSX 中,沒有生命周期的概念,組件是無狀態的並且只渲染一次。
2.2 AI.JSX 是異步/流原生的
在 React 中,客戶端組件必須是同步的,伺服器組件可以返回 Promise。 在 AI.JSX 中,組件可以返回 Promise 或生成器 generator:
async function MyAsyncComponent() {
const data = await loadData();
const formattedData = processData(data);
return <UserMessage>Please summarize: {formattedData}</UserMessage>;
}
可以直接將 Promise 直接嵌入到 JSX 中:
function MyAsyncComponent() {
return <UserMessage>Please summarize: {loadData()}</UserMessage>;
}
2.3 Context 上下文
在 React 客戶端組件中,可以使用 useContext 來訪問上下文。在 React Server 組件中,不能使用上下文。 在 AI.JSX 中,有一個類似的上下文概念。
// 創建一個默認值為 0 的上下文。
const Temperature = AI.createContext(0.0);
// 創建一個讀取上下文的組件
function CharacterGenerator(props: Record<string, never>, { getContext }: AI.RenderContext) {
return (
<Completion temperature={getContext(Temperature)}>
Create a bio for a character in an RPG game.
</Completion>
);
}
showInspector(
<>
{/* 設置溫度值 */}
<Temperature.Provider value={0.0}>
:{'\n'}
<CharacterGenerator />
</Temperature.Provider>
{/* 設置溫度值 */}
<Temperature.Provider value={2.0}>
:{'\n'}
<CharacterGenerator />
</Temperature.Provider>
</>
3.AI.JSX & LangChain
3.1 AI.JSX 和 LangChain 差異
LangChain 是一個開源的應用開發框架,目前支持 Python 和 TypeScript 兩種程式語言。它賦予 LLM 兩大核心能力:
- 數據感知,將語言模型與其他數據源相連接
- 代理能力,允許語言模型與其環境互動
LangChain 的主要應用場景包括:個人助手、基於文檔的問答、聊天機器人、查詢表格數據、代碼分析等。
AI.JSX 和 LangChain 都提供了一種構建提示、編排對 LLM 的多次調用以及與外部數據交互的方法。 對於 LangChain 來說,這主要是通過提示模板和鏈(Prompt Templates and Chains)來完成的。
在 AI.JSX 中,開發者可以使用 JSX 來處理字符串組合(替換提示模板)和組合(鏈)。 AI.JSX 認為 JSX 是組織基於 LLM 的應用程式的高級抽象,因為它提供:
- 一組更好的原語
- 可以聲明式和顯式地組成
- 更容易理解且更靈活的抽象
3.2 為什麼選擇 AI.JSX 而不是 Chains?
LLM 應用程式受益於編排框架(orchestration framework),該框架:
- 可以輕鬆連接一個 LLM 調用的輸出和另一個 LLM 調用的輸入
- 提供可重用性/封裝範例
鏈(Chains)抽象了傳遞值、應用邏輯和返回值,但 AI.JSX 認為隱藏這一點並不總是正確,因為其已經有 function。 鏈使開發者需要學習新的語義來完成已經知道如何做的事情。
而且鏈作為復用的工具也不太靈活。 考慮鏈 STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION。 它採用結構化的工具描述,進行零次提示,並使用 ReAct 模式。 這是從以下獨立屬性中選擇的一個:
- 結構化與非結構化
- 聊天與非聊天完成
- Zero shot vs few shot
- ReAct vs not
這些屬性的組合可能產生 16 種可能的鏈,而 LangChain 只提供了一小部分。 如果想要不同的組合怎麼辦? 或者想用自己的版本替換其中一層(例如 ReAct)?
AI.JSX 通過提供每個獨立屬性作為原語來解決這個問題,然後讓開發者自己組裝它們:
function MyComponent({ query }: { query: string }) {
return (
<Structured tools={myTools}>
<ChatCompletion>
<SystemMessage>
<MyFewShots />
<ReAct />
</SystemMessage>
<UserMessage>{query}</UserMessage>
</ChatCompletion>
</Structured>
);
}
所有組成都存在了,因此開發者可以組裝強大的構建塊以滿足需求。
3.3 AI.JSX 與 LangChain 生態輕鬆互操作
LangChain 與各種生態系統工具有許多有用的集成,例如:
- PDF 文件加載器
- 非結構化加載器 (Loader for Unstructured)
- 色度矢量資料庫 (Chroma Vector DB)
- Pinecone 矢量資料庫(Pinecone Vector DB)
這些很容易從 AI.JSX 中使用,因為它們只是函數:
import { PineconeClient } from "@pinecone-database/pinecone";
import { OpenAIEmbeddings } from "langchain/embeddings/openai";
import { PineconeStore } from "langchain/Vectorstores/pinecone";
import { ChatCompletion, SystemMessage, UserMessage } from 'ai-jsx/completion-components';
function getVectorStore() {
const client = new PineconeClient();
await client.init({
apiKey: process.env.PINECONE_API_KEY,
environment: process.env.PINECONE_ENVIRONMENT,
});
const pineconeIndex = client.Index(process.env.PINECONE_INDEX);
const vectorStore = await PineconeStore.fromExistingIndex(
new OpenAIEmbeddings(),
{ pineconeIndex }
);
}
function MyDocsFunction({query}: {query: string}) {
const docs = await getVectorStore().similaritySearch(query);
return <ChatCommpletion>
<SystemMessage>
You are a knowledge base agent who answers questions based on these docs: {JSON.stringify(docs)}
</SystemMessage>
<UserMessage>{query}</UserMessage>
</ChatCompletion>
}
4.開始使用 AI.JSX
4.1 AI.JSX Hello World
要使用任何 AI.JSX 示例(使用 OpenAI 大語言模型),首先需要從 OpenAI API 儀錶板獲取 OpenAI API 密鑰。要快速實現 AI.JSX 的「hello world」,請執行以下操作:
$ export OPENAI_API_KEY=<your OpenAI API key>
$ git clone https://github.com/fixie-ai/ai-jsx-template
$ cd ai-jsx-template
$ npm install
$ npm start
執行上面命令後會看到如下輸出:
Oh, wond'rous beast of language, vast and strong,
Whose depths of knowledge ne'er have been surpassed,
A marvel wrought by human mind and thought,
At once both tool and servant to be sought.
[...]
4.2 構建並運行 AI.JSX 演示應用程式
AI.JSX GitHub 存儲庫有許多演示應用程式,開發者可以自行檢查 AI.JSX 存儲庫並從獲取相關示例。
以下命令應構建整個 AI.JSX 存儲庫:
$ git clone https://github.com/fixie-ai/ai-jsx
$ cd ai-jsx
$ yarn
$ yarn build
還可以在目錄 packages/examples、packages/tutorial、packages/create-react-app-demo 和 packages/nextjs-demo 中找到示例。
然後可以使用 yarn workspace 從 ai-jsx checkout 的頂層運行各種示例,如下所示:
$ yarn workspace tutorial run part1
$ yarn workspace examples run demo:debate
$ yarn workspace create-react-app-demo start
4.3 AI.JSX 生成 AI 響應
下面是一個使用 AI.JSX 生成對提示的 AI 響應的簡單示例:
import * as AI from "ai-jsx";
import { ChatCompletion, UserMessage } from "ai-jsx/core/completion";
const app = (
<ChatCompletion>
<UserMessage>Write a Shakespearean sonnet about AI models.</UserMessage>
</ChatCompletion>
);
const renderContext = AI.createRenderContext();
const response = await renderContext.render(app);
console.log(response);
下面是一個更複雜的示例,它使用內置的 <Inline> 組件在 JSON 對象中逐步生成多個欄位:
function CharacterGenerator() {
const inlineCompletion = (prompt: Node) => (
<Completion stop={['"']} temperature={1.0}>
{prompt}
</Completion>
);
return (
<Inline>
Generate a character profile for a fantasy role-playing game in JSON
format.{"\n"}
{"{"}
{"\n "}"name": "{inlineCompletion}",
{"\n "}"class": "{inlineCompletion}",
{"\n "}"race": "{inlineCompletion}",
{"\n "}"alignment": "{inlineCompletion}",
{"\n "}"weapons": "{inlineCompletion}",
{"\n "}"spells": "{inlineCompletion}",
{"\n}"}
</Inline>
);
}
5.本文總結
本文主要和大家介紹 AI.JSX,即一個使用 Javascript 和 JSX 構建 AI 應用程式的框架。相信通過本文的閱讀,大家對 AI.JSX 會有一個初步的了解。
因為篇幅有限,關於 AI.JSX 的更多用法和特性文章並沒有過多展開,如果有興趣,可以在我的主頁繼續閱讀,同時文末的參考資料提供了大量優秀文檔以供學習。最後,歡迎大家點讚、評論、轉發、收藏,您的支持是我不斷創作的動力。
參考資料
https://github.com/fixie-ai/ai-jsx
https://docs.ai-jsx.com/guides/rules-of-jsx#context
https://docs.ai-jsx.com/is-it-langchain
https://medium.com/databutton/getting-started-with-langchain-a-powerful-tool-for-working-with-large-language-models-286419ba0842