XSwitch CherryGPT 接口(草稿)
CherryGPT 是一个聊天机器人接口和应用程序,一端连接 XSwitch 及 PSTN/VoIP 平台,一端连接 ChatGPT,可以实现电话与 ChatGPT 语音聊天。
ChatGPT 是聊天机器人的巅峰,XSwitch 也很快开发了与 ChatGPT 的接口,用户只需要填入自己的 ChatGPT Token 就可以与 ChatGPT 轻松对接。
另外,为了支持更多聊天机器人开发,CherryGPT 也扩展了 ChatGPT 协议,可以与很多不同的 GPT 类聊天机器人连接,实现丰富的对话场景。AI 开发者也可以参考该协议实现自己的聊天机器人。
综述
CherryGPT 通过XCC协议连接 ChatGPT。架构图如下:
交互流程时序图如下:
CherryGPT 可以支持如下功能:
- 与 ChatGPT 对接,来电直接与 ChatGPT 对话。
- 对接 ASR/TTS 平台(阿里、讯飞、百度、思必驰、MRCP 等)做语音识别和语音合成。
- 对接其他类似 ChatGPT 协议的机器人。
- 对 ChatGPT 协议扩展,支持更多的对话功能。
ChatGPT 协议简介
CherryGPT 主要使用 ChatGPT 的 chat completions 协议,参考:https://platform.openai.com/docs/api-reference/chat 。
ChatGPT 协议有两种方式,一种是普通的 HTTP 请求响应协议,另一种是 Server-sent events(SSE)协议,分别对应stream参数的false和true。
ChatGPT 有三种 role(角色),分别是system、assistant、user。
role
system:系统角色,用于系统设定,如给 AI 系统一个人设:“你是一个 AI 客服助理,你的名字叫小樱桃”。assistant:助理角色,指聊天机器人(ChatGPT)生成的信息。user:用户产生的信息,如用户说的话。
ChatGPT 本身是无状态的,也就是说 ChatGPT 本身没有对话上下文的概念,所有的上下文信息都在客户端侧(此处是 CherryGPT)维护。在每次请求时携带相应的上下文信息。如:
第一次请求:
"messages": [ {"role": "system", "content": "你是一个AI客服助理,你的名字叫小樱桃"}, {"role": "user", "content": "你好,今天天气怎么样?"} ]
ChatGPT 返回结果:
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "今天天气晴,适合写代码。你想问点什么呢?", }, "finish_reason": "stop" }]
后续请求:
messages: [ {"role": "system", "content": "你是一个AI客服助理,你的名字叫小樱桃"}, {"role": "user", "你好,今天天气怎么样?"}, {"role": "assistant", "今天天气晴,适合写代码。你想问点什么呢?"}, {"role": "user", "帮我写个快速排序程序"} ]
这样,ChatGPT 就可以根据上下文信息生成更加合理的回复。
普通 HTTP
比较简单的用法是使用普通的 HTTP 协议。在连接真实 ChatGPT 服务时延迟比较大(因为 ChatGPT 生成结果比较慢),但如果你基于该协议构建自己的聊天机器人时,可以考虑使用这种模式。
curl 示例:
curl https://api.openai.com/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -d '{ "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "Hello!"}] }'
参数:
{ "model": "gpt-3.5-turbo", "messages": [{ "role": "user", "content": "Hello!" }] }
返回值:
{ "id": "chatcmpl-123", "object": "chat.completion", "created": 1677652288, "choices": [ { "index": 0, "message": { "role": "assistant", "content": "\n\nHello there, how may I assist you today?" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 9, "completion_tokens": 12, "total_tokens": 21 } }
SSE
ChatGPT 使用 Server-sent events 协议,也就是 SSE 协议,这个协议是基于 HTTP 的,所以可以使用 HTTP 的工具来连接 ChatGPT。
SSE 协议会渐近地返回结果,因而延迟不是很大,完全可以用于实时的对话。
关于 SSE 的文档,可以参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Server-sent_events/Using_server-sent_events 。
注意 Event Stream 在 Nginx 上有个 Bug:https://jvns.ca/blog/2021/01/12/day-36--server-sent-events-are-cool--and-a-fun-bug/ 。
关于 ChatGPT 的协议文本更多可参见:https://github.com/openai/openai-cookbook/blob/main/examples/How_to_stream_completions.ipynb 。
Todo: 在 htts://git.xswitch.cn/xswitch/xcc-examples/sse/ 上有各种语言的服务器的例子。
快速上手
前提条件:
- 下载安装 XSwitch:参见 https://docs.xswitch.cn/installation/
- 安装 NATS,配置 XCC:参见 https://docs.xswitch.cn/howto/xcc/
- 启用一个 ASR/TTS 模块:参见 https://docs.xswitch.cn/howto/asr-tts/
- 安装 CherryGPT:Todo
要连接 ChatGPT,你首先要有一个 Token,将 Token 配置到环境变量里,就可以启动 CherryGPT。
export GPT_TOKEN=..... ./CherryGPT
如果你没有 ChatGPT Token,也可以使用如下方法连接“你自己写的 ChatGPT 服务”,具体协议可以参见上一节的例子。
export GPT_TOKEN=..... export GPT_URL=http://localhost:8080
如果你还没有自己的 ChatGPT 服务,在 htts://git.xswitch.cn/xswitch/xcc-examples/sse/ 上有各种语言的例子,可以下载测试使用。
以下是一个在线的 ChatGPT 服务器,可以直接使用:
export GPT_TOKEN=demo export GPT_URL=https://demo.xswitch.cn/api/hello/cn/chat/completions ./CherryGPT
你也可以使用curl命令测试:
export GPT_TOKEN=demo export GPT_URL=https://demo.xswitch.cn/api/hello/cn/chat/completions curl $GPT_URL \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $GPT_TOKEN" \ -d '{ "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "Hello!"}] }'
或:
export GPT_TOKEN=demo export GPT_URL=https://demo.xswitch.cn/api/hello/cn/completions curl $GPT_URL \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $GPT_TOKEN" \ -d '{ "streaming": true, "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "Hello!"}] }'
环境变量
GPT_TOKEN:ChatGPT Token,如果没有 Token,可以使用CHATGPT_URL连接自己的 ChatGPT 服务。GPT_URL:可以指向自己服务器的 URL。DB_URL:可以将聊天记录写入自己的数据库。GPT_PUT_CHANVAR_IN_SYSTEM_ROLE:是否将通道变量放入systemrole 中,默认为false。GPT_STREAMING:是否启用流式请求,默认为false(普通 HTTP),改为true可以支持 SSE。GPT_TTS_ENGINE:TTS 引擎名称,如ali、baidu、huawei、xunfei等,默认为ali。GPT_TTS_VOICE:TTS 声音名称,如aixia、xiaoyun等,默认为default。GPT_ASR_ENGINE:ASR 引擎名称,默认为ali。
CherryGPT 扩展
CherryGPT 对 ChatGPT 协议做了一些扩展,以便支持更多的场景。
扩展的原则是尽量使用 ChatGPT 原有的字段和字段类型。如果需要增加新的字段类型,也需要小心评估。
system role
CherryGPT 会在 system role 中增加当前通话的信息,如:
{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "channel_uuid=12345678-1234-1234-1234-123456789012" }, { "role": "system", "content": "caller_id_name=小樱桃" }, { "role": "system", "content": "caller_id_number=1234" }, { "role": "system", "content": "dest_number=1234" }, { "role": "user", "content": "Hello!" } ] }
启用该功能需要启用以下环境变量:
GPT_PUT_CHANNEL_VAR_IN_SYSTEM_ROLE=true
常用的通道变量如下:
channel_uuid:通道 ID,本次通话的唯一标识caller_id_name:主叫名称caller_id_number:主叫号码dest_number:被叫号码language:语言,可以为auto、zh-CN、zh-TW等
system role 也支持 URLEncode 格式,如:
channel_uuid=1234&caller_id_name=小樱桃&caller_id_number=1234&dest_number=5678
启用该功能需要启用以下环境变量:
GPT_PUT_CHANNEL_VAR_IN_SYSTEM_ROLE=true GPT_PUT_CHANNEL_VAR_IN_SYSTEM_ROLE_URLENCODE=true
params role
为了语义更明确,也可以增加params role,用于传递参数。跟上面的system role 含义相同,如:
{ "role": "params", "content": "channel_uuid=1234&caller_id_name=小樱桃&caller_id_number=1234&dest_number=5678" }
一次请求中可以有多个params role。
启动该功能需要启用如下环境变量:
GPT_PUT_CHANNEL_VAR_IN_PARAMS_ROLE=true GPT_PUT_CHANNEL_VAR_IN_PARAMS_ROLE_URLENCODE=true
cookie role
增加一个cookie的 role,该 role 的所有内容会原样返回,类似浏览器的 cookie,用于保存会话信息。
服务端在返回结果集中返回名为cookie的 role:
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "\n\nHello there, how may I assist you today?", }, "finish_reason": "stop" }, { "index": 1, "message": { "role": "cookie", "content": "any string will be echoed back", } }, { "index": 2, "message": { "role": "cookie", "content": "another string a=1, b=2", } }, { "index": 3, "message": { "role": "cookie", "content": "{\"a\":1, \"b\":2, \"c\": \"string\"}", } }]
下一次请求时 CherryGPT 将会包含:
{ "model": "gpt-3.5-turbo", "messages": [ {"role": "cookie", "content": "any string will be echoed back"}, {"role": "cookie", "content": "another string a=1, b=2"}, {"role": "cookie", "content": "{\"a\":1, \"b\":2, \"c\": \"string\"}"}, {"role": "user", "content": "Hello!"}, ] }
扩展字段
可以在请求和回复中增加扩展字段。目前的设计是增加一个extra对象。需要使用如下环境变量启用。
GPT_PUT_CHANNEL_VAR_IN_EXTRA_OBJECT=true
具体字段中的含义跟上述system和params role 中一样。
function_call
服务端可以可以返回function_call,用于指示 CherryGPT 执行一个功能。如:
{ "message": "电话转接中,请稍候...", "content": null, "function_call": { "name": "transfer", "arguments": { "number": "1001" } } }
其中,arguments为函数的参数,可以是一个 JSON 字符串,或者是一个 JSON 对象。具体的函数列表及参数可以参考下面的定义。
function_call 函数列表
目前系统支持的function_call列表如下,更多函数功能可以根据需求继续补充。
transfer
转接。
参数:
number:被转接的号码。具体转接规则需要在服务器端配置。
hangup
挂断。
play
url:音频文件的 URL。
record
录音。
对通话进行录音。录音文件路径可以通过其他 API 查询(如media_files REST API)。
更多示例
- CherryGPT 简易版:用 350 行 Go 代码写一个 ChatGPT 聊天机器人:https://github.com/rts-cn/chatgpt 。
- CherryGPT 源代码:CherryGPT 使用 Go 语言开发,是上述简易代码的升级版。如果你想扩展更多功能,可以联系我们购买 CherryGPT 源代码并自行扩展。
XSwitch 功能非常强大,如果你有更多的扩展需要,推荐使用更底层的 API,如:
- CherryGPT 底层使用的 XCC API:https://docs.xswitch.cn/xcc-api/
- 基于 HTTP 的 API - AIAPI:https://docs.xswitch.cn/ai-api/
- 更多 API:https://docs.xswitch.cn/dev-guide/api/