# Structured Outputs
## 概述
Structured Outputs 是指通过预定义格式约束,使大模型生成内容严格遵循指定结构。该功能可显著提升生成结果的可控性,适用于需要精确格式输出的场景(如API调用、数据解析、代码生成等),同时支持动态语法扩展,平衡灵活性与规范性。
FastDeploy 支持使用 [XGrammar](https://xgrammar.mlc.ai/docs/) 后端生成结构化输出。
支持输出格式
- `json格式`: 输出内容为标准的 JSON 格式
- `正则表达式格式(regex)`: 精确控制文本模式(如日期、邮箱、身份证号等),支持复杂正则表达式语法
- `选项格式(choice)`: 输出严格限定在预定义选项中
- `语法格式(grammar)`: 使用扩展 BNF 语法定义复杂结构,支持字段名、类型及逻辑关系的联合约束
- `结构标签格式(structural_tag)`: 通过标签树定义结构化输出,支持嵌套标签、属性校验及混合约束
## 使用方式
服务启动时,可以通过 `--guided-decoding-backend` 参数指定期望使用的后端,如果指定 `auto`, FastDeploy 会自动选择合适的后端。
### OpenAI 接口
FastDeploy 支持 OpenAI 的 [Completions](https://platform.openai.com/docs/api-reference/completions) 和 [Chat Completions](https://platform.openai.com/docs/api-reference/chat) API,OpenAI 通过 `response_format` 参数指定 Structured Outputs 的输出格式。
FastDeploy 支持通过指定 `json_object` 来保证输出为json格式,如果想指定 JSON 内部具体参数名、类型等信息,可以通过 `json_schema` 来指定详细信息,详细使用方法可以参考示例。
```python
import openai
port = "8170"
client = openai.Client(base_url=f"http://127.0.0.1:{port}/v1", api_key="null")
completion = client.chat.completions.create(
model="null",
messages=[
{
"role": "user",
"content": "生成一个包含以下信息的JSON对象:中国四大发明名称、发明朝代及简要描述(每项不超过50字)",
}
],
response_format={"type": "json_object"}
)
print(completion.choices[0].message.content)
print("\n")
```
输出
```
{"inventions": [{"name": "造纸术", "dynasty": "东汉", "description": "蔡伦改进造纸术,用树皮、麻头等为原料,成本低廉,推动文化传播。"}, {"name": "印刷术", "dynasty": "唐朝", "description": "雕版印刷术在唐朝出现,后毕昇发明活字印刷术,提高印刷效率。"}, {"name": "火药", "dynasty": "唐朝", "description": "古代炼丹家偶然发明,后用于军事,改变了战争方式和格局。"}, {"name": "指南针", "dynasty": "战国", "description": "最初称司南,后发展为指南针,为航海等提供方向指引。"}]}
```
以下示例要求模型返回一个 book 信息的 json 数据,json 数据中必须包含`author、title、genre`三个字段,且`genre`必须在给定 `BookType` 中。
```python
import openai
from pydantic import BaseModel
from enum import Enum
class BookType(str, Enum):
romance = "Romance"
historical = "Historical"
adventure = "Adventure"
mystery = "Mystery"
dystopian = "Dystopian"
class BookDescription(BaseModel):
author: str
title: str
genre: BookType
port = "8170"
client = openai.Client(base_url=f"http://127.0.0.1:{port}/v1", api_key="null")
completion = client.chat.completions.create(
model="null",
messages=[
{
"role": "user",
"content": "生成一个JSON,描述一本中国的著作,要包含作者、标题和书籍类型。",
}
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "book-description",
"schema": BookDescription.model_json_schema()
},
},
)
print(completion.choices[0].message.content)
print("\n")
```
输出
```
{"author": "曹雪芹", "title": "红楼梦", "genre": "Historical"}
```
`structural_tag` 可以提取输入内容中的重点信息,并调用指定方法,返回预定义的结构化输出。以下示例展示了通过 `structural_tag` 获取指定时区并输出格式化结果。
```python
import openai
port = "8170"
client = openai.Client(base_url=f"http://127.0.0.1:{port}/v1", api_key="null")
content_str = """
你有以下函数可以调用:
{
"name": "get_current_date",
"description": "根据给定的时区获取当前日期和时间",
"parameters": {
"type": "object",
"properties": {
"timezone": {
"type": "string",
"description": "获取当前日期和时间的时区, 例如: Asia/Shanghai",
}
},
"required": ["timezone"],
}
}
如果你选择只调用函数,请按照以下格式回复:
<{start_tag}={function_name}>{parameters}{end_tag}
其中
start_tag => `