Askit เป็นปลั๊กอินภาษาสำหรับ TypeScript ที่ช่วยให้คุณสามารถใช้ประโยชน์จากความสามารถของรูปแบบภาษาขนาดใหญ่ (LLM) เช่น GPT-4 โดยตรงภายในสภาพแวดล้อมการเขียนโปรแกรมของคุณไม่จำเป็นต้องใช้ API ที่ซับซ้อน แอปพลิเคชันที่หลากหลายของ Askit รวมถึง:
Askit สร้างขึ้นบน OpenAI API จัดเตรียมอินเทอร์เฟซที่ใช้งานง่ายสำหรับการรวม LLMs ลงในแอปพลิเคชันของคุณ คุณสามารถใช้ Askit ไม่เพียง แต่ใน TypeScript แต่ยังอยู่ใน JavaScript และ Python
สำหรับการรวม Askit กับ JavaScript โปรดดูส่วน JavaScript ที่เกี่ยวข้อง
หาก Python เป็นภาษาที่คุณต้องการคุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับวิธีการใช้ Askit โดยไปที่หน้า Askit (Pyaskit) ของเรา
การควบคุมเอาต์พุตแบบแนะนำ: รับการตอบกลับในประเภทที่ระบุ
นิยามฟังก์ชั่นที่ใช้เทมเพลต: กำหนดฟังก์ชั่นโดยใช้เทมเพลตพรอมต์
การสร้างรหัส: สร้างฟังก์ชั่นจากอินเทอร์เฟซแบบครบวงจร ดูการสร้างรหัสด้วย Askit สำหรับรายละเอียดเพิ่มเติม
การเขียนโปรแกรมโดยตัวอย่าง (PBE): กำหนดฟังก์ชั่นโดยใช้ตัวอย่าง ดูการเขียนโปรแกรมโดยตัวอย่างด้วย Askit สำหรับรายละเอียดเพิ่มเติม
ก่อนเริ่มต้นตรวจสอบให้แน่ใจว่าติดตั้ง Node.js และ NPM ในระบบของคุณ จากนั้นดำเนินการคำสั่งต่อไปนี้:
npm install ts-askit แพ็คเกจนี้อาศัย ts-patch ในการติดตั้ง ts-patch , Run:
npx ts-patch install เพิ่มตัวอย่างต่อไปนี้ใน tsconfig.json ของคุณ:
"compilerOptions" : {
"plugins" : [{ "transform" : " ts-askit/transform " }]
} การปรับเปลี่ยนนี้ช่วยให้คอมไพเลอร์ TypeScript รองรับพารามิเตอร์ประเภทสำหรับ ask และ define APIs ใน Askit
แพ็คเกจ ts-patch เป็นสิ่งสำคัญสำหรับการปลดปล่อยศักยภาพของ Askit อย่างเต็มที่เนื่องจากมันขยายคอมไพเลอร์ TypeScript เพื่อรวมระบบประเภทของ Askit อย่างเต็มที่ ในขณะที่ Askit สามารถใช้งานได้โดยไม่ต้องใช้ ts-patch แต่การรวมนี้ให้ประสบการณ์ที่หลากหลายมากขึ้น
ก่อนใช้ Askit คุณต้องตั้งค่าคีย์ OpenAI API ของคุณเป็นตัวแปรสภาพแวดล้อม OPENAI_API_KEY :
export OPENAI_API_KEY= < your OpenAI API key > <your OpenAI API key> เป็นสตริงที่มีลักษณะเช่นนี้: sk-<your key> คุณสามารถค้นหาคีย์ API ของคุณได้ในแผงควบคุม OpenAI
นอกจากนี้คุณยังสามารถระบุชื่อโมเดลเป็นตัวแปรสภาพแวดล้อม 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 จะสแกนรหัสและสร้างไฟล์ JSONL ที่มีรายละเอียดเกี่ยวกับ define และ ask การโทร APInpx askgen < jsonl file >tsc เวลานี้ define และ ask การโทร API จะถูกแทนที่ด้วยการอ้างอิงและการโทรไปยังฟังก์ชั่นที่สร้างขึ้นใหม่ตามลำดับด้วยคุณลักษณะการเปลี่ยนอัตโนมัติของ Askit 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 เช่นเดียวกับการเรียกใช้ฟังก์ชันแบบดั้งเดิมการดำเนินการ ask ของ Askit จะส่งคืนสัญญาที่แก้ไขด้วยผลลัพธ์ที่คำนวณได้
นักพัฒนา JavaScript สามารถใช้ประโยชน์จากศักยภาพของการควบคุมเอาต์พุตแบบนำทางประเภทที่เสนอโดย Askit เช่นเดียวกับ Typescript ของพี่น้อง 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 (): พิมพ์ ('สวัสดีโลก!')" |
แต่ละประเภทมีคุณสมบัติเฉพาะที่ ถามว่า ใช้เพื่อทำความเข้าใจงานในมือและจัดรูปแบบผลลัพธ์ที่เหมาะสม
ณ เวลาของการเขียนคุณสมบัติการสร้างรหัสมีเฉพาะใน typeScript อย่างไรก็ตามความพยายามกำลังแกว่งอย่างเต็มที่เพื่อขยายคุณสมบัติที่ทรงพลังนี้ไปยังอาณาจักรของ JavaScript หากความต้องการของคุณเรียกร้องให้ใช้การสร้างรหัสในระหว่างกาลเราขอแนะนำให้ใช้ TypeScript จนกว่าจะมีการอัปเดตเพิ่มเติม
สำหรับรายละเอียดเกี่ยวกับจรรยาบรรณของเราและกระบวนการส่งคำขอดึงโปรดดูที่การสนับสนุน
โครงการนี้ได้รับใบอนุญาตภายใต้ใบอนุญาต 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 }
}