Closed Suchun-sv closed 3 weeks ago
很棒的idea,2.2我觉得可以独立一个插件,JSON schema 跟 Higress 的结合点很多,例如插件的配置格式化、API文档的辅助生成(swagger/oas3也都是基于 JSON schema 扩展而来的)
Note
需要数据面的proxy wasm版本大于等于0.2.100
编译时,需要带上版本的tag,例如:tinygo build -o main.wasm -scheduler=none -target=wasi -gc=custom -tags="custommalloc nottinygc_finalizer proxy_wasm_version_0_2_100" ./
需搭配AI-Proxy插件,并且需要配置
provider = openai
,model=gpt-4o-2024-08-06
以支持结构化输出接口
AI 结构化Json文档生成和验证,可根据自然语言描述生成Json文档或者Json Schema,或根据预先定义的JsonSchema验证Json文档是否正确,并给出解释。
生成Json文档或者Json Schema约束 验证给定文档是否满足给定Json Schema约束
Name | Type | Requirement | Default | Description |
---|---|---|---|---|
model | string | optional | "gpt-4o-2024-08-06" | 指定的模型服务,注意需选择支持结构化输出接口的模型 |
enable_swagger | bool | optional | false | 是否启用swagger验证文档 |
enable_oas3 | bool | optional | true | 是否启用oas3验证文档 |
custom_askjson | object | optional | “” | 生成Json文档时使用的JsonSchema约束,此设置会覆盖默认设置 |
custom_askjsonschema | object | optional | “” | 生成Json Schema约束时使用的JsonSchema约束,此设置会覆盖默认设置 |
custom_askverify | object | optional | “” | 当验证Json文档不符合给定的Json Schema约束时,传入后续模型服务使用的JsonSchema约束,此设置会覆盖默认设置 |
Model: "gpt-4o-2024-08-06"
EnableOas3: true
Name | Type | Requirement | Description |
---|---|---|---|
desc | string | required | 自然语言描述,需要用户提供,单独提供可以根据默认Json Schema生成Json文档 |
json_doc | string | optional | json文档,和 desc 搭配可以生成相应的Json Schema约束 |
json_schema | string | optional | [type=val] 用于验证 json_doc 是否满足约束 [type=gen] 和 json_doc 一起提示LLM生成相应的Json Schema约束 |
type | string | required | 指定为 gen 或者 val ,分别代表生成和验证模式 |
返回参数
Name | Type | Requirement | Description |
---|---|---|---|
reason | string | required | LLM后端的自然语言回答 |
json | string | optional | 返回的json文档获json schema约束 |
listOfCases | string | optional | 如果生成Json文档(API文档),相应给出案例说明 |
curl -X POST "http://loalhost:8001/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-2024-08-06",
"desc": "帮我设计API接口:在请求的变量上加5,返回加和",
"type": "gen"
}'
默认使用
templates\askjson.go
中定义的json schema来生成Json文档,可以使用配置中的custom_askjson
来替换
返回示例:
{
"json": {
"api_version": "1.0",
"endpoint": "/addFive",
"method": "POST",
"parameters": [
{
"name": "number",
"type": "integer"
}
],
"response": {
"message": "The sum of the input number and 5.",
"status": "success"
}
},
"listOfCases": [
{
"caseDescription": "Add 5 to the positive integer 10",
"caseName": "Adding to positive integer",
"input": "number=10",
"output": "15"
},
{
"caseDescription": "Add 5 to zero",
"caseName": "Adding to zero",
"input": "number=0",
"output": "5"
},
{
"caseDescription": "Add 5 to negative integer -3",
"caseName": "Adding to negative integer",
"input": "number=-3",
"output": "2"
}
],
"reason": "This API is designed to take an integer input, add the number 5 to it, and return the result. It demonstrates a simple arithmetic operation applied to an API input parameter."
}
curl -X POST "http://localhost:8001/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-2024-08-06",
"desc": "我希望实现一个 JSON Schema,用于约束 Kibana 配置文件的结构。请根据以下测试用例帮助我编写该 JSON Schema。",
"json_doc": "{ \"attributes\": { \"title\": \"Sample Dashboard\", \"description\": \"This is a sample dashboard.\", \"panelsJSON\": \"[{\\\"panelIndex\\\":\\\"1\\\",\\\"gridData\\\":{\\\"x\\\":0,\\\"y\\\":0,\\\"w\\\":24,\\\"h\\\":15},\\\"type\\\":\\\"visualization\\\",\\\"id\\\":\\\"1\\\"}]\", \"optionsJSON\": \"{\\\"darkTheme\\\":false}\", \"version\": 1, \"timeRestore\": false, \"kibanaSavedObjectMeta\": { \"searchSourceJSON\": \"{\\\"query\\\":{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"lucene\\\"},\\\"filter\\\":[]}\" } }, \"type\": \"dashboard\" }",
"type": "gen"
}'
默认使用
templates\askjson.go
中定义的json schema来生成Json文档,可以使用配置中的custom_askjsonschema
来替换,注意由于现有的结构化输出接口不支持所有的Json Schema语法,所以这里生成的Json Schema仅为String类型,用户使用时需要根据实际情况进行验证并调整
{
"json": "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"type\": \"object\",\n \"properties\": {\n \"attributes\": {\n \"type\": \"object\",\n \"properties\": {\n \"title\": {\n \"type\": \"string\"\n },\n \"description\": {\n \"type\": \"string\"\n },\n \"panelsJSON\": {\n \"type\": \"string\",\n \"description\": \"Serialized JSON string of panels configuration\"\n },\n \"optionsJSON\": {\n \"type\": \"string\",\n \"description\": \"Serialized JSON string of dashboard options\"\n },\n \"version\": {\n \"type\": \"integer\"\n },\n \"timeRestore\": {\n \"type\": \"boolean\"\n },\n \"kibanaSavedObjectMeta\": {\n \"type\": \"object\",\n \"properties\": {\n \"searchSourceJSON\": {\n \"type\": \"string\",\n \"description\": \"Serialized JSON string of search source configuration\"\n }\n },\n \"required\": [\"searchSourceJSON\"]\n }\n },\n \"required\": [\"title\", \"panelsJSON\", \"version\", \"kibanaSavedObjectMeta\"]\n },\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"dashboard\"]\n }\n },\n \"required\": [\"attributes\", \"type\"]\n}",
"reason": "The JSON schema defines the required structure for a Kibana configuration file based on the provided example, ensuring correct data types and required fields."
}
curl -X POST "http://localhost:8001/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"desc": "请帮我检查一下这个case和对应的jsonschema是否匹配请检查以下提供的案例及其对应的JSON Schema是否匹配。",
"json_doc": "{ \"attributes\": { \"title\": \"Sample Dashboard\", \"description\": \"This is a sample dashboard.\", \"panelsJSON\": \"[{\\\"panelIndex\\\":\\\"1\\\",\\\"gridData\\\":{\\\"x\\\":0,\\\"y\\\":0,\\\"w\\\":24,\\\"h\\\":15},\\\"type\\\":\\\"visualization\\\",\\\"id\\\":\\\"1\\\"}]\", \"optionsJSON\": \"{\\\"darkTheme\\\":false}\", \"version\": 1, \"timeRestore\": false, \"kibanaSavedObjectMeta\": { \"searchSourceJSON\": \"{\\\"query\\\":{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"lucene\\\"},\\\"filter\\\":[]}\" } }, \"type\": \"dashboard\" }",
"json_schema": "{ \"type\": \"object\", \"properties\": { \"attributes\": { \"type\": \"object\", \"properties\": { \"title\": { \"type\": \"string\" }, \"description\": { \"type\": \"string\" }, \"panelsJSON\": { \"type\": \"string\" }, \"optionsJSON\": { \"type\": \"string\" }, \"version\": { \"type\": \"integer\" }, \"timeRestore\": { \"type\": \"boolean\" }, \"kibanaSavedObjectMeta\": { \"type\": \"object\", \"properties\": { \"searchSourceJSON\": { \"type\": \"string\" } }, \"required\": [\"searchSourceJSON\"] } }, \"required\": [\"title\", \"description\", \"panelsJSON\", \"optionsJSON\", \"version\", \"timeRestore\", \"kibanaSavedObjectMeta\"] }, \"type\": { \"type\": \"string\" } }, \"required\": [\"attributes\", \"type\"] }",
"type": "val"
}'
当检验通过
{"reason": "case is valid"}
当检验不通过
这里的
json
代表尝试更正后的json_doc
,reason
代表对不匹配原因的解释
{
"json": "{\n \"attributes\": { \n \"title\": \"Sample Dashboard\", \n \"description\": \"This is a sample dashboard.\", \n \"panelsJSON\": \"[{\\\"panelIndex\\\":\\\"1\\\",\\\"gridData\\\":{\\\"x\\\":0,\\\"y\\\":0,\\\"w\\\":24,\\\"h\\\":15},\\\"type\\\":\\\"visualization\\\",\\\"id\\\":\\\"1\\\"}]\", \n \"optionsJSON\": \"{\\\"darkTheme\\\":false}\", \n \"version\": 1, \n \"timeRestore\": false, \n \"kibanaSavedObjectMeta\": { \n \"searchSourceJSON\": \"{\\\"query\\\":{\\\"query\\\":\\\"\\\",\\\"language\\\":\\\"lucene\\\"},\\\"filter\\\":[]}\" \n } \n }, \n \"type\": \"dashboard\" \n}",
"reason": "The JSON case does not match the schema because a key in the 'attributes' object is incorrectly named. In the JSON case, 'tile' is used instead of 'title', which is the required key name as per the JSON schema. To fix this, we need to rename 'tile' to 'title', ensuring that all required keys in the schema are present and correctly named. After this correction, all keys in the JSON case will align with those specified in the JSON schema."
}
当提供的JsonSchema格式不正确
{"reason": "failed to compile json schema, please check the json schema you provided"}
Note
需要数据面的proxy wasm版本大于等于0.2.100
编译时,需要带上版本的tag,例如:tinygo build -o main.wasm -scheduler=none -target=wasi -gc=custom -tags="custommalloc nottinygc_finalizer proxy_wasm_version_0_2_100" ./
需要配合 ai-proxy 插件使用
LLM响应结构化插件,用于根据默认或用户配置的Json Schema对AI的响应进行结构化,以便后续插件处理。注意目前只支持 非流式响应
。
Name | Type | Requirement | Default | Description |
---|---|---|---|---|
serviceName | str | required | - | 网关服务名称 |
serviceDomain | str | required | - | 网关服务域名/IP地址 |
servicePort | int | required | - | 网关服务端口 |
serviceTimeout | int | optional | 50000 | 默认请求超时时间 |
maxRetry | int | optional | 3 | 若回答无法正确提取格式化时重试次数 |
contentPath | str | optional | "choices.0.message.content” | 从LLM回答中提取响应结果的gpath路径 |
jsonSchema | str (json) | optional | APITemp, details in the “./templates.go” | 验证请求所参照的jsonSchema |
enableSwagger | bool | optional | false | 是否启用Swagger协议进行验证 |
enableOas3 | bool | optional | true | 是否启用Oas3协议进行验证 |
Json格式响应
或 空字符串
curl -X POST "http://localhost:8001/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4",
"messages": [
{"role": "user", "content": "give me a api doc for add the variable x to x+5"}
]
}'
返回Json为
{
"apiVersion": "1.0",
"request": {
"endpoint": "/add_to_five",
"method": "POST",
"port": 8080,
"headers": {
"Content-Type": "application/json"
},
"body": {
"x": 7
}
}
}
1. 背景
目前,LLM 的响应往往是非正式且非结构化的。这使得在需要基于 LLM 响应进行开发时,通常需要使用复杂的工具如 LangChain 等思维链操作,以确保输出符合预期。例如,在根据用户提问生成代码的场景中,开发者常常需要手动分离 LLM 的文本回复和生成的代码。这不仅增加了开发的复杂性,还难以确保最终效果的稳定性。 为了简化这一流程,OpenAI 最近基于 “gpt-4o-2024-08-06” 模型推出了 JSON 结构化输出接口(Structured Outputs - OpenAI API)。通过定义 JSON Schema 来严格约束 LLM 的响应格式,开发者可以确保输出更加规范和可控,大大降低了开发的难度。 一个简单的Case如下:
首先定义需要响应的JSON Schema:
其次,问题为:帮我解方程:8x + 7 = -23 最后的回答为:
这样不仅使得对回答要求的格式更为明确,并且回复的结果能可以简单的作为后续程序处理的输入。
2. 需求
2.1 在 AI-Proxy 的代码基础上增加对 JSON Schema 接口的支持
AI-Proxy 已经支持了众多 LLM 的接口,在其上增加支持 JSON Sechma 的接口可以让现有使用其的用户或依赖 AI-Proxy 开发的组件方便的扩展对 JSON Sechma 接口的支持。
2.2 格式化文档/代码生成
由于 JSON Sechma 的编写和维护并不适合所有基础的用户,单独维护一个格式化文档/代码生成的插件也有一定的价值。
如针对低代码需求的用户,可以维护用于网页 UI 代码生成的 JSON Schema,用户可以一键得到能运行的网页 UI 代码:
针对需求生成特定格式文档(如 json)的用户,可以直接代理用户请求后返回特定格式的文档(可以加上content-disposition 响应头,方便用户下载)
3.下一步计划进度
已初步完成 2.1 的开发,2.2 的思路待讨论完善后看看是在现有插件基础上开发还是开发独立插件方便应用扩展。