跳到内容

教程

基于字符串初始化的统一提供者接口

Instructor 现在提供了一种简化的方式,可以通过单一一致的接口初始化任何受支持的 LLM 提供者。这种方法使得在不同 LLM 提供者之间切换变得前所未有的简单,同时还能保持您所依赖的结构化输出功能。

问题

随着 LLM 提供者数量的增长,初始化和使用不同的客户端库的复杂性也随之增加。每个提供者都有其自己的初始化模式、API 结构和怪癖。这导致代码在提供者之间不可移植,并且在您想要尝试新模型时需要大量的重构工作。

解决方案:基于字符串的初始化

我们引入了一个新的统一接口,允许您使用简单的字符串格式初始化任何受支持的提供者。

import instructor
from pydantic import BaseModel

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

# Initialize any provider with a single consistent interface
client = instructor.from_provider("openai/gpt-4")
client = instructor.from_provider("anthropic/claude-3-sonnet")
client = instructor.from_provider("google/gemini-pro")
client = instructor.from_provider("mistral/mistral-large")

from_provider 函数接受一个格式为 "provider/model-name" 的字符串,并处理设置适当客户端和正确模型的所有细节。这提供了几个关键优势:

  • 简化初始化: 无需手动创建特定于提供者的客户端
  • 一致的接口: 相同的语法适用于所有提供者
  • 减少依赖暴露: 您无需在应用程序代码中导入特定的提供者库
  • 轻松尝试: 只需修改一行代码即可在提供者之间切换

支持的提供者

基于字符串的初始化目前支持生态系统中的所有主要提供者。

  • OpenAI: "openai/gpt-4", "openai/gpt-4o", "openai/gpt-3.5-turbo"
  • Anthropic: "anthropic/claude-3-opus-20240229", "anthropic/claude-3-sonnet-20240229", "anthropic/claude-3-haiku-20240307"
  • Google Gemini: "google/gemini-pro", "google/gemini-pro-vision"
  • Mistral: "mistral/mistral-small-latest", "mistral/mistral-medium-latest", "mistral/mistral-large-latest"
  • Cohere: "cohere/command", "cohere/command-r", "cohere/command-light"
  • Perplexity: "perplexity/sonar-small-online", "perplexity/sonar-medium-online"
  • Groq: "groq/llama2-70b-4096", "groq/mixtral-8x7b-32768", "groq/gemma-7b-it"
  • Writer: "writer/palmyra-instruct", "writer/palmyra-instruct-v2"
  • AWS Bedrock: "bedrock/anthropic.claude-v2", "bedrock/amazon.titan-text-express-v1"
  • Cerebras: "cerebras/cerebras-gpt", "cerebras/cerebras-gpt-2.7b"
  • Fireworks: "fireworks/llama-v2-70b", "fireworks/firellama-13b"
  • Vertex AI: "vertexai/gemini-pro", "vertexai/text-bison"
  • Google GenAI: "genai/gemini-pro", "genai/gemini-pro-vision"

每个提供者都将使用合理的默认值进行初始化,但您也可以传递额外的关键字参数来自定义配置。有关模型的具体细节,请查阅各个提供者的文档。

异步支持

统一接口完全支持同步和异步客户端。

# Synchronous client (default)
client = instructor.from_provider("openai/gpt-4")

# Asynchronous client
async_client = instructor.from_provider("anthropic/claude-3-sonnet", async_client=True)

# Use like any other async client
response = await async_client.chat.completions.create(
    response_model=UserInfo,
    messages=[{"role": "user", "content": "Extract information about John who is 30 years old"}]
)

模式选择

您还可以指定要与提供者一起使用的结构化输出模式。

import instructor
from instructor import Mode

# Override the default mode for a provider
client = instructor.from_provider(
    "anthropic/claude-3-sonnet", 
    mode=Mode.ANTHROPIC_TOOLS
)

# Use JSON mode instead of the default tools mode
client = instructor.from_provider(
    "mistral/mistral-large", 
    mode=Mode.MISTRAL_STRUCTURED_OUTPUTS
)

# Use reasoning tools instead of regular tools for Anthropic
client = instructor.from_provider(
    "anthropic/claude-3-opus", 
    mode=Mode.ANTHROPIC_REASONING_TOOLS
)

如果未指定,每个提供者将使用其推荐的默认模式。

  • OpenAI: Mode.OPENAI_FUNCTIONS
  • Anthropic: Mode.ANTHROPIC_TOOLS
  • Google Gemini: Mode.GEMINI_JSON
  • Mistral: Mode.MISTRAL_TOOLS
  • Cohere: Mode.COHERE_TOOLS
  • Perplexity: Mode.JSON
  • Groq: Mode.GROQ_TOOLS
  • Writer: Mode.WRITER_JSON
  • Bedrock: Mode.ANTHROPIC_TOOLS (用于 Bedrock 上的 Claude)
  • Vertex AI: Mode.VERTEXAI_TOOLS

您始终可以根据您的具体需求和模型能力进行自定义。

错误处理

from_provider 函数包含强大的错误处理功能,可帮助您快速识别和修复问题。

# Missing dependency
try:
    client = instructor.from_provider("anthropic/claude-3-sonnet")
except ImportError as e:
    print("Error: Install the anthropic package first")
    # pip install anthropic

# Invalid provider format
try:
    client = instructor.from_provider("invalid-format")
except ValueError as e:
    print(e)  # Model string must be in format "provider/model-name"

# Unsupported provider
try:
    client = instructor.from_provider("unknown/model")
except ValueError as e:
    print(e)  # Unsupported provider: unknown. Supported providers are: ...

该函数会验证提供者字符串格式,检查提供者是否受支持,并确保安装了必要的软件包。

环境变量

与原生客户端库一样,from_provider 尊重为每个提供者设置的环境变量。

# Set environment variables 
import os
os.environ["OPENAI_API_KEY"] = "your-openai-key"
os.environ["ANTHROPIC_API_KEY"] = "your-anthropic-key" 
os.environ["MISTRAL_API_KEY"] = "your-mistral-key"

# No need to pass API keys directly
client = instructor.from_provider("openai/gpt-4")

故障排除

以下是使用统一提供者接口时的一些常见问题和解决方案:

未找到模型错误

如果您收到 404 错误,请检查您使用的模型名称格式是否正确。

Error code: 404 - {'type': 'error', 'error': {'type': 'not_found_error', 'message': 'model: claude-3-haiku'}}

对于 Anthropic 模型,请务必包含版本日期:- ✅ 正确:anthropic/claude-3-haiku-20240307 - ❌ 不正确:anthropic/claude-3-haiku

特定于提供者的参数

一些提供者需要特定的参数来进行 API 调用。

# Anthropic requires max_tokens
anthropic_client = instructor.from_provider(
    "anthropic/claude-3-haiku-20240307", 
    max_tokens=400  # Required for Anthropic
)

# Use models with vision capabilities for multimodal content
gemini_client = instructor.from_provider(
    "google/gemini-pro-vision"  # Required for image processing
)

工作示例

这是一个完整的示例,演示了跨多个提供者的 automodel 功能。

import os
import asyncio
import instructor
from pydantic import BaseModel, Field

class UserInfo(BaseModel):
    """User information extraction model."""
    name: str = Field(description="The user's full name")
    age: int = Field(description="The user's age in years")
    occupation: str = Field(description="The user's job or profession")

async def main():
    # Test OpenAI
    openai_client = instructor.from_provider("openai/gpt-3.5-turbo")
    openai_result = openai_client.chat.completions.create(
        response_model=UserInfo,
        messages=[{"role": "user", "content": "Jane Doe is a 28-year-old data scientist."}]
    )
    print(f"OpenAI result: {openai_result.model_dump()}")

    # Test Anthropic with async client
    if os.environ.get("ANTHROPIC_API_KEY"):
        anthropic_client = instructor.from_provider(
            model="anthropic/claude-3-haiku-20240307",
            async_client=True,
            max_tokens=400  # Required for Anthropic
        )
        anthropic_result = await anthropic_client.chat.completions.create(
            response_model=UserInfo,
            messages=[{"role": "user", "content": "John Smith is a 35-year-old software engineer."}]
        )
        print(f"Anthropic result: {anthropic_result.model_dump()}")

if __name__ == "__main__":
    asyncio.run(main())

结论

基于字符串的初始化是使 Instructor 更加用户友好和灵活的重要一步。它降低了使用多个提供者的学习曲线,并使得试验不同模型变得前所未有的简单。

优点包括:- 简化的初始化,具有一致的接口 - 自动选择合适的默认模式 - 支持同步和异步客户端 - 清晰的错误消息,可快速识别问题 - 尊重特定于提供者的环境变量 - 涵盖整个 LLM 生态系统的全面模型选择

无论您是构建新应用程序还是迁移现有应用程序,统一提供者接口都提供了一种更清晰、更易于维护的方式来处理 LLM 生态系统中的结构化输出。

立即尝试使用 instructor.from_provider() 并查看我们在仓库中的完整示例代码