Генерация структурированных данных
Модели GigaChat могут генерировать структурированные данные в соответствии с переданной в запросе JSON-схемой или регулярным выражением. Такая функциональность полезна, например, для извлечения сущностей из текста или парсинга документов.
Как и для генерации текста, для получения структурированных данных используются запросы POST /v1/chat/completions и POST /v2/chat/completions.
Формат и схема данных задаются в объекте response_format.
Возможные значения поля response_format.type:
text— принудительная генерация текста. В этом случае объектresponse_fortmatне может содержать другие поля;json_schema— генерация JSON-объекта, обернутого в строку. Схема объекта передается в полеresponse_format.schema;regex— генерация текста в соответствии с переданным регулярным выражением. Регулярное выражение передается в полеresponse_format.regex.
Примеры запросов:
from gigachat import GigaChat
from gigachat.models import Chat, Messages, MessagesRole
from gigachat import GigaChat
client = GigaChat(
base_url="https://gigachat-ift.sberdevices.delta.sbrf.ru/v1",
cert_file="./certs/<сертификат>.pem",
key_file="./certs/<ключ>.key",
verify_ssl_certs=False,
)
PROMPT = "27 октября 2023 года у меня родился сын"
chat = Chat(
model="GigaChat-2-Max",
messages=[Messages(role=MessagesRole.USER, content=PROMPT)],
response_format={
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Дата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"additionalProperties": True,
"required": [
"date"
]
},
"strict": True
},
)
resp = client.chat(chat)
print(resp)
curl --request POST \
--url https://gigachat-ift.sberdevices.delta.sbrf.ru/v1/chat/completions \
--cert <сертификат>.pem \
--key <ключ>.key \
-k \
--header "Content-Type: application/json" \
--data '{
"model": "GigaChat-2-Max",
"messages": [
{
"content": "27 октября 2023 года у меня родился сын",
"role": "user"
}
],
"response_format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Дата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"required": ["date"]
},
"strict": true
}
}'
Пример ответа модели в виде обернутого в строку JSON-объекта:
{
"choices": [
{
"message": {
"content": "{\n \"date\": \"27 октября 2023 года\",\n \"event\": \"рождение сына\"\n}",
"role": "assistant"
},
"index": 0,
"finish_reason": "stop"
}
],
"created": 1780069601,
"model": "GigaChat-2-Max:2.0.30.1",
"object": "chat.completions",
"usage": {
"prompt_tokens": 1,
"completion_tokens": 32,
"total_tokens": 33,
"precached_prompt_tokens": 31
}
}
Описание схемы данных
Схема данных, которой должен соответствовать ответ модели, передается в поле response_format.schema.
При этом, если в схеме отсутствует описание обязательных полей в массиве required, модель сгенерирует произвольный JSON-объект.
Чтобы ответ строго соответствовал схеме, передайте список обязательных полей в массиве required и задайте параметр "strict": true.
Тогд а ответ будет содержать все поля, в том числе необязательные.
Если передать список обязательных полей без параметра "strict": true, ответ модели может содержать поля, неописанные в схеме.
Вы также можете задать схему данных с помощью модели Pydantic.
{
"response_format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Дата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"additionalProperties": true,
"required": [
"date"
]
},
"strict": true
}
}
from pydantic import BaseModel, Field
class Event(BaseModel):
date: str = Field(description="Дата в формате dd.mm")
event: str | None = Field(default=None, description="Наименование события")
SDK автоматически обрабатывает Pydantic-модель и создает соответствующую JSON-схему:
from gigachat import GigaChat
from gigachat.models import ChatCompletionRequest, ChatMessage, ChatModelOptions, ChatResponseFormat
from pydantic import BaseModel, Field
# Описание данных с помощью Pydantic
class Event(BaseModel):
date: str = Field(description="Дата в формате dd.mm")
event: str | None = Field(default=None, description="Наименование события")
request = ChatCompletionRequest(
messages=[ChatMessage(
role="user",
content="27 октября 2023 года у меня родился сын"
)],
model_options=ChatModelOptions(
response_format=ChatResponseFormat(
type="json_schema",
schema=Event,
strict=True)
),
)
with GigaChat(
base_url="https://gigachat-ift.sberdevices.delta.sbrf.ru/v2",
cert_file="./certs/<сертификат>.pem",
key_file="./certs/<ключ>.key",
verify_ssl_certs=False,
) as client:
response = client.chat.create(request)
print(response.messages[0])
Использование регулярных выражений
Чтобы модель сгенерировала ответ в соответствии с заданным регулярным выражением, передайте его в формате строки в поле response_format.regex.
Для строгого соответствия используйте параметр "strict": true.
Пример запроса:
from gigachat import GigaChat
from gigachat.models import Chat, Messages, MessagesRole
from gigachat import GigaChat
client = GigaChat(
base_url="https://gigachat-ift.sberdevices.delta.sbrf.ru/v1",
cert_file="./certs/<сертификат>.pem",
key_file="./certs/<ключ>.key",
verify_ssl_certs=False,
)
PROMPT = "Сгенерируй произвольную дату"
chat = Chat(
model="GigaChat-2-Max",
messages=[Messages(role=MessagesRole.USER, content=PROMPT)],
response_format={
"type": "regex",
"regex": "^(0[1-9]|[12][0-9]|3[01])\\.(0[1-9]|1[0-2])\\.(?:\\d{2}|\\d{4})$",
"strict": True
},
)
resp = client.chat(chat)
print(resp)
curl --request POST \
--url https://gigachat-ift.sberdevices.delta.sbrf.ru/v1/chat/completions \
--cert <сертификат>.pem \
--key <ключ>.key \
-k \
--header "Content-Type: application/json" \
--data '{
"model": "GigaChat-2-Max",
"messages": [
{
"content": "27 октября 2023 года у меня родился сын",
"role": "user"
}
],
"response_format": {
"type": "regex",
"regex": "^(0[1-9]|[12][0-9]|3[01])\\.(0[1-9]|1[0-2])\\.(?:\\d{2}|\\d{4})$",
"strict": true
}
}'
Пример ответа:
{
"choices": [
{
"message": {
"content": "27.10.2023",
"role": "assistant"
},
"index": 0,
"finish_reason": "stop"
}
],
"created": 1780323401,
"model": "GigaChat-2-Max:2.0.30.1",
"object": "chat.completions",
"usage": {
"prompt_tokens": 1,
"completion_tokens": 12,
"total_tokens": 13,
"precached_prompt_tokens": 31
}
}
Структурированные данные в v2/chat/completions
В отличие от POST /v1/chat/completions, в запросе POST /v2/chat/completions параметры структурированного вывода и описание схемы данных передаются в объекте model_options.response_format.
В остальном оба способа работают одинаково:
from gigachat import GigaChat
from gigachat.models import ChatCompletionRequest, ChatMessage, ChatModelOptions, ChatResponseFormat
SCHEMA = {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Дата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"additionalProperties": True,
"required": ["date"]
}
request = ChatCompletionRequest(
model="GigaChat-2-Max",
messages=[ChatMessage(role="user", content=[{"text": "27 октября 2023 года у меня родился сын"}])],
model_options=ChatModelOptions(
response_format=ChatResponseFormat(
type="json_schema",
schema=SCHEMA,
strict=True,
)
),
)
client = GigaChat(
base_url="https://gigachat-ift.sberdevices.delta.sbrf.ru/v2",
cert_file="./certs/<сертификат>.pem",
key_file="./certs/<ключ>.key",
verify_ssl_certs=False,
)
response = client.chat.create(request)
print(response)
curl --request POST \
--url https://gigachat-ift.sberdevices.delta.sbrf.ru/v2/chat/completions \
--cert <сертификат>.pem \
--key <ключ>.key \
-k \
--header "Content-Type: application/json" \
--data '{
"model": "GigaChat-2-Max",
"messages": [
{
"role": "user",
"content": [
{
"text": "27 октября 2023 года у меня родился сын"
}
]
}
],
"model_options": {
"response_format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Дата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"required": [
"date"
]
},
"strict": true
}
}
}'
Структура ответа также отличается от POST /v1/chat/completions:
{
"model": "GigaChat-2-Max:2.0.30.01",
"created_at": 1781694924,
"messages": [
{
"role": "assistant",
"content": [
{
"text": " {\n \"date\": \"27 октября 2023\",\n \"event\": \"рождение сына\"\n}"
}
]
}
],
"finish_reason": "stop",
"usage": {
"input_tokens": 29,
"input_tokens_details": { "prompt_tokens": 29, "cached_tokens": 3 },
"output_tokens": 31,
"total_tokens": 60
}
}
Потоковая передача данных
Структурированные данные можно получать в потоке SSE-событий так же, как и обычный текст.
Для запуска потоковой передачи данных используйте метод stream().
Запрос POST /v1/chat/completions:
from gigachat import GigaChat
from gigachat.models import Chat, Messages, MessagesRole
from gigachat import GigaChat
PROMPT = "27 октября 2023 года у меня родился сын"
chat = Chat(
model="GigaChat-2-Max",
messages=[Messages(role=MessagesRole.USER, content=PROMPT)],
response_format={
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Дата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"additionalProperties": True,
"required": [
"date"
]
},
"strict": True
},
)
client = GigaChat(
base_url="https://gigachat-ift.sberdevices.delta.sbrf.ru/v1",
cert_file="./certs/<сертификат>.pem",
key_file="./certs/<ключ>.key",
verify_ssl_certs=False,
)
# Извлечение и построчное отображение содержимого событий
for chunk in client.stream(chat):
print(chunk.choices[0].delta.content, end="", flush=True)
Запрос POST /v2/chat/completions:
from gigachat import GigaChat
from gigachat.models import ChatCompletionRequest, ChatMessage, ChatModelOptions, ChatResponseFormat
SCHEMA = {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Д ата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"additionalProperties": True,
"required": ["date"]
}
request = ChatCompletionRequest(
model="GigaChat-2-Max",
messages=[ChatMessage(role="user", content=[{"text": "27 октября 2023 года у меня родился сын"}])],
model_options=ChatModelOptions(
response_format=ChatResponseFormat(
type="json_schema",
schema=SCHEMA,
strict=True,
)
),
)
client = GigaChat(
base_url="https://gigachat-ift.sberdevices.delta.sbrf.ru/v2",
cert_file="./certs/<сертификат>.pem",
key_file="./certs/<ключ>.key",
verify_ssl_certs=False,
)
# Извлечение и построчное отображение содержимого событий
for chunk in client.chat.stream(request):
for msg in chunk.messages or []:
for part in msg.content or []:
if text := part.text:
print(text, end="", flush=True)
Запрос POST /v1/chat/completions:
curl --request POST \
--url https://gigachat-ift.sberdevices.delta.sbrf.ru/v1/chat/completions \
--cert <сертификат>.pem \
--key <ключ>.key \
-k \
--header "Content-Type: application/json" \
--data '{
"model": "GigaChat-2-Max",
"messages": [
{
"content": "27 октября 2023 года у меня родился сын",
"role": "user"
}
],
"stream": true,
"response_format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Дата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"required": ["date"]
},
"strict": true
}
}'
Запрос POST /v2/chat/completions:
curl --request POST \
--url https://gigachat-ift.sberdevices.delta.sbrf.ru/v2/chat/completions \
--cert <сертификат>.pem \
--key <ключ>.key \
-k \
--header "Content-Type: application/json" \
--data '{
"model": "GigaChat-2-Max",
"messages": [
{
"role": "user",
"content": [
{
"text": "27 октября 2023 года у меня родился сын"
}
]
}
],
"stream": true,
"model_options": {
"response_format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "Дата в формате dd.mm"
},
"event": {
"type": "string",
"description": "Наименование события"
}
},
"required": [
"date"
]
},
"strict": true
}
}
}'
При работе с потоковой передачей учитывайте, что формат событий в ответе на запросы POST /v1/chat/completions и POST /v2/chat/completions отличается:
data: {"choices":[{"delta":{"content":"{\n \"date\":","role":"assistant"},"index":0}],"created":1780064210,"model":"GigaChat-2-Max:2.0.30.1","object":"chat.completions"}
data: {"choices":[{"delta":{"content":" \"27 октября 2023 года\",\n \"event\":","role":"assistant"},"index":0}],"created":1780064211,"model":"GigaChat-2-Max:2.0.30.1","object":"chat.completions"}
data: {"choices":[{"delta":{"content":" \"рождение сына\"\n}","role":"assistant"},"index":0}],"created":1780064211,"model":"GigaChat-2-Max:2.0.30.1","object":"chat.completions"}
data: {"choices":[{"delta":{"content":""},"index":0,"finish_reason":"stop"}],"created":1780064211,"model":"GigaChat-2-Max:2.0.30.1","object":"chat.completions","usage":{"prompt_tokens":1,"completion_tokens":32,"total_tokens":33,"precached_prompt_tokens":31}}
data: [DONE]
event: response.message.delta
data: {"model":"GigaChat-2-Max:2.0.30.1","created_at":1780064131,"messages":[{"role":"assistant","content":[{"text":"{\n \"date\":"}]}]}
event: response.message.delta
data: {"model":"GigaChat-2-Max:2.0.30.1","created_at":1780064131,"messages":[{"role":"assistant","content":[{"text":" \"27 октября 2023\",\n \"event\":"}]}]}
event: response.message.delta
data: {"model":"GigaChat-2-Max:2.0.30.1","created_at":1780064131,"messages":[{"role":"assistant","content":[{"text":" \"рождение сына\"\n}"}]}]}
event: response.message.done
data: {"model":"GigaChat-2-Max:2.0.30.1","created_at":1780064131,"finish_reason":"stop","usage":{"input_tokens":1,"input_tokens_details":{"prompt_tokens":1,"cached_tokens":31},"output_tokens":31,"total_tokens":32}}
Разбор ответа с помощью chat_parse()
Используйте метод chat_parse(), чтобы автоматически разобрать JSON и провалидировать его с помощью Pydantic-модели.
Метод возвращает как разобранный JSON, так и исходные данные в экземпляре ChatCompletion.
from gigachat import GigaChat
from gigachat.models import ChatCompletionRequest, ChatMessage, ChatModelOptions, ChatResponseFormat
from pydantic import BaseModel, Field
class Event(BaseModel):
date: str = Field(description="Дата в формате dd.mm")
event: str | None = Field(default=None, description="Наименование события")
PROMPT = "27 октября 2023 года у меня родился сын"
with GigaChat(
model="GigaChat-2-Max",
base_url="https://gigachat-ift.sberdevices.delta.sbrf.ru/v1",
cert_file="./certs/<сертификат>.pem",
key_file="./certs/ключ.pem.key",
verify_ssl_certs=False,
) as client:
completion, parsed_response = client.chat_parse(
PROMPT,
response_format=Event,
strict=True,
)
print("=== client.chat_parse() ===")
print("Дата:", parsed_response.date)
print("Событие:", parsed_response.event)
print(f"Кол-во токенов: {completion.usage.total_tokens}")