AskIt は、 GPT-4、Gemini、Claude、COHERE、LLama2 などの大規模言語モデル (LLM) の利用を効率化するように設計された専用ライブラリまたはドメイン固有言語として機能します。これにより、プロンプト エンジニアリングの複雑さが簡素化され、LLM からの応答を解析する必要がなくなり、プログラミング タスクがよりスムーズになります。
AskIt を使用すると、次のような多数のタスクに LLM をデプロイできます。
pyaskit は、GPT、Gemini、Claude、COHERE、または LLama2 をバックエンドとして使用できます。 pyaskit は、OpenAI API、Gemini API、Claude API、および COHERE API または LLama2 API を通じて動作します。 AskIt はPython 以外に TypeScript でも実装されています。 TypeScript バージョンの ts-askit にアクセスできます。
from pyaskit import ask
# Automatically parses the response to an integer
sum = ask ( int , "add 1 + 1" )
# `sum` is an integer with a value of 2
from typing import TypedDict , List
from pyaskit import ask
# Define a typed dictionary for programming languages
class PL ( TypedDict ):
name : str
year_created : int
# Automatically extracts structured information into a list of dictionaries
langs = ask ( List [ PL ], "List the two oldest programming languages." )
# `langs` holds information on the oldest programming languages in a structured format like
# [{'name': 'Fortran', 'year_created': 1957},
# {'name': 'Lisp', 'year_created': 1958}]
from pyaskit import function
@ function ( codable = False )
def translate ( s : str , lang : str ) -> str :
"""Translate {{s}} into {{lang}} language."""
s = translate ( "こんにちは世界。" , "English" )
# `s` would be "Hello, world."
from pyaskit import function
@ function ( codable = True )
def get_html ( url : str ) -> str :
"""Get the webpage from {{url}}."""
# When `codable` is set to True, the body of the function is automatically coded by an LLM.
html = get_html ( "https://github.com/katsumiok/pyaskit/blob/main/README.md" )
# `html` contains the HTML version of this README.md
AskIt をインストールするには、ターミナルで次のコマンドを実行します。
pip install pyaskit
または
pip install git+https://github.com/katsumiok/pyaskit.git
AskIt を使用する前に、API キーを適切な環境変数として設定する必要があります。
OPENAI_API_KEY
GOOGLE_API_KEY
ANTHROPIC_API_KEY
CO_API_KEY
GROQ_API_KEY
たとえば、OpenAI API を使用するには、OpenAI API キーを環境変数OPENAI_API_KEY
として設定する必要があります。
export OPENAI_API_KEY= < your OpenAI API key >
<your OpenAI API key>
、 sk-<your key>
のような文字列です。 OpenAI API キーは OpenAI ダッシュボードで見つけることができます。
モデル名を環境変数ASKIT_MODEL
として指定する必要があります。
export ASKIT_MODEL= < model name >
<model name>
、使用するモデルの名前です。最新の AskIt は、 gpt-4
、 gpt-3.5-turbo-16k
、 gemini-pro
、 claude-2.1
、およびcohere-2.0
でテストされています。使用可能なモデルのリストは、OpenAI API ドキュメント、Gemini API ドキュメント、Claude API ドキュメント、および COHERE API ドキュメントで確認できます。使用可能なモデルは、 models.py
ファイルでも見つけることができます。
Llama 2 でAskIt を使用する前に、AskIt をインストールする必要があります。 Llama 2 をインストールするには、ターミナルで次のコマンドを実行します。
pip install git+https://github.com/facebookresearch/llama.git
また、トークナイザー モデルと使用するモデルのチェックポイントをダウンロードする必要があります。詳細については、Llama 2 のドキュメントを参照してください。
Llama 2 でAskIt を使用する例がサンプル ディレクトリにあります。この例を実行するには、ターミナルで次のコマンドを実行します。
torchrun --nproc_per_node 1 examples/use_llama2.py
--ckpt_dir llama-2-7b-chat/
--tokenizer_path tokenizer.model
--max_seq_len 512 --max_batch_size 6
AskItに慣れるのに役立ついくつかの基本的な例を次に示します。
import pyaskit as ai
s = ai . ask ( str , 'Paraphrase "Hello World!"' )
print ( s )
AskIt を利用するには、まずpyaskit
モジュールをインポートします。 ask
API は 2 つの引数 (出力タイプとプロンプト) を受け取り、指定された形式で LLM の出力を生成します。この場合、出力タイプはstr
で、プロンプトはParaphrase "Hello World!"
です。 。 AskItのタイプの包括的な説明は、「タイプ」セクションで提供されます。このコードを実行すると、次のようなプロンプトの言い換えが表示されます。
Greetings, Planet!
function
デコレータを使用するfunction
デコレータを使用すると、プロンプト テンプレートを使用して関数を定義できます。定義された関数のパラメータは、プロンプト テンプレートのパラメータとして使用できます。例えば、
from pyaskit import function
@ function ( codable = False )
def paraphrase ( text : str ) -> str :
"""Paraphrase {{text}}"""
s = paraphrase ( 'Hello World!' )
print ( s )
ここで、 {{text}}
テンプレート パラメータを表し、関数パラメータに対応します。
define
APIを使用するAPI のdefine
、テンプレート構文を使用したプロンプトのパラメータ化が可能になります。
import pyaskit as ai
paraphrase = ai . define ( str , 'Paraphrase {{text}}' )
s = paraphrase ( text = 'Hello World!' )
# s = paraphrase('Hello World!') # This is also valid
print ( s )
この例では、 define
API は、LLM に指定されたテキストを言い換えるように指示するテンプレート関数を作成します。 「Hello World!」でparaphrase
機能を呼び出すこのテキストの言い換えバージョンが返されます。このコードを実行すると、「Greetings, Planet!」のようなメッセージが出力される可能性があります。
API のdefine
カスタム関数を簡単に作成して、さまざまなタスクに大規模な言語モデルの機能を活用できます。その他の例は、example ディレクトリにあります。
リアルタイム データ、ネットワーク アクセス、ファイル アクセス、データベース アクセスなどの外部リソースを必要とするタスクなどの特定のタスクは、LLM の実行には適していません。ただし、 AskIt はプロンプトをバックグラウンドで Python プログラムに変換することで、これらのタスクを処理できます。
次の例は、 AskItを使用してネットワーク アクセスを必要とするタスクに取り組む方法を示しています。
import pyaskit as ai
get_html = ai . define ( str , 'Get the webpage from {{url}}' ). compile ()
html = get_html ( url = 'https://csail.mit.edu' )
print ( html )
このシナリオでは、 define
API によって返された関数に対してcompile()
を呼び出すだけで済みます。 compile
関数はプロンプトを Python プログラムに変換し、通常の Python 関数と同様に動作して、このコードを実行する関数を返します。
上記の例ではパラメータurl
のタイプを指定していませんが、 AskIt はこれを行うためのdefun
API を提供しています。次のコードは、パラメーターurl
の型がstr
として指定される関数を定義する方法を示しています。
import pyaskit as ai
get_html = ai . defun ( str , { "url" : str }, 'Get the webpage from {{url}}' ). compile ()
html = get_html ( url = 'https://csail.mit.edu' )
print ( html )
defun
API の 2 番目の引数は、パラメーター名をその型にマップする辞書です。
次のコードでも同じことができます。
from pyaskit import function
@ function ( codable = True )
def get_html ( url : str ) -> str :
"""Get the webpage from {{url}}"""
html = get_html ( url = 'https://csail.mit.edu' )
print ( html )
言語学習モデル (LLM) は、 AskIt がプログラミング タスクで利用する機能である、少数ショット学習の利点を提供します。 AskIt を使用すると、必要な入力と出力の例を提供する Programming by Example (PBE) 手法を使用してタスクを解決できます。
2 つの 2 進数 (文字列として表される) を加算する関数を作成することを考えてみましょう。この関数は 2 つの 2 進数を受け入れ、その合計をやはり 2 進数形式で返します。次のコードは、例示的な例を使用してそのような関数の定義を示しています。
from pyaskit import define
training_examples = [
{ "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" },
]
add_binary_numbers = define ( str , "Add {{x}} and {{y}}" , training_examples = training_examples )
sum_binary = add_binary_numbers ( x = "101" , y = "11" )
print ( sum_binary ) # Output: "1000"
この例では、 define
API は、出力タイプ、プロンプト、トレーニング サンプルの 3 つの引数を受け取ります。トレーニング例リストの各エントリは、「入力」辞書 (変数名と値を含む) と、入力が与えられた場合に期待される関数出力を表す「出力」を含む辞書です。次に、 define
API は、入力変数をキーワード引数として受け入れ、指定された型で LLM の出力を出力する関数を返します。
add_binary_numbers
関数は 2 つの 2 進数を加算し、通常の Python 関数と同様に動作します。
compile
関数を使用すると、オプションのテスト例のリストを使用して、生成された関数をテストできます。
次のコードは、新しいテスト例を使用して、上で定義した関数をテストする方法を示しています。
test_examples = [
{ "input" : { "x" : "0" , "y" : "1" }, "output" : "1" },
{ "input" : { "x" : "10" , "y" : "0" }, "output" : "10" },
{ "input" : { "x" : "110" , "y" : "10" }, "output" : "1000" },
]
f = add_binary_numbers . compile ( test_examples = test_examples )
sum_binary = f ( x = "101" , y = "11" )
print ( sum_binary ) # Output: "1000"
ここで、 f
add_binary_numbers
と同様に動作する生成された関数です。 AskIt は、生成された関数の出力を各テスト例の期待される出力と比較することで、生成された関数が期待どおりに動作することを確認します。矛盾が生じた場合、 AskIt は翻訳を再試行します。翻訳の試行が複数回失敗すると、 AskIt は例外を発生させます。
AskIt は、言語学習モデル (LLM) の出力タイプを指定する API を提供します。これらの型をask
API およびdefine
API の最初の引数として指定することにより、LLM の出力形式を管理できます。 Python が提供する型ヒントを使用することもできます。
次の表では、 AskItでサポートされているさまざまなタイプを説明します。
タイプ | 説明 | タイプ例 | 値の例 |
---|---|---|---|
int | 整数 | t.int | 123 |
float | 浮動小数点数 | t.float | 1.23 |
bool | ブール値 | t.bool | 真実 |
str | 弦 | t.str | "こんにちは世界!" |
literal | リテラル | t.literal(123) | 123 |
list | リスト | t.list(t.int) | [1、2、3] |
dict | 辞書 | t.dict({ 'a': t.int, 'b': t.str }) | {'a': 1、'b': "abc"} |
record | 辞書 | t.record(t.str, t.int) | {'a': 1、'b': 2} |
tuple | タプル | t.tuple(t.int, t.str) | (1、「ABC」) |
union | Union (複数の可能な値) | t.union(t.literal('yes'), t.literal('no')) | "はい、もしくは、いいえ" |
t.literal('yes') | t.literal('no') | "はい、もしくは、いいえ" | ||
t.literal('yes', 'no') | "はい、もしくは、いいえ" | ||
None | なし | None | なし |
各型宣言は、 AskIt が目的の出力を解析して理解するのに役立ち、LLM が必要な正確な形式でデータを返すようにすることに注意してください。
プロンプト テンプレートは、定義される関数のパラメーターのプレースホルダーで構成される文字列です。プレースホルダーは二重中括弧{{
および}}
で示され、変数名のみを含めることができます。この変数名は、定義された関数のパラメーターとして使用されます。
関数パラメータは、キーワード引数または位置引数のいずれかによって定義できます。キーワード引数の場合、プレースホルダー内の変数名がキーワード引数の名前として機能します。位置引数の場合、プレースホルダーが表示される順序によって位置引数の順序が定義されます。
2 つの引数x
とy
を受け取り、それらの合計を返す関数add
定義する方法を示す次の例を考えてみましょう。
from pyaskit import define
import pyaskit . types as t
add = define ( t . int , '{{x}} + {{y}}' )
print ( add ( x = 1 , y = 2 )) # keyword arguments
print ( add ( 1 , 2 )) # positional arguments
この場合、キーワードまたは位置引数を使用してadd
関数を呼び出すことができ、 x
とy
の合計が出力として返されます。
特に、同じ変数名がプロンプト テンプレートで複数回使用される場合、その後の使用は最初に出現した変数にマップされます。次の例でこの動作を確認してください。
from pyaskit import define
import pyaskit . types as t
add = define ( t . int , '{{x}} + {{y}} + {{x}} + {{z}}' )
print ( add ( x = 1 , y = 2 , z = 3 ))
print ( add ( 1 , 2 , 3 ))
ここで、 {{x}}
プロンプト テンプレートに 2 回表示されます。 2 回目に出現した{{x}}
は最初の出現にマッピングされます。したがって、 {{z}}
テンプレート内の 4 番目のプレースホルダーであっても、関数の 3 番目の引数と一致します。
当社の行動規範とプル リクエストを当社に送信するプロセスの詳細については、CONTRIBUTING.md を参照してください。
このプロジェクトは MIT ライセンスに基づいてライセンスされています - 詳細については、LICENSE.md ファイルを参照してください。
研究で当社のソフトウェアを使用する場合は、当社の論文を引用してください。
@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 }
}