Askit是一個用於打字稿的語言插件,使您能夠直接在您的編程環境中利用大型語言模型(例如GPT-4)的功能(例如GPT-4)的功能,不需要復雜的API。 Askit的廣泛申請包括:
Askit建立在OpenAI API上,提供了一個用戶友好的界面,用於將LLMS納入您的應用程序。您不僅可以在打字稿中,而且可以在JavaScript和Python中使用Askit 。
有關將askit與JavaScript集成,請參閱相應的JavaScript部分。
如果Python是您的首選語言,您可以通過訪問我們的專用askit(Pyaskit)頁面了解有關如何利用Askit的更多信息。
類型引導的輸出控制:在指定類型中獲取響應。
基於模板的功能定義:使用提示模板定義函數。
代碼生成:從統一接口生成功能。有關更多詳細信息,請參見帶有Askit的代碼生成。
按示例編程(PBE):使用示例定義函數。請參閱以示例的方式參見編程,以獲取更多詳細信息。
在開始之前,請確保系統上安裝了Node.js和NPM。然後,執行以下命令:
npm install ts-askit此軟件包依賴於ts-patch 。要安裝ts-patch ,請運行:
npx ts-patch install將以下片段添加到您的tsconfig.json :
"compilerOptions" : {
"plugins" : [{ "transform" : " ts-askit/transform " }]
}此修改允許打字稿編譯器支持ask的類型參數,並在Askit中define API。
ts-patch軟件包對於釋放Askit的全部潛力至關重要,因為它擴展了打字稿編譯器以完全集成了Askit類型系統。儘管可以在沒有ts-patch情況下使用Askit,但此集成提供了更豐富的體驗。
在使用askit之前,您需要將OpenAI API密鑰設置為環境變量OPENAI_API_KEY :
export OPENAI_API_KEY= < your OpenAI API key > <your OpenAI API key>是一個看起來像這樣的字符串: sk-<your key> 。您可以在OpenAI儀表板中找到API鍵。
您還可以將模型名稱指定為環境變量ASKIT_MODEL :
export ASKIT_MODEL= < model name > <model name>是您要使用的模型的名稱。最新的Askit經過gpt-4和gpt-3.5-turbo-16k測試。您可以在OpenAI API文檔中找到可用型號的列表。
以下是一些介紹性示例:
import { ask } from 'ts-askit' ;
ask < string > ( 'Paraphrase "Hello World!"' ) . then ( ( result ) => {
console . log ( result ) ;
} ) ;在此示例中, ask是一個API函數,允許您的程序對大型語言模型(LLM)提出查詢。類型參數表示LLM的預期輸出類型。在這裡,輸出類型是string 。提示以自然語言為論點傳遞,描述了LLM執行的任務。 ask是異步的,返回指定輸出類型的Promise 。上面的代碼段應該打印出這樣的內容:
Greetings, Universe!
對於帶有參數的提示,您可以使用以下方式使用define API:
import { define } from 'ts-askit' ;
const paraphrase = define < string > ( 'Paraphrase {{text}}' ) ;
paraphrase ( { text : 'Hello World!' } ) . then ( ( result ) => {
console . log ( result ) ;
} ) ; define是一個API函數,允許您定義自定義功能。其類型參數指示LLM的輸出類型,因此表示函數的返回值。該函數接收一個字符串模板作為參數,用作LLM的任務提示。該模板可以包括包含在雙捲髮括號中的參數。在上面的示例中, text是模板中的一個參數,並且可以是任何有效的JavaScript標識符。
定義功能後,可以像任何其他功能一樣調用它。此函數接受對像作為參數,該參數映射到模板參數的值。在這種情況下, text映射到字符串“ Hello World!”。
Askit擅長從自然語言描述中生成代碼。這是一個例子:
import { define } from 'ts-askit' ;
const sort = define < number [ ] , { numbers : number [ ] } > (
'Sort {{numbers}} in ascending order'
) ;此示例顯示一個函數,該函數以升序順序排列數字數組,並利用define API指示LLM來定義函數。儘管概念效率有效,但由於每個功能調用都需要一個新的LLM任務,因此該方法似乎在計算上很重。
要簡化此過程,我們可以利用LLM生成排序函數的代碼,而不是訴諸於每個分類任務的LLM。由於Askit的代碼生成功能,這可以優化功能,而無需進行實施任何更改。
上述函數的代碼可以通過三個步驟生成:
tsc編譯代碼。 Askit Analyzer掃描代碼並生成一個JSONL文件,其中包含define並ask API調用的詳細信息。npx askgen < jsonl file >tsc重新編譯代碼。這次,得益於Askit的自動更換功能, define和ask API調用分別由新生成的功能的參考和調用代替。 Askit允許您以示例(PBE)來利用編程的功能。 PBE通過使您能夠通過示例而不是硬編碼邏輯來定義功能來簡化編程過程。下面的示例通過向您展示如何使用PBE和Askit添加兩個二進制數字來說明這一點。
import { define , Example } from 'ts-askit' ;
const trainingExamples : Example [ ] = [
{ input : { x : '1' , y : '0' } , output : '1' } ,
{ input : { x : '1' , y : '1' } , output : '10' } ,
{ input : { x : '101' , y : '11' } , output : '1000' } ,
{ input : { x : '1001' , y : '110' } , output : '1111' } ,
{ input : { x : '1111' , y : '1' } , output : '10000' } ,
] ;
const testExamples = [
{ input : { x : '0' , y : '1' } , output : '1' } ,
{ input : { x : '10' , y : '0' } , output : '10' } ,
{ input : { x : '110' , y : '10' } , output : '1000' } ,
] ;
const addInBase2 = define < string , { x : string ; y : string } > (
'Add {{x}} and {{y}}' ,
trainingExamples ,
testExamples
) ;
async function doit ( ) {
console . log ( await addInBase2 ( { x : '101' , y : '11' } ) ) ;
}
doit ( ) ;在此示例中,我們定義了一個函數addInBase2 ,該函數採用兩個二進制數(表示為字符串)並添加它們。 define函數通過提示和兩個示例來調用:培訓示例和測試示例。培訓示例以一些速度學習方式在提示中反映。另一方面,測試示例用於驗證生成的函數的正確性。如果您不為該功能生成代碼,則不需要測試示例。
結果是一個強大的功能,允許您指示LLM使用示例執行複雜的操作,例如二進制添加。這種方法使您能夠快速發展複雜的功能,並且具有較少的明確邏輯。
定義函數addInBase2後,您可以將其調用二進制數字字符串以在基本2中執行添加。與傳統功能呼叫一樣, Askit的ask Operation返回返回的承諾可以解決計算結果。
JavaScript開發人員可以充分利用Askit提供的類型引導輸出控制的潛力。就像其兄弟姐妹打字稿一樣,JavaScript合併了API方法來實現這一ask 。函數ask需要兩個參數:類型和提示。
這是證明其用法的一系列示例:
const ai = require ( 'ts-askit' )
const t = require ( 'ts-askit/types' )
ai . ask ( t . number , 'What is the third prime number?' ) . then ( ( answer ) => { console . log ( answer ) } ) ;
ai . ask ( t . string , "What is the month number of 'January'?" ) . then ( ( answer ) => { console . log ( answer ) } ) ;
ai . ask ( t . array ( t . number ) , "What are the month numbers in the second quarter?" ) ;
const monthType = t . type ( {
name : t . string ,
number : t . number
} )
ai . ask ( monthType , "What is the month number of 'October'?" ) . then ( ( answer ) => { console . log ( answer ) } ) ;
ai . ask ( t . array ( monthType ) , "What are the months in the second quarter?" ) . then ( ( answer ) => { console . log ( answer ) } ) ;在上面的代碼片段中,使用類型和提示調用ask功能。類型參數的目的是通知Askit有關所需輸出的格式和結構。當您處理複雜的數據結構時,這變得非常方便。
使用Askit ,JavaScript開發人員可以使用易於理解的模板來定義功能。 define方法是這裡的幕後英雄,因為它可以根據提供的任務模板來創建功能。創建後,這些函數可以用任何為模板中佔位持有人提供值的對象調用。
這是一個如何完成的示例:
const ai = require ( 'ts-askit' )
const t = require ( 'ts-askit/types' )
let f = ai . define ( t . string , 'Translate {{text}} into {{language}}' ) ;
f ( { text : 'Hello' , language : 'French' } ) . then ( ( answer ) => { console . log ( answer ) } ) ;在上面的代碼中,使用define方法來使用任務模板f轉換{{text}}到{{language}}'。然後將函數f與提供text和language值的對象調用。
'ts-askit/types'模塊是您可以用來指導Askit輸出的類型的寶庫。這是一張可以幫助您快速掌握這些類型的桌子:
| 類型 | 描述 | 類型示例 | 價值示例 |
|---|---|---|---|
NumberType | 數字類型 | t.number | 123 |
StringType | 字符串類型 | t.string | “你好世界!” |
BooleanType | 布爾類型 | t.boolean | 真的 |
LiteralType | 字面價值類型 | t.literal(123) | 123 |
ArrayType | 數組類型 | t.array(t.number) | [1,2,3] |
UnionType | 聯合類型(多個可能的值) | t.union([t.literal('yes'), t.literal('no')]) | “是還是不是” |
InterfaceType | 接口/字典類型 | t.type({a: t.number, b: t.number}) | {a:1,b:2} |
CodeType | 代碼類型 | t.code('python') | “ def hello_world():print('Hello,World!')” |
每種類型都有特定的屬性,該屬性用來理解手頭的任務並正確格式化輸出。
截至撰寫本文時,代碼生成功能在打字稿中僅可用。但是,努力正在努力將這一強大功能擴展到JavaScript領域。如果您的要求要求在此期間使用代碼生成,我們建議使用TypeScript直至進一步更新。
有關我們的行為守則和提交拉的請求過程的詳細信息,請參閱progruting.md。
該項目已根據MIT許可獲得許可。有關更多信息,請參閱許可證文件。
@misc { okuda2023askit ,
title = { AskIt: Unified Programming Interface for Programming with Large Language Models } ,
author = { Katsumi Okuda and Saman Amarasinghe } ,
year = { 2023 } ,
eprint = { 2308.15645 } ,
archivePrefix = { arXiv } ,
primaryClass = { cs.PL }
}