Cortex COMPLETE 结构化输出¶
COMPLETE 结构化输出允许您提供完成响应必须遵循的 JSON 架构。这减少了 AI 数据管道中对后处理的需求,并能无缝集成需要确定性响应的系统。COMPLETE 会根据你的 JSON 架构验证每个生成的词元,以确保响应符合所提供的架构。
COMPLETE 支持的每个模型支持结构化输出,但最强大的模型通常会产生更高质量的响应。
使用 COMPLETE 结构化输出¶
要获得采用结构化格式的响应,请指定 JSON 架构 (https://json-schema.org/) 作为 response_format
实参。提供的 JSON 架构对象定义了生成文本必须遵循的结构、数据类型和约束条件,包括必填字段。对于简单任务,您无需指定输出格式的任何细节,甚至无需指示模型“以 JSON 格式响应”。对于更复杂的任务,提示模型以 JSON 格式响应可以提高准确性;详见 优化 JSON 依从性准确性。
该架构必须作为 options
实参内的子对象指定,如此处所示,而非字符串形式。这要求字符串使用单引号,而非 JSON 中使用的双引号,因为这是一个 SQL 对象。响应是一个 JSON 对象。
options: {
...
response_format: {
'type': 'json',
'schema': {
'type': 'object',
'properties': {
'property_name': {
'type': 'string'
},
...
},
'required': ['property_name', ...]
}
}
SQL 示例¶
以下示例演示如何使用 response_format
实参来指定响应的 JSON 架构。
SELECT SNOWFLAKE.CORTEX.COMPLETE('mistral-large2', [
{
'role': 'user',
'content': 'Return the customer sentiment for the following review: New kid on the block, this pizza joint! The pie arrived neither in a flash nor a snail\'s pace, but the taste? Divine! Like a symphony of Italian flavors, it was a party in my mouth. But alas, the party was a tad pricey for my humble abode\'s standards. A mixed bag, I\'d say!'
}
],
{
'temperature': 0,
'max_tokens': 1000,
'response_format':{
'type':'json',
'schema':{'type' : 'object','properties' : {'sentiment_categories':{'type':'array','items':{'type':'object','properties':
{'food_quality' : {'type' : 'string'},'food_taste': {'type':'string'}, 'wait_time': {'type':'string'}, 'food_cost': {'type':'string'}},'required':['food_quality','food_taste' ,'wait_time','food_cost']}}}}
}
}
);
响应:
{
"created": 1738683744,
"model": "mistral-large2",
"structured_output": [
{
"raw_message": {
"sentiment_categories": [
{
"food_cost": "negative",
"food_quality": "positive",
"food_taste": "positive",
"wait_time": "neutral"
}
]
},
"type": "json"
}
],
"usage": {
"completion_tokens": 60,
"prompt_tokens": 94,
"total_tokens": 154
}
}
Python 示例¶
备注
结构化输出功能在 snowflake-ml-python
版本 1.8.0 及更高版本中受支持。
以下示例演示如何使用 response_format
实参来指定响应的 JSON 架构。
from snowflake.cortex import complete, CompleteOptions
response_format = {
"type": "json",
"schema": {
"type": "object",
"properties": {
"people": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "number"},
},
"required": ["name", "age"],
},
}
},
"required": ["people"],
},
}
prompt = [{
"role": "user",
"content": "Please prepare me a data set of 5 ppl and their age",
}]
options = CompleteOptions(
max_tokens=4096,
temperature=0.7,
top_p=1,
guardrails=False,
response_format=response_format
)
result = complete(
model="claude-3-5-sonnet",
prompt=prompt,
session={session_object}, # session created via connector
stream=True,
options=options,
)
output = "".join(result)
print(output)
响应:
{"people": [{"name":"John Smith","age":32},{"name":"Sarah Johnson","age":28},
{"name":"Michael Chen","age":45},{"name":"Emily Davis","age":19},{"name":"Robert Wilson","age":56}]}
REST API 示例¶
您可以使用 Snowflake Cortex LLM REST API 调用 COMPLETE 与您选择的 LLM。下面是使用 Cortex LLM REST API 提供架构的示例:
curl --location --request POST 'https://<account_identifier>.snowflakecomputing.cn/api/v2/cortex/inference:complete'
--header 'Authorization: Bearer <jwt>' \
--header 'Accept: application/json, text/event-stream' \
--header 'Content-Type: application/json' \
--data-raw '{
"model": "claude-3-5-sonnet",
"messages": [{
"role": "user",
"content": "Order a pizza for a hungry space traveler heading to the planet Zorgon. Make sure to include a special instruction to avoid any intergalactic allergens."
}],
"max_tokens": 1000,
"response_format": {
"type": "json",
"schema":
{
"type": "object",
"properties":
{
"crust":
{
"type": "string",
"enum":
[
"thin",
"thick",
"gluten-free",
"Rigellian fungus-based"
]
},
"toppings":
{
"type": "array",
"items":
{
"type": "string",
"enum":
[
"Gnorchian sausage",
"Andromedian mushrooms",
"Quasar cheese"
]
}
},
"delivery_planet":
{
"type": "string"
},
"special_instructions":
{
"type": "string"
}
},
"required":
[
"crust",
"toppings",
"delivery_planet"
]
}
}
}
}'
响应:
data: {"id":"4d62e41a-d2d7-4568-871a-48de1463ed2a","model":"claude-3-5-sonnet","choices":[{"delta":{"content":"{\"crust\":","content_list":[{"type":"text","text":"{\"crust\":"}]}}],"usage":{}}
data: {"id":"4d62e41a-d2d7-4568-871a-48de1463ed2a","model":"claude-3-5-sonnet","choices":[{"delta":{"content":" \"thin\"","content_list":[{"type":"text","text":" \"thin\""}]}}],"usage":{}}
data: {"id":"4d62e41a-d2d7-4568-871a-48de1463ed2a","model":"claude-3-5-sonnet","choices":[{"delta":{"content":", \"topping","content_list":[{"type":"text","text":", \"topping"}]}}],"usage":{}}
data: {"id":"4d62e41a-d2d7-4568-871a-48de1463ed2a","model":"claude-3-5-sonnet","choices":[{"delta":{"content":"s\": [\"Quasar","content_list":[{"type":"text","text":"s\": [\"Quasar"}]}}],"usage":{}}
创建一个 JSON 架构定义¶
为了获得 COMPLETE 结构化输出的最佳准确度,请遵循以下指导原则:
使用架构中的“required”字段 来指定必填字段。如果无法提取必填字段,COMPLETE 会报错。
在以下示例中,架构指示 COMPLETE 查找文档中提到的人员。
people
字段被标记为必填项,以确保人员被识别。{ 'type': 'object', 'properties': { 'dataset_name': { 'type': 'string' }, 'created_at': { 'type': 'string' }, 'people': { 'type': 'array', 'items': { 'type': 'object', 'properties': { 'name': { 'type': 'string' }, 'age': { 'type': 'number' }, 'isAdult': { 'type': 'boolean' } } } } }, 'required': [ 'dataset_name', 'created_at', 'people' ] }
响应:
{ "dataset_name": "name", "created_at": "date", "people": [ { "name": "Andrew", "isAdult": true } ] }
提供要提取的字段的详细描述,以便模型能够更准确地识别它们。例如,以下架构包括每个
people
字段的描述:name
、age
和isAdult
。{ 'type': 'object', 'properties': { 'dataset_name': { 'type': 'string' }, 'created_at': { 'type': 'string' }, 'people': { 'type': 'array', 'items': { 'type': 'object', 'properties': { 'name': { 'type': 'string', 'description': 'name should be between 9 to 10 characters' }, 'age': { 'type': 'number', 'description': 'Should be a value between 0 and 200' }, 'isAdult': { 'type': 'boolean', 'description': 'Persons is older than 18' } } } } } }
优化 JSON 依从性准确性¶
COMPLETE 结构化输出通常不需要提示;它已经明白它的响应应该符合您指定的架构。然而,任务复杂度会显著影响 LLMs 遵循 JSON 响应格式的能力。任务越复杂,指定提示就越能提高结果的准确性。
简单任务,例如文本分类、实体提取、释义和摘要任务,这些任务不需要复杂的推理,通常不需要额外的提示。对于智能程度较低的小型模型,仅使用结构化输出功能就能显著提高 JSON 的格式遵循准确度,因为它会忽略模型生成的、与提供架构无关的任何文本。
中等复杂度任务 包括任何要求模型进行额外推理的简单任务,例如为分类决策提供理由。对于这些用例,我们建议添加“以 JSON 响应”来优化性能。
复杂推理任务 会要求模型执行更具开放性和模糊性的任务,例如根据回答的相关性、专业性和忠实度来评估和评分通话质量。对于这些用例,我们建议使用最强大的模型,例如 Anthropic 的
claude-3-5-sonnet
或 Mistral AI 的mistral-large2
,并添加“以 JSON 响应”,以及有关您想要在提示中生成的架构的详细信息。
为了获得最一致的结果,请在调用 COMPLETE 时将 temperature
选项设置为 0,无论任务或模型如何。
小技巧
要处理模型可能引发的错误,请使用 TRY_COMPLETE 而不是 COMPLETE。
成本注意事项¶
Cortex COMPLETE 结构化输出功能根据处理的词元数量计算成本,但不会因对照 JSON 架构验证每个词元而产生额外计算成本。然而,处理(和计费)的词元数量会随着架构复杂性的增加而增加。一般来说,提供的架构越大越复杂,消耗的输入和输出词元就越多。深度嵌套的高度结构化响应(例如分层数据)比简单架构消耗更多词元。
限制¶
您不能在架构的键中使用空格。
属性名称允许使用的字符包括:字母、数字、连字符和下划线。名称的最大长度为 64 个字符。
您不能使用
$ref
或者$dynamicRef
引用外部架构。
不支持以下约束关键字。使用不受支持的约束关键字会导致错误。
类型 |
关键字 |
---|---|
整数 |
|
数字 |
|
字符串 |
|
数组 |
|
对象 |
|
这些限制可能会在未来的版本中得到解决。
错误条件¶
情况 |
示例消息 |
---|---|
模型输出验证失败。模型无法生成与架构匹配的响应。这可能是由于文档中未出现必填字段所致。 |
解组模型输出时发生错误。模型返回无法解析的无效 JSON。%!(EXTRA string=JSON 输入意外终止)" |
附加属性“dataset_name”不遵循架构。错误消息指定了未通过验证的属性。 |
{"$ref":"值与参考架构不匹配"}},{"errors":{"properties":"属性“type”与架构不匹配"}}, {"evaluationPath":"/properties/type","errors":{"enum":"值应与枚举指定的值之一匹配"}}]" |
不允许有额外的约束。错误消息指定了哪个属性未通过验证。 |
[{"evaluationPath":"/properties/properties","errors":{"additionalProperties":"其他属性“company”与架构不匹配"}},{"evaluationPath":"/additionalProperties/company","errors": {"$ref"值与参考架构不匹配"}},{"errors":{"additionalProperties":"其他属性“maxLength”与架构不匹配"}},{"evaluationPath":"/additionalProperties/maxLength","errors":{"schema":"由于架构设置为“false”,因此不允许任何值"}}]" |