TypeChat、JSONSchemaChat实战 - 让ChatGPT更听你的话

TypeChat 用一句话概括,就是用了它你可以让大语言模型(比如 ChatGPT)将自然语言转换成特定类型的 JSON 数据。

我们在使用 ChatGPT 的时候,大致流程如下:

假如我们需要 ChatGPT 按照我们输入的 prompt,输出指定格式的 JSON 数据,我们在 prompt 里将我们的要求描述清楚就行,比如

好像没什么问题,很听话。

我们再看一个例子

js 复制代码
{
    "filters": [
        {
            "component": "select",
            "key": "店铺名称",
            "label": "店铺名称",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "key": "店铺编码",
            "label": "店铺编码",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "key": "店铺门头编码",
            "label": "店铺门头编码",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "key": "所在区域",
            "label": "所在区域",
            "placeholder": "全部"
        }
    ],
    "columns": [
        {
            "slot": false,
            "title": "店铺编码",
            "dataIndex": "店铺编码",
            "key": "店铺编码"
        },
        {
            "slot": false,
            "title": "店铺名称",
            "dataIndex": "店铺名称",
            "key": "店铺名称"
        },
        {
            "slot": false,
            "title": "店铺业务范围",
            "dataIndex": "店铺业务范围",
            "key": "店铺业务范围"
        },
        {
            "slot": false,
            "title": "店铺类型",
            "dataIndex": "店铺类型",
            "key": "店铺类型"
        },
        {
            "slot": false,
            "title": "所在区域",
            "dataIndex": "所在区域",
            "key": "所在区域"
        },
        {
            "slot": false,
            "title": "详细地址",
            "dataIndex": "详细地址",
            "key": "详细地址"
        }
    ],
    "pagination": {
        "show": true,
        "page": "page",
        "size": "size",
        "total": "result.total"
    },
    "includeModifyModal": false,
    "fetchName": "fetchTableList",
    "result": "[\"result\"][\"records\"]",
    "serviceName": "getTableList"
}

我们需要 ChatGPT 把上面 JSON 数据中 filters 字段中的 key 字段的值翻译为英文,使用驼峰语法。columns 字段中的 key、dataIndex 字段的值翻译为英文,使用驼峰语法。

我们的 prompt 可以这么写:

js 复制代码
{
    "filters": [
        {
            "component": "select",
            "key": "店铺名称",
            "label": "店铺名称",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "key": "店铺编码",
            "label": "店铺编码",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "key": "店铺门头编码",
            "label": "店铺门头编码",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "key": "所在区域",
            "label": "所在区域",
            "placeholder": "全部"
        }
    ],
    "columns": [
        {
            "slot": false,
            "title": "店铺编码",
            "dataIndex": "店铺编码",
            "key": "店铺编码"
        },
        {
            "slot": false,
            "title": "店铺名称",
            "dataIndex": "店铺名称",
            "key": "店铺名称"
        },
        {
            "slot": false,
            "title": "店铺业务范围",
            "dataIndex": "店铺业务范围",
            "key": "店铺业务范围"
        },
        {
            "slot": false,
            "title": "店铺类型",
            "dataIndex": "店铺类型",
            "key": "店铺类型"
        },
        {
            "slot": false,
            "title": "所在区域",
            "dataIndex": "所在区域",
            "key": "所在区域"
        },
        {
            "slot": false,
            "title": "详细地址",
            "dataIndex": "详细地址",
            "key": "详细地址"
        }
    ],
    "pagination": {
        "show": true,
        "page": "page",
        "size": "size",
        "total": "result.total"
    },
    "includeModifyModal": false,
    "fetchName": "fetchTableList",
    "result": "[\"result\"][\"records\"]",
    "serviceName": "getTableList"
}
将这段 json 中,filters 字段中的 key 字段的值翻译为英文,使用驼峰语法,label、placeholder 字段的值保留中文。
columns 字段中的 key、dataIndex 字段的值翻译为英文,使用驼峰语法,title 字段的值保留中文。 
返回翻译后的 markdown 语法的代码块

最后面的那段话已经经过了几次修改,我们看下 ChatGPT 返回的内容:

js 复制代码
{
    "filters": [
        {
            "component": "select",
            "storeName": "店铺名称",
            "label": "店铺名称",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "storeCode": "店铺编码",
            "label": "店铺编码",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "storeDoorCode": "店铺门头编码",
            "label": "店铺门头编码",
            "placeholder": "请输入"
        },
        {
            "component": "select",
            "area": "所在区域",
            "label": "所在区域",
            "placeholder": "全部"
        }
    ],
    "columns": [
        {
            "slot": false,
            "title": "店铺编码",
            "storeCode": "店铺编码",
            "key": "storeCode"
        },
        {
            "slot": false,
            "title": "店铺名称",
            "storeName": "店铺名称",
            "key": "storeName"
        },
        {
            "slot": false,
            "title": "店铺业务范围",
            "storeBusinessScope": "店铺业务范围",
            "key": "storeBusinessScope"
        },
        {
            "slot": false,
            "title": "店铺类型",
            "storeType": "店铺类型",
            "key": "storeType"
        },
        {
            "slot": false,
            "title": "所在区域",
            "area": "所在区域",
            "key": "area"
        },
        {
            "slot": false,
            "title": "详细地址",
            "detailedAddress": "详细地址",
            "key": "detailedAddress"
        }
    ],
    "pagination": {
        "show": true,
        "page": "page",
        "size": "size",
        "total": "result.total"
    },
    "includeModifyModal": false,
    "fetchName": "fetchTableList",
    "result": "[\"result\"][\"records\"]",
    "serviceName": "getTableList"
}

filters 里的 key 字段哪去了?columns 里 dataIndex 字段哪去了?

这只是我遇到的各种情况里的一种,当然也有成功的,反正就是很玄学,可能是我半年 prompt 练习生的水平不够吧。

如果我们用 TypeChat 会怎么样呢?

直接看效果 :

完美。

TypeChat 的大致原理如下:

其实就是在 prompt 拼上了一个 TS 类型,要求 ChatGPT 按照 TS 类型声明输出 JSON。背后还会构建一个 TS 程序去进行校验,如果校验失败就把错误信息也加到 prompt 里,让 ChatGPT 再处理一次。

上面生成的 prompt 跟 TypeChat 生成的有些区别,我并没有直接使用 TypeChat,为了方便在我的项目里使用就抄了一份进行修改,在生成 prompt 的里加上了 "按照字段的注释进行处理" 这一要求。修改后的代码: github.com/lowcode-sca...

在 TS 类型的字段注释里还可以加入更离谱的东西来要求 ChatGPT 去处理,比如之前弄的一个根据聊天记录生成日程安排的小 demo,在字段注释里加上当前时间,让 ChatGPT 根据会话内容推算出具体的日期。TS 类型定义如下:

js 复制代码
const res = await translate({
    schema: `export type SchedulType = {
              /**
               * 时间,格式:YYYY-MM-DD HH:mm:ss,当前时间为 ${new Date().toLocaleString()},请推算出正确的时间
               */
              time: string;
              /**
               * 活动主题
               */
              todo: string;
              /**
               * 地点
               */
              addr: string;
              /**
               * 活动的全体参与人
               */
              participant: string[];
            };`,
    typeName: 'SchedulType',
    request: `根据下面的聊天记录,生成日程安排:${message.data}`,
    createChatCompletion: createChatCompletionForScript,
    showWebview: true,
  });

聊天记录中只说到了周六下午两点,ChatGPT 根据字段注释里的当前时间正确推算出了日程的具体日期。

受到 TypeChat 的启发,借助 JSON Schema 实现了一个 JSONSchemaChat,原理差不多,效果如下:

相关推荐
TimelessHaze19 分钟前
拆解字节面试题:async/await 到底是什么?底层实现 + 最佳实践全解析
前端·javascript·trae
执键行天涯1 小时前
从双重检查锁定的设计意图、锁的作用、第一次检查提升性能的原理三个角度,详细拆解单例模式的逻辑
java·前端·github
青青子衿越1 小时前
微信小程序web-view嵌套H5,小程序与H5通信
前端·微信小程序·小程序
OpenTiny社区1 小时前
TinyEngine 2.8版本正式发布:AI能力、区块管理、Docker部署一键强化,迈向智能时代!
前端·vue.js·低代码
qfZYG1 小时前
Trae 编辑器在 Python 环境缺少 Pylance,怎么解决
前端·vue.js·编辑器
bug爱好者1 小时前
Vue3 基于Element Plus 的el-input,封装一个数字输入框组件
前端·javascript
Silence_xl1 小时前
RACSignal实现原理
前端
柯南二号1 小时前
【大前端】实现一个前端埋点SDK,并封装成NPM包
前端·arcgis·npm
dangkei1 小时前
【Wrangler(Cloudflare 的官方 CLI)和 npm/npx 的区别一次讲清】
前端·jvm·npm
乔公子搬砖1 小时前
小程序开发提效:npm支持、Vant Weapp组件库与API Promise化(八)
前端·javascript·微信小程序·js·promise·vagrant·事件绑定