instructor-js
TypeScript的结构化提取,由llms驱动,设计简洁,透明且可控。
探索基于TypeScript的结构化提取世界,通过OpenAI的函数调用API和Zod,TypeScript优先的模式验证与静态类型推断。Instructor因其简洁、透明和以用户为中心的设计而脱颖而出。无论你是经验丰富的开发者还是刚刚入门,你都会发现Instructor的方法直观且可操控。
安装
bun add @instructor-ai/instructor zod openai
npm i @instructor-ai/instructor zod openai
pnpm add @instructor-ai/instructor zod openai
基本用法
要查看所有提示和数据提取技巧,请查阅文档。
import Instructor from "@instructor-ai/instructor";
import OpenAI from "openai"
import { z } from "zod"
const oai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY ?? undefined,
organization: process.env.OPENAI_ORG_ID ?? undefined
})
const client = Instructor({
client: oai,
mode: "TOOLS"
})
const UserSchema = z.object({
// 说明将会在提示中使用
age: z.number().describe("用户的年龄"),
name: z.string()
})
// 用户类型将为 z.infer<typeof UserSchema>
const user = await client.chat.completions.create({
messages: [{ role: "user", content: "Jason Liu 30岁" }],
model: "gpt-3.5-turbo",
response_model: {
schema: UserSchema,
name: "User"
}
})
console.log(user)
// { age: 30, name: "Jason Liu" }
API 参考
Instructor 类
创建Instructor客户端的主要类。
createInstructor
function createInstructor<C extends GenericClient | OpenAI>(args: {
client: OpenAILikeClient<C>;
mode: Mode;
debug?: boolean;
}): InstructorClient<C>
创建Instructor类的实例。
- client: 类似OpenAI的客户端。
- mode: 操作模式。
- debug: 是否记录调试消息。
返回扩展的类似OpenAI的客户端。
chat.completions.create
chat.completions.create<
T extends z.AnyZodObject,
P extends T extends z.AnyZodObject ? ChatCompletionCreateParamsWithModel<T>
: ClientTypeChatCompletionParams<OpenAILikeClient<C>> & { response_model: never }
>(
params: P
): Promise<ReturnTypeBasedOnParams<typeof this.client, P>>
当参数中存在response_model时,根据提供的模式创建具有结构化提取的聊天完成,否则将代理回提供的客户端。
- params: 包含响应模式模式参数的聊天完成参数。
- 返回基于模式提取的数据的返回值的承诺。
模式
Instructor支持不同的模式来定义语言模型响应的结构和格式。这些模式在zod-stream
包中定义,具体如下:
-
FUNCTIONS
(已废弃): 使用OpenAI的函数调用API生成响应。它映射到函数调用API所需的参数,包括function_call
和functions
属性。 -
TOOLS
: 使用OpenAI的工具规范生成响应。它构造工具规范所需的参数,包括tool_choice
和tools
属性。 -
JSON
: 将response_format
设置为json_object
,并在系统消息中包含JSON模式以引导响应生成。(Together & Anyscale) -
MD_JSON
: 在Markdown代码块中嵌入JSON格式的响应。在系统消息中包含JSON模式,并期望响应为一个有效的JSON对象,包裹在Markdown代码块中。 -
JSON_SCHEMA
: 使用符合提供的JSON模式的“JSON模式”生成响应。将response_format
设置为json_object
,并在系统消息中包含模式说明。
示例
流式完成
Instructor支持部分流式完成,允许您在模型生成响应的同时实时接收提取数据。这有助于提供更互动的用户体验或逐步处理大量数据。
import Instructor from "@instructor-ai/instructor"
import OpenAI from "openai"
import { z } from "zod"
const textBlock = `
在我们最近的在线会议中,来自不同背景的参与者加入了讨论即将召开的技术会议。
参与者的姓名和联系方式如下:
- 姓名: John Doe, 邮箱: johndoe@email.com, 推特: @TechGuru44
- 姓名: Jane Smith, 邮箱: janesmith@email.com, 推特: @DigitalDiva88
- 姓名: Alex Johnson, 邮箱: alexj@email.com, 推特: @CodeMaster2023
在会议期间,我们同意了几个关键点。会议将于 2024 年 3 月 15 日在创新大道 4521 号的大型科技场馆举行。著名人工智能研究员Emily Johnson博士将担任我们的主讲人。本次活动的预算定为 50,000 美元,用于场地费用、讲师费和宣传活动。
每个参与者都预计在 2 月 20 日之前为会议博客贡献一篇文章。我们计划于 1 月 25 日下午 3 点 GMT 举行后续会议,以最终确定议程并确认讲师名单。
`
async function extractData() {
const ExtractionSchema = z.object({
users: z.array(
z.object({
name: z.string(),
handle: z.string(),
twitter: z.string()
})
).min(3),
location: z.string(),
budget: z.number()
})
const oai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY ?? undefined,
organization: process.env.OPENAI_ORG_ID ?? undefined
})
const client = Instructor({
client: oai,
mode: "TOOLS"
})
const extractionStream = await client.chat.completions.create({
messages: [{ role: "user", content: textBlock }],
model: "gpt-3.5-turbo",
response_model: {
schema: ExtractionSchema,
name: "Extraction"
},
max_retries: 3,
stream: true
})
let extractedData = {}
for await (const result of extractionStream) {
extractedData = result
console.log("部分提取:", result)
}
console.log("最终提取:", extractedData)
}
extractData()
在本示例中,我们使用Zod定义了一个ExtractionSchema以指定要提取的数据结构。然后我们启用流媒体并创建Instructor客户端,将模式传递给response_model参数。
extractionStream变量持有一个异步生成器,该生成器在部分提取结果可用时生成数据。我们使用for await...of循环迭代流,更新extractedData对象,同时将每个部分结果记录到控制台。
最后,一旦流耗尽,我们记录完整的提取数据。
通过代理使用不同的提供商
Instructor支持遵守OpenAI API规范的各种提供商。您可以通过配置适当的客户端并指定所需的模式和模型轻松切换提供商。
Anyscale
import Instructor from "@instructor-ai/instructor"
import OpenAI from "openai"
import { z } from "zod"
const UserSchema = z.object({
age: z.number(),
name: z.string().refine(name => name.includes(" "), {
message: "名字必须包含空格"
})
})
async function extractUser() {
const client = new OpenAI({
baseURL: "https://api.endpoints.anyscale.com/v1",
apiKey: process.env.ANYSCALE_API_KEY
})
const instructor = Instructor({
client: client,
mode: "TOOLS"
})
const user = await instructor.chat.completions.create({
messages: [{ role: "user", content: "Jason Liu 30岁" }],
model: "mistralai/Mixtral-8x7B-Instruct-v0.1",
response_model: {
schema: UserSchema,
name: "User"
},
max_retries: 4
})
return user
}
const anyscaleUser = await extractUser()
console.log("Anyscale用户:", anyscaleUser)
Together
import Instructor from "@instructor-ai/instructor"
import OpenAI from "openai"
import { z } from "zod"
const UserSchema = z.object({
age: z.number(),
name: z.string().refine(name => name.includes(" "), {
message: "名字必须包含空格"
})
})
async function extractUser() {
const client = new OpenAI({
baseURL: "https://api.together.xyz/v1",
apiKey: process.env.TOGETHER_API_KEY
})
const instructor = Instructor({
client: client,
mode: "TOOLS"
})
const user = await instructor.chat.completions.create({
messages: [{ role: "user", content: "Jason Liu 30岁" }],
model: "mistralai/Mixtral-8x7B-Instruct-v0.1",
response_model: {
schema: UserSchema,
name: "User"
},
max_retries: 4
})
return user
}
const togetherUser = await extractUser() console.log("Together user:", togetherUser)
在这些示例中,我们从Anyscale指定一个特定的基本URL和API密钥,以及Together。
extractUser函数将模型、模式和提供者作为参数。它检索相应的提供者配置,创建一个OpenAI客户端,并以指定的模式初始化Instructor实例。
然后,我们调用instructor.chat.completions.create,使用所需的模型、响应模式和其他参数来提取用户信息。
通过在调用extractUser时改变提供者、模型和模式参数,您可以轻松地在不同的提供者和配置之间切换。
使用llm-polyglot的非OpenAI提供者
Instructor支持集成那些不遵循OpenAI SDK的提供者,例如Anthropic、Azure和Cohere,通过由@dimitrikennedy维护的llm-polyglot
库。该库提供了一个统一的接口,用于跨不同提供者与各种语言模型进行交互。
import { createLLMClient } from "llm-polyglot"
import Instructor from "@instructor-ai/instructor"
import { z } from "zod"
const anthropicClient = createLLMClient({
provider: "anthropic",
apiKey: process.env.ANTHROPIC_API_KEY
})
const UserSchema = z.object({
age: z.number(),
name: z.string()
})
const instructor = Instructor<typeof anthropicClient>({
client: anthropicClient,
mode: "TOOLS"
})
async function extractUser() {
const user = await instructor.chat.completions.create({
model: "claude-3-opus-20240229",
max_tokens: 1000,
messages: [
{
role: "user",
content: "My name is Dimitri Kennedy."
}
],
response_model: {
name: "extract_name",
schema: UserSchema
}
})
return user
}
// 示例用法
const extractedUser = await extractUser()
console.log("Extracted user:", extractedUser)
在这个例子中,我们使用llm-polyglot库的createLLMClient函数来为Anthropic提供者创建一个客户端。我们将提供者名称("anthropic")和相应的API密钥传递给该函数。
接下来,我们使用Zod定义一个UserSchema,以指定我们要提取的用户数据的结构。
我们通过将Anthropic客户端和所需的模式传递给Instructor函数来创建一个Instructor实例。注意,我们使用Instructor
extractUser函数演示了如何使用Instructor实例从给定输入中提取用户信息。我们调用instructor.chat.completions.create,使用适当的模型(在本例中为"claude-3-opus-20240229")、参数和包含我们UserSchema的response_model。
最后,我们记录下提取的用户信息。
通过利用llm-polyglot库,Instructor能够实现与超出遵循OpenAI SDK的广泛提供者的无缝集成。这使您能够利用不同提供者提供的独特功能和模型,同时仍受益于Instructor的结构化提取和验证功能。
有关使用其他提供者与llm-polyglot的更多支持和信息,请参阅该库的文档和示例。
更多示例
如果你想查看更多示例,请查阅我们的食谱。
安装Instructor非常简单。
基于Island AI构建
Instructor基于几个由Island AI工具包提供的强大包构建,并由Dimitri Kennedy开发和维护。这些包提供了与大型语言模型进行结构化数据处理和流处理的必要功能。
zod-stream
zod-stream是一个客户端模块,可直接与LLM流对接。它利用Schema-Stream进行高效解析,并配备了用于处理来自OpenAI的原始响应的工具,按模式(函数、工具、JSON等)分类,并确保适当的错误处理和流转换。它非常适合提供结构化LLM响应流的API集成。
schema-stream
schema-stream是一个JSON流解析器,它基于Zod schema增量构建和更新响应模型。它旨在进行实时数据处理和增量模型填充。
llm-polyglot
llm-polyglot是一个库,提供了一个统一的接口,用于跨多个提供者与各种语言模型交互,如OpenAI、Anthropic、Azure和Cohere。它简化了与多个LLM提供者合作的过程,并实现了与Instructor的无缝集成。
Instructor利用这些Island AI包的强大功能,提供了与LLM进行结构化数据提取和流处理的无缝和高效的体验。Island AI的创建者Dimitri Kennedy和原Instructor Python包的作者Jason Liu之间的合作,催生了Instructor的TypeScript版本,该版本引入了来自LLM的部分JSON流的概念。
有关Island AI及其包的更多信息,请参阅Island AI repository。
为什么使用Instructor?
使用Instructor的问题基本上是为什么要使用Zod的问题。
- 兼容OpenAI SDK — Instructor遵循OpenAI的API,这意味着您可以在支持OpenAI API的多个提供者之间使用相同的API进行提示和提取。
- 可定制 — Zod高度可定制,您可以定义自己的验证器、自定义错误消息等。
- 生态系统 — Zod 是Typescript中最广泛使用的数据验证库。
- 经过考验 — Zod 每月下载量超过2400万次,并得到了一个庞大的贡献者社区的支持。
贡献
如果您想帮忙,请查看标有good-first-issue
或help-wanted
的一些问题。可以在此处找到。它们可能是代码改进、嘉宾博客文章或新的食谱。
请查看贡献指南了解如何设置、测试、变更集和指南。
ℹ️ 提示: 对其他语言的支持
查看以下其他语言的移植:
- [Python](https://www.github.com/jxnl/instructor)
- [Elixir](https://github.com/thmsmlr/instructor_ex/)
如果您想将Instructor移植到其他语言,请通过[Twitter](https://twitter.com/jxnlco)与我们联系,我们很乐意帮助您入门!
许可证
该项目根据MIT许可证的条款授权。