AskIt作为专用库或特定领域语言,旨在简化大型语言模型 (LLM)(例如 GPT-4、Gemini、Claude、COHERE 和 LLama2)的使用。它简化了即时工程的复杂性,并消除了解析法学硕士响应的要求,使编程任务更加顺利。
使用AskIt ,您可以为多种任务部署 LLM,例如:
pyaskit可以使用 GPT、Gemini、Claude、COHERE 或 LLama2 作为后端。 pyaskit通过 OpenAI API、Gemini API、Claude API 和 COHERE API 或 LLama2 API 运行。除了 Python 之外, AskIt也已经用 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 仪表板中找到您的 OpenAI API 密钥。
您需要将模型名称指定为环境变量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
文件中找到可用的模型。
在将AskIt与 Llama 2 一起使用之前,您需要安装它。要安装 Llama 2,请在终端中运行以下命令:
pip install git+https://github.com/facebookresearch/llama.git
您还需要下载分词器模型以及要使用的模型的检查点。请参阅 Llama 2 文档了解更多详细信息。
我们在示例目录中提供了将AskIt与 Llama 2 一起使用的示例。要运行该示例,请在终端中运行以下命令:
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 采用两个参数 - 输出类型和提示 - 以指定格式生成 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 define
API 允许使用模板语法进行提示参数化:
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!”的内容。
define
API 允许直接创建自定义函数,以利用大型语言模型的功能来执行不同的任务。更多示例可以在示例目录中找到。
某些任务,例如需要实时数据、网络访问、文件访问或数据库访问等外部资源的任务,不适合 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 的第二个参数是一个字典,它将参数名称映射到其类型。
我们可以用下面的代码做同样的事情:
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使您能够使用示例编程 (PBE) 技术来解决任务,您可以在其中提供所需输入和输出的示例。
让我们考虑创建一个函数来添加两个二进制数(表示为字符串)。该函数接受两个二进制数并返回它们的和,也是二进制形式。以下代码使用说明性示例演示了定义此类函数。
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 采用三个参数:输出类型、提示和训练示例。训练示例列表中的每个条目都是一个字典,其中包含一个“输入”字典(带有变量名称和值)和一个表示给定输入的预期函数输出的“输出”。然后, define
API 返回一个函数,该函数接受输入变量作为关键字参数,并以指定类型输出 LLM 的输出。
add_binary_numbers
函数将两个二进制数相加,其行为与任何常规 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提供 API 来指定语言学习模型 (LLM) 的输出类型。通过将这些类型作为ask
和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 | 联合(多个可能的值) | t.union(t.literal('yes'), t.literal('no')) | “是还是不是” |
t.literal('yes') | t.literal('no') | “是还是不是” | ||
t.literal('yes', 'no') | “是还是不是” | ||
None | 没有任何 | None | 没有任何 |
请注意,每个类型声明都有助于AskIt解析和理解所需的输出,确保您的 LLM 以您所需的精确格式返回数据。
提示模板是由所定义函数的参数的占位符组成的字符串。占位符由双大括号{{
和}}
表示,并且只能包含变量名称。然后,该变量名称将用作定义的函数中的参数。
函数参数可以通过两种方式定义:通过关键字参数或通过位置参数。对于关键字参数,占位符内的变量名称用作关键字参数的名称。对于位置参数,占位符出现的顺序定义了位置参数的顺序。
考虑以下示例,该示例演示如何定义函数add
,该函数接受两个参数x
和y
并返回它们的总和:
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}}
在提示模板中出现了两次。第二次出现的{{x}}
映射回第一次出现。因此,即使{{z}}
是模板中的第四个占位符,它也与函数的第三个参数对齐。
有关我们的行为准则以及向我们提交拉取请求的流程的详细信息,请参阅 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 }
}