跳到内容

面向开源和本地大模型的结构化输出

Instructor 扩展了其语言模型能力。最初通过 OpenAI SDK 进行 API 交互,并使用 Pydantic 进行结构化数据验证。现在,Instructor 支持多种模型和平台。

JSON 模式的集成提高了对视觉模型和开源替代方案的适应性。这使得它能够支持从 GPTMistralOllamaHugging Face 上的模型,并使用 llama-cpp-python

Instructor 现在支持基于云的 API 和本地模型进行结构化数据提取。开发人员可以参考我们的 修补指南,了解如何在不同模型中使用 JSON 模式。

要了解 Instructor 和 Pydantic,我们提供了一个关于 引导语言模型生成结构化输出 的课程。

以下部分展示了 Instructor 与平台和本地设置集成的示例,以在 AI 项目中实现结构化输出。

使用 Instructor 探索不同的 OpenAI 客户端

OpenAI 客户端提供满足不同需求的功能。我们探索了与 Instructor 集成的客户端,提供结构化输出和能力。示例展示了如何初始化和修补每个客户端。

本地模型

Ollama:本地模型的新领域

Ollama 使用 JSON Schema 为本地模型启用结构化输出。请参阅我们的 Ollama 文档了解详情。

有关设置和功能,请参阅文档。Ollama 网站提供资源、模型和支持。

ollama run llama2
from openai import OpenAI
from pydantic import BaseModel
import instructor


class UserDetail(BaseModel):
    name: str
    age: int


# enables `response_model` in create call
client = instructor.from_openai(
    OpenAI(
        base_url="https://:11434/v1",
        api_key="ollama",  # required, but unused
    ),
    mode=instructor.Mode.JSON,
)


user = client.chat.completions.create(
    model="llama2",
    messages=[
        {
            "role": "user",
            "content": "Jason is 30 years old",
        }
    ],
    response_model=UserDetail,
)

print(user)
#> name='Jason' age=30

llama-cpp-python

llama-cpp-python 提供 llama-cpp 模型,使用 JSON Schema 生成结构化输出。它使用了 约束采样推测解码。一个 OpenAI 兼容客户端 允许无需网络依赖的进程内结构化输出。

使用 llama-cpp-python 实现结构化输出的示例

import llama_cpp
import instructor
from llama_cpp.llama_speculative import LlamaPromptLookupDecoding
from pydantic import BaseModel


llama = llama_cpp.Llama(
    model_path="../../models/OpenHermes-2.5-Mistral-7B-GGUF/openhermes-2.5-mistral-7b.Q4_K_M.gguf",
    n_gpu_layers=-1,
    chat_format="chatml",
    n_ctx=2048,
    draft_model=LlamaPromptLookupDecoding(num_pred_tokens=2),
    logits_all=True,
    verbose=False,
)


create = instructor.patch(
    create=llama.create_chat_completion_openai_v1,
    mode=instructor.Mode.JSON_SCHEMA,
)


class UserDetail(BaseModel):
    name: str
    age: int


user = create(
    messages=[
        {
            "role": "user",
            "content": "Extract `Jason is 30 years old`",
        }
    ],
    response_model=UserDetail,
)

print(user)
#> name='Jason' age=30

其他提供商

Groq

Groq 平台(更多详情请参见我们的 Groq 文档Groq 官方文档)凭借其张量架构提供了独特的处理方法。这项创新显著提升了结构化输出处理的性能。

export GROQ_API_KEY="your-api-key"
import os
from pydantic import BaseModel

import groq
import instructor


client = groq.Groq(
    api_key=os.environ.get("GROQ_API_KEY"),
)

# By default, the patch function will patch the ChatCompletion.create and ChatCompletion.create methods
# to support the response_model parameter
client = instructor.from_openai(client, mode=instructor.Mode.MD_JSON)


# Now, we can use the response_model parameter using only a base model
# rather than having to use the OpenAISchema class
class UserExtract(BaseModel):
    name: str
    age: int


user: UserExtract = client.chat.completions.create(
    model="mixtral-8x7b-32768",
    response_model=UserExtract,
    messages=[
        {"role": "user", "content": "Extract jason is 25 years old"},
    ],
)

assert isinstance(user, UserExtract), "Should be instance of UserExtract"

print(user)
#> name='jason' age=25

Together AI

Together AI 与 Instructor 结合使用时,为希望在应用中利用结构化输出的开发者提供了无缝体验。更多详情请参阅我们的 Together AI 文档 并查阅 修补指南 以增强您的应用。

export TOGETHER_API_KEY="your-api-key"
import os
from pydantic import BaseModel

import instructor
import openai


client = openai.OpenAI(
    base_url="https://api.together.xyz/v1",
    api_key=os.environ["TOGETHER_API_KEY"],
)

client = instructor.from_openai(client, mode=instructor.Mode.TOOLS)


class UserExtract(BaseModel):
    name: str
    age: int


user: UserExtract = client.chat.completions.create(
    model="mistralai/Mixtral-8x7B-Instruct-v0.1",
    response_model=UserExtract,
    messages=[
        {"role": "user", "content": "Extract jason is 25 years old"},
    ],
)

assert isinstance(user, UserExtract), "Should be instance of UserExtract"

print(user)
#> name='jason' age=25

Mistral

对于那些有兴趣使用 Instructor 探索 Mistral Large 能力的用户,我们强烈建议查阅我们关于 Mistral Large 的详细指南。

import instructor
from pydantic import BaseModel
from mistralai.client import MistralClient


client = MistralClient()

patched_chat = instructor.from_openai(
    create=client.chat, mode=instructor.Mode.MISTRAL_TOOLS
)


class UserDetails(BaseModel):
    name: str
    age: int


resp = patched_chat(
    model="mistral-large-latest",
    response_model=UserDetails,
    messages=[
        {
            "role": "user",
            "content": f'Extract the following entities: "Jason is 20"',
        },
    ],
)

print(resp)
#> name='Jason' age=20