一个用于编写大型语言模型代码的小型库。查看MiniChain Zoo以了解其工作原理。
编码
- 代码(math_demo.py):注释调用语言模型的Python函数。
@prompt(OpenAI(), template_file="math.pmpt.tpl")
def math_prompt(model, question):
"使用Jinja模板调用GPT的提示"
return model(dict(question=question))
@prompt(Python(), template="import math\n{{code}}")
def python(model, code):
"调用Python解释器的提示"
code = "\n".join(code.strip().split("\n")[1:-1])
return model(dict(code=code))
def math_demo(question):
"将它们串联在一起"
return python(math_prompt(question))
- 链(Space):MiniChain构建了一个所有调用的图(类似于PyTorch),用于调试和错误处理。
show(math_demo,
examples=["小于100的3的幂(3^i)之和是多少?",
"前10个正整数的和是多少?"],
subprompts=[math_prompt, python],
out_type="markdown").queue().launch()
- 模板(math.pmpt.tpl):提示与代码分离。
...
问题:
一件长袍需要2匹蓝色纤维和一半数量的白色纤维。总共需要多少匹纤维?
代码:
2 + 2/2
问题:
{{question}}
代码:
- 安装
pip install minichain
export OPENAI_API_KEY="sk-***"
示例
这个库允许我们用几行代码实现几种流行的方法。
- 检索增强QA
- 带记忆的聊天
- 信息提取
- 交错代码(PAL) - (Gao et al 2022)
- 搜索增强(Self-Ask) - (Press et al 2022)
- 思维链 - (Wei et al 2022)
它支持以下后端:
- OpenAI(Completions / Embeddings)
- Hugging Face 🤗
- Google搜索
- Python
- Manifest-ML(AI21, Cohere, Together)
- Bash
为什么选择Mini-Chain?
目前有几个非常流行的提示链接库,特别是:LangChain、Promptify和GPTIndex。这些库很有用,但它们非常庞大和复杂。MiniChain旨在以一个小型易懂的库实现核心的提示链接功能。
教程
Mini-chain基于将函数注释为提示。
@prompt(OpenAI())
def color_prompt(model, input):
return model(f"如果这是一种颜色,请回答'Yes',{input}。回答:")
提示函数的行为类似于Python函数,但它们是惰性的,要访问结果,你需要调用run()
。
if color_prompt("blue").run() == "Yes":
print("这是一种颜色")
或者,你可以将提示链接在一起。提示是惰性的,所以如果你想操作它们,你需要在函数上添加@transform()
。例如:
@transform()
def said_yes(input):
return input == "Yes"
@prompt(OpenAI())
def adjective_prompt(model, input):
return model(f"给出一个形容词来描述{input}。回答:")
adjective = adjective_prompt("彩虹")
if said_yes(color_prompt(adjective)).run():
print("这是一种颜色")
我们还包含了一个参数template_file
,它假设模型使用来自Jinja语言的模板。这允许我们将提示文本与Python代码分离。
@prompt(OpenAI(), template_file="math.pmpt.tpl")
def math_prompt(model, question):
return model(dict(question=question))
可视化
MiniChain有一个内置的提示可视化系统,使用Gradio
。如果你构建了一个调用提示链的函数,你可以通过调用show
和launch
来可视化它。这也可以直接在notebook中完成。
show(math_demo,
examples=["小于100的3的幂(3^i)之和是多少?",
"前10个正整数的和是多少?"],
subprompts=[math_prompt, python],
out_type="markdown").queue().launch()
记忆
MiniChain不内置显式的有状态内存类。我们建议将其实现为一个队列。
以下是一个可能对跟踪响应有用的类。
@dataclass
class State:
memory: List[Tuple[str, str]]
human_input: str = ""
def push(self, response: str) -> "State":
memory = self.memory if len(self.memory) < MEMORY_LIMIT else self.memory[1:]
return State(memory + [(self.human_input, response)])
请参阅完整的聊天示例。 它会跟踪最近看到的两个响应。
工具和代理
MiniChain不提供agents
或tools
。如果你想要这些功能,可以使用模型的tool_num
参数,它允许你从多个不同的可能后端中选择。添加自己的新后端很容易(参见GradioExample)。
@prompt([Python(), Bash()])
def math_prompt(model, input, lang):
return model(input, tool_num= 0 if lang == "python" else 1)
文档和嵌入
MiniChain不管理文档和嵌入。我们推荐使用Hugging Face Datasets库,它内置了FAISS索引。
以下是实现方式。
# 加载并索引数据集
olympics = datasets.load_from_disk("olympics.data")
olympics.add_faiss_index("embeddings")
@prompt(OpenAIEmbed())
def get_neighbors(model, inp, k):
embedding = model(inp)
res = olympics.get_nearest_examples("embeddings", np.array(embedding), k)
return res.examples["content"]
这创建了一个K近邻(KNN)提示,根据问题的嵌入查找3个最接近的文档。 请参阅完整的检索增强QA示例。
我们建议使用datasets库的批量映射功能离线创建这些嵌入。
def embed(x):
emb = openai.Embedding.create(input=x["content"], engine=EMBEDDING_MODEL)
return {"embeddings": [np.array(emb['data'][i]['embedding'])
for i in range(len(emb["data"]))]}
x = dataset.map(embed, batch_size=BATCH_SIZE, batched=True)
x.save_to_disk("olympics.data")
还有其他方法可以做到这一点,比如sqllite或Weaviate。
类型化提示
MiniChain可以自动为你生成一个提示头,旨在确保输出遵循给定的类型规范。例如,如果你运行以下代码,MiniChain将生成一个返回Player
对象列表的提示。
class StatType(Enum):
POINTS = 1
REBOUNDS = 2
ASSISTS = 3
@dataclass
class Stat:
value: int
stat: StatType
@dataclass
class Player:
player: str
stats: List[Stat]
@prompt(OpenAI(), template_file="stats.pmpt.tpl", parser="json")
def stats(model, passage):
out = model(dict(passage=passage, typ=type_to_prompt(Player)))
return [Player(**j) for j in out]
具体来说,它会为你的模板提供一个typ
字符串,你可以使用。对于这个例子,字符串将是以下形式:
你是一个高度智能和准确的信息提取系统。你接收passage作为输入,你的任务是找出passage中回答问题的部分。
你需要输出一个JSON编码值的列表
你需要为key: "color"分类为以下类型:
RED
GREEN
BLUE
只从上面的列表中选择,或者"Other"。
你需要为key: "object"分类为以下类型:
String
你需要为key: "explanation"分类为以下类型:
String
[{ "color" : "color" , "object" : "object" , "explanation" : "explanation"}, ...]
确保每个输出都准确地出现在文档中。尽可能多地找出。
然后这将自动为你转换为一个对象。