Instructor:58种Prompt技术让 LLM输出更加结构化和可控

Instructor:58种Prompt技术让 LLM输出更加结构化和可控

让 LLM 结构化输出,一直是个热点关注的问题。在之前介绍过一些库旨在解决这些问题,比如:Outlines:让LLM结构化输出可控,提升LLM应用的稳定性

图片

Instructor[1] 也是目标解决这个问题的 Python 库,并且更进一步,以简单而强大的方式来定义、验证和控制 AI 输出的结构,可直接返回可操作的的 pydantic 对象,Instructor 提它支持 OpenAI、Anthropic、Cohere 等多种主流 LLM 提供商,极大地简化了开发者与 AI 交互的工作流程。

核心功能包括:

  1. 使用 Pydantic 模型精确定义输出结构

  2. 自动响应验证和重试机制

  3. 支持流式响应处理

  4. 提供灵活的多后端集成

通过简单的代码示例,开发者可以快速实现结构化输出:

import instructor
from pydantic import BaseModel
from openai import OpenAI


# Define your desired output structure
class UserInfo(BaseModel):
    name: str
    age: int


# Patch the OpenAI client
client = instructor.from_openai(OpenAI())

# Extract structured data from natural language
user_info = client.chat.completions.create(
    model="gpt-4o-mini",
    response_model=UserInfo,
    messages=[{"role": "user", "content": "John Doe is 30 years old."}],
)

print(user_info.name)
#> John Doe
print(user_info.age)
#> 30

在实现上,instructor 针对于不同的 LLM 编写了依赖 json 进行格式化的实现。

   mode_handlers = {  # type: ignore
        Mode.FUNCTIONS: handle_functions,
        Mode.TOOLS_STRICT: handle_tools_strict,
        Mode.TOOLS: handle_tools,
        Mode.MISTRAL_TOOLS: handle_mistral_tools,
        Mode.JSON_O1: handle_json_o1,
        Mode.JSON: lambda rm, nk: handle_json_modes(rm, nk, Mode.JSON),  # type: ignore
        Mode.MD_JSON: lambda rm, nk: handle_json_modes(rm, nk, Mode.MD_JSON),  # type: ignore
        Mode.JSON_SCHEMA: lambda rm, nk: handle_json_modes(rm, nk, Mode.JSON_SCHEMA),  # type: ignore
        Mode.ANTHROPIC_TOOLS: handle_anthropic_tools,
        Mode.ANTHROPIC_JSON: handle_anthropic_json,
        Mode.COHERE_JSON_SCHEMA: handle_cohere_json_schema,
        Mode.COHERE_TOOLS: handle_cohere_tools,
        Mode.GEMINI_JSON: handle_gemini_json,
        Mode.GEMINI_TOOLS: handle_gemini_tools,
        Mode.VERTEXAI_TOOLS: handle_vertexai_tools,
        Mode.VERTEXAI_JSON: handle_vertexai_json,
        Mode.CEREBRAS_JSON: handle_cerebras_json,
        Mode.CEREBRAS_TOOLS: handle_cerebras_tools,
        Mode.FIREWORKS_JSON: handle_fireworks_json,
        Mode.FIREWORKS_TOOLS: handle_fireworks_tools,
        Mode.WRITER_TOOLS: handle_writer_tools,
    }

具体的解析实现。

def handle_json_modes(
    response_model: type[T], new_kwargs: dict[str, Any], mode: Mode
) -> tuple[type[T], dict[str, Any]]:
    message = dedent(
        f"""
        As a genius expert, your task is to understand the content and provide
        the parsed objects in json that match the following json_schema:\n

        {json.dumps(response_model.model_json_schema(), indent=2, ensure_ascii=False)}

        Make sure to return an instance of the JSON, not the schema itself
        """
    )

    if mode == Mode.JSON:
        new_kwargs["response_format"] = {"type": "json_object"}
    elif mode == Mode.JSON_SCHEMA:
        new_kwargs["response_format"] = {
            "type": "json_object",
            "schema": response_model.model_json_schema(),
        }
    elif mode == Mode.MD_JSON:
        new_kwargs["messages"].append(
            {
                "role": "user",
                "content": "Return the correct JSON response within a ```json codeblock. not the JSON_SCHEMA",
            },
        )
        new_kwargs["messages"] = merge_consecutive_messages(new_kwargs["messages"])

    if new_kwargs["messages"][0]["role"] != "system":
        new_kwargs["messages"].insert(
            0,
            {
                "role": "system",
                "content": message,
            },
        )
    elif isinstance(new_kwargs["messages"][0]["content"], str):
        new_kwargs["messages"][0]["content"] += f"\n\n{message}"
    elif isinstance(new_kwargs["messages"][0]["content"], list):
        new_kwargs["messages"][0]["content"][0]["text"] += f"\n\n{message}"
    else:
        raise ValueError(
            "Invalid message format, must be a string or a list of messages"
        )

    return response_model, new_kwargs

可以看出,这种利用 LLM 解决 LLM 的问题的方式值得借鉴,这也是笔者介绍这个项目的目的。官方与 OpenAI、微软和谷歌的研究人员合作发布了名为《The Prompt Report: A Systematic Survey of Prompting Techniques[2]》的报告,该报告调研了超过 1500 篇有关Prompt技术论文,并将发现总结为 58 种不同的提示技术。他们将这些技术应用在 Instructor 这个项目中,形成了有关结构化 LLM 输出的Prompt 最佳实践[3],可以参考学习。

除此之外,Instructor 还提供了很多工程层面的改进和优化,并且支持多种语言,包括 Python、TypeScript、Ruby、Go 等。该项目获得了已获得 8.4k 收藏,每月60万下载,并持续在 GitHub 上活跃更新,感兴趣的开发者可以关注学习。

[1] Instructor: https://github.com/instructor-ai/instructor

[2] The Prompt Report: A Systematic Survey of Prompting Techniques: https://trigaten.github.io/Prompt_Survey_Site/

[3] Prompt 最佳实践: https://python.useinstructor.com/prompting/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值