ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Semantic Kernel Python 中的 OpenAI Structured Outputs:用 Pydantic 模型约束 LLM 输出

Semantic Kernel Python 中的 OpenAI Structured Outputs:用 Pydantic 模型约束 LLM 输出 Semantic Kernel Python 中的 OpenAI Structured Outputs用 Pydantic 模型约束 LLM 输出【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel导读本文基于 Semantic Kernel Python 仓库中的 python/samples/concepts/structured_outputs/README.md 及其配套示例系统讲解如何利用 OpenAI Structured Outputs结构化输出能力让大语言模型严格按照开发者定义的 JSON Schema 返回结果。读完本文你将掌握response_format的配置方式、Pydantic 模型的定义要点如extraforbid的严格模式、如何与函数调用Function Calling结合以及 Azure OpenAI 与 OpenAI 两种接入方式的前置条件并理解 Semantic Kernel 在底层是如何把 Pydantic 模型转换为json_schema的。一、前置条件哪些模型与 API 版本支持 Structured Outputs结构化输出不是所有模型、所有 API 版本都支持的。根据 python/samples/concepts/structured_outputs/README.md 的说明接入前必须先确认你的模型与 API 版本满足以下条件。Azure OpenAI模型需要是gpt-4o-2024-08-06或更新版本API 版本需要使用2024-08-01-preview如果使用 Azure AD Token而非 API Key进行认证则你的 Azure AD 用户必须被授予Cognitive Services OpenAI Contributor角色。OpenAI原生OpenAI 官方支持结构化输出的模型包括gpt-4o-mini-2024-07-18及更新版本gpt-4o-2024-08-06及更新版本。说明上述模型版本与 API 版本信息以仓库 README 为准。在示例代码的注释中也同步写明了这些要求见 json_structured_outputs.py 与 json_structured_outputs_function_calling.py并提醒如果使用 Azure OpenAI需要将服务选择切换为 Azure。二、示例总览两个可运行的实战脚本structured_outputs目录下提供了两个可直接运行的示例分别演示纯结构化输出与结构化输出 函数调用两种场景文件场景核心知识点json_structured_outputs.py数学题求解机器人分步引导用户解题用 Pydantic 模型定义输出结构、response_format配置、流式/非流式两种调用json_structured_outputs_function_calling.py天气查询机器人先调插件函数再结构化作答结构化输出 FunctionChoiceBehavior.Auto 插件注册 流式结果拼接两个脚本都通过get_chat_completion_service_and_request_settings帮助函数完成服务初始化默认使用Services.AZURE_OPENAI。该帮助函数定义于 python/samples/concepts/setup/chat_completion_services.py其中Services枚举列出了仓库支持的全部聊天补全服务包括OPENAI、AZURE_OPENAI、AZURE_AI_INFERENCE、ANTHROPIC、BEDROCK、GOOGLE_AI、MISTRAL_AI、OLLAMA、ONNX、VERTEX_AI、DEEPSEEK、NVIDIA。示例注释特别提醒所选模型必须支持结构化输出。三、核心配置response_format与 Pydantic 严格模式3.1 定义 Pydantic 模型作为输出 Schema结构化输出的核心是先定义结构再让模型按结构生成。示例中定义了嵌套的 Pydantic 模型Reasoning它包含一个Step列表和一个最终答案字段from pydantic import BaseModel, ConfigDict class Step(BaseModel): model_config ConfigDict(extraforbid) explanation: str output: str class Reasoning(BaseModel): model_config ConfigDict(extraforbid) steps: list[Step] final_answer: str代码注释明确指出extraforbid用于在模型初始化时禁止任何未在模型中定义的额外字段这是保证模型严格输出、不夹带多余字段的必需配置。从源码结构看这一配置与 OpenAI 结构化输出的strict: True约束相辅相成确保模型产出的 JSON 与 Schema 完全一致。3.2 通过request_settings.response_format绑定模型这是整个示例中告诉 OpenAI 服务按 Pydantic 模型返回结构化输出的关键设置request_settings.response_format Reasoning示例还配置了其他常用采样参数request_settings.max_tokens 2000 request_settings.temperature 0.7 request_settings.top_p 0.8这些参数的取值范围在 open_ai_prompt_execution_settings.py 中有明确约束temperature取值范围为0.0 ~ 2.0top_p为0.0 ~ 1.0max_tokens必须大于 0frequency_penalty与presence_penalty均在-2.0 ~ 2.0之间number_of_responses序列化别名n在1 ~ 128之间。3.3response_format的三种合法取值源码级解析在 OpenAIChatPromptExecutionSettings 中response_format的类型被定义为字典 /BaseModel子类 / 任意 Python 类型 /None四选一。其model_validator校验逻辑为值为None直接返回不启用结构化输出字典且type json_object按 OpenAI 传统 JSON 模式处理字典且type json_schema要求json_schema必须是合法字典并自动把内部标志structured_json_response置为True传入BaseModel子类或任意 Python 类型同样自动启用structured_json_response其他值抛出ServiceInvalidExecutionSettingsError。也就是说你既可以直接传 Pydantic 模型示例采用的方式也可以传一个标准字典甚至可以传普通 Python 类型让 Semantic Kernel 自动推导 JSON Schema。3.4 底层如何把 Pydantic 模型变成json_schema当structured_json_response为True且传入了response_format时open_ai_handler.py 会分三种情况处理response_format是BaseModel子类调用openai库的type_to_response_format_param将其转换为 OpenAI 官方要求的结构化输出参数response_format是普通 Python 类型先用KernelJsonSchemaBuilder.build(parameter_type..., structured_outputTrue)生成 JSON Schema再调用 structured_output_schema.py 中的generate_structured_output_response_format_schema封装为{ type: json_schema, json_schema: {name: name, strict: True, schema: schema}, }其中strict: True正是 OpenAI 结构化输出严格模式的标志 3.response_format是字典原样透传给服务端。这条链路说明你只需要关心 Pydantic 模型的定义JSON Schema 的生成与封装完全由 Semantic Kernel 自动完成。四、实战一纯结构化输出求解数学题4.1 完整流程json_structured_outputs.py 演示了一个分步解题的数学辅导机器人。核心流程为创建Kernel实例并注册聊天补全服务定义系统提示词You are a helpful math tutor. Guide the user through the solution step by step.配置response_format Reasoning用kernel.add_function注册一个名为chat的提示词函数将系统提示词与{{$chat_history}}模板变量拼接并把请求设置绑定到该函数向ChatHistory添加用户问题示例为how can I solve 8x 7y -23, and 4x12?调用kernel.invoke获取结果。4.2 非流式结果解析Pydantic 校验与美化输出非流式调用下服务返回的文本保存在result.value[0].content中示例用它做了一次信任校验reasoned_result Reasoning.model_validate(json.loads(result.value[0].content)) print(f{reasoned_result.model_dump_json(indent4)})先用json.loads把字符串反序列化为字典再用Reasoning.model_validate严格校验其是否符合定义的结构配合extraforbid做到零容错最后以带缩进的美化 JSON 打印。校验通过后history.add_assistant_message(str(result))把模型回复回填到对话历史保证多轮对话上下文完整。4.3 流式调用路径脚本中保留了流式调用分支stream True通过kernel.invoke_stream逐块获取StreamingChatMessageContent把每个消息块str(message[0])拼接成完整回复。流式与结构化输出可以同时使用但需要注意最终仍需对整个结果做 JSON 解析与 Pydantic 校验。五、实战二结构化输出 函数调用5.1 场景设定json_structured_outputs_function_calling.py 演示了更贴近生产环境的组合用法模型先根据用户问题决定是否调用工具函数获取数据再把结果以结构化 JSON 输出。5.2 定义并注册插件函数示例用kernel_function装饰器定义了一个WeatherPlugin提供get_weather_for_city函数对 Boston、London、Miami、Paris、Tokyo、Sydney、Tel Aviv 等城市返回写死的天气数据。参数和返回值都用typing.Annotated标注了自然语言描述供模型理解函数语义from semantic_kernel.functions import kernel_function from typing import Annotated class WeatherPlugin: kernel_function(nameget_weather_for_city, descriptionGet the weather for a city) def get_weather_for_city(self, city: Annotated[str, The input city]) - Annotated[str, The output is a string]: if city Paris: return 60 and rainy # ... 其他城市注册方式为kernel.add_plugin(WeatherPlugin(), plugin_nameweather)5.3 启用函数自动调用与示例一不同这里在请求设置中额外启用了函数选择行为request_settings.function_choice_behavior FunctionChoiceBehavior.Auto( filters{excluded_plugins: [chat]} )FunctionChoiceBehavior定义于 function_choice_behavior.py其类注释说明了三种行为Auto自动调用模式由模型自行决定调用哪些函数如有必要NoneInvoke不真正调用函数模型只描述如果要完成任务会如何调用Required强制模型必须调用指定函数才能完成任务。maximum_auto_invoke_attempts默认值为 5即最多自动调用 5 次filters支持excluded_plugins、included_plugins、excluded_functions、included_functions四种过滤维度。示例用filters{excluded_plugins: [chat]}排除 chat 插件自身避免模型把聊天函数误当作可调用工具。5.4 流式场景下过滤函数调用中间结果脚本的流式分支有一个值得注意的细节遍历流式消息时用isinstance(item, FunctionResultContent)判断消息项是否为函数调用返回的中间结果如果是则跳过、不打印只拼接最终的文本内容if not any(isinstance(item, FunctionResultContent | FunctionResultContent) for item in message[0].items): print(str(message[0]), end, flushTrue) result_content.append(message[0])最后用reduce(lambda x, y: x y, result_content)把分片拼接成完整响应再走与示例一相同的Reasoning.model_validate校验流程。FunctionResultContent与StreamingChatMessageContent均来自semantic_kernel.contents包。5.5 运行结果示例脚本注释给出了调用What is the weather in Paris?时的预期输出结构化 JSON{ steps: [ { explanation: User requested the current weather condition in Paris, so I utilized the weather-get_weather_for_city function to retrieve the data., output: The weather in Paris is 60 degrees Fahrenheit and rainy. } ], final_answer: The current weather in Paris is 60 degrees Fahrenheit and rainy. }可以看到模型先通过函数调用拿到了巴黎的天气数据再把推理步骤 最终答案装进预定义的结构中返回——这正是工具调用结果转结构化输出的完整链路。六、运行方式与注意事项6.1 环境准备两个示例均通过get_chat_completion_service_and_request_settings(Services.AZURE_OPENAI)初始化服务默认走 Azure OpenAI 路径。该帮助函数见 chat_completion_services.py使用AzureCliCredential()Azure CLI 登录凭据完成认证无需在代码里硬编码密钥。仓库同时支持通过构造函数、环境变量、环境文件三种方式注入服务凭据。如果你使用原生 OpenAI可将枚举切换为Services.OPENAI此时会构造OpenAIChatCompletion并从环境变量读取 API Key 与模型 ID。6.2 关键注意事项模型必须支持结构化输出切换服务前请对照第一节的模型清单确认Azure 用 Token 认证时确保 Azure AD 用户已分配Cognitive Services OpenAI Contributor角色extraforbid不要省略它是保证输出严格符合 Schema 的重要前提函数调用过滤启用FunctionChoiceBehavior.Auto时建议用filters排除不需要暴露给模型的插件流式结果仍需整体校验流式输出最终拼接后的文本同样要走Reasoning.model_validate(json.loads(...))。七、总结OpenAI Structured Outputs 在 Semantic Kernel Python 中的落地路径非常清晰定义 Pydantic 模型 → 赋给request_settings.response_format→ 让模型按 Schema 生成 → 用model_validate校验。在此基础上结合FunctionChoiceBehavior.Auto与kernel_function插件即可构建自主调用工具 严格结构化输出的可靠 Agent 工作流。本文所有结论均可回溯到仓库中的两个示例脚本及其底层源码实现建议直接运行示例并结合 structured_outputs 目录 下的代码进行实践验证。【免费下载链接】semantic-kernelIntegrate cutting-edge LLM technology quickly and easily into your apps项目地址: https://gitcode.com/GitHub_Trending/se/semantic-kernel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表