前言
原本是想实现调用ChatGPT接口,但是能力有限,没办法搞到ChatGPT的apiKey。于是就想着实现文心一言(来自于百度的千帆大模型)的接口。如果是需要实现对话的功能,调用该接口是需要付费的。具体付费规则如下
刚注册的账号存在一个20元的代金卷,可以使用代金券练手。
如果没有代金券而且不想开通就想测试调用接口的功能的话,存在一个免费试用的接口。Prompt模板。
接下来我分别实现就实现一下调用Prompt模板的功能与调用对话接口的功能。
获取AccessToken
无论是实现调用免费的接口还是付费接口,都要先获取AccessToken,目的是鉴权。
查看对应文档获取access_token – 千帆大模型平台 | 百度智能云文档 (baidu.com)
根据文档我们知道我们向接口发起一个POST请求。一个请求头以及三个Query参数。
我们可以根据在线调试平台获取到部分Java代码。我们参考它的文档去写。
首先我们在pom文件中导入了如下jar包
com.squareup.okhttp3okhttp4.8.1com.alibabafastjson2.0.19org.slf4jslf4j-log4j121.7.36org.projectlomboklombok1.18.8
编写测试获取AccessToken的方法
@Slf4jpublic class Chat {private final String ACCESS_TOKEN_URI = "https://aip.baidubce.com/oauth/2.0/token";private String apiKey = "yourApikey";private String secretKey = "yourSecetkey";private String accessToken;private OkHttpClient client = new OkHttpClient();public boolean getAccessToken(){MediaType mediaType = MediaType.parse("application/json");RequestBody body = RequestBody.create(mediaType, "");//创建一个请求Request request = new Request.Builder().url(ACCESS_TOKEN_URI+"" />
我们将调用的获取AccessToken接口获取到的信息转为JSON格式后,获取access_token属性值,复制给类属性。
测试
public class Main {public static void main(String[] args) throws InterruptedException {Chat chat = new Chat();boolean result = chat.getAccessToken();System.out.println(result);}}
运行结果为:
19:46:13,387 DEBUG Chat:48 - 获取accessToken成功
true
实现Prompt模板接口调用
查看对应文档Prompt模板 - 千帆大模型平台 | 百度智能云文档 (baidu.com)。
要想调用该接口,我们需要事先创建好Promet模板。创建模板过程如下
创建好模板后,我们后续需要调用模板ID。
具体实现代码如下
/** * 调用Prompt接口 * @param param */public void getPrompt(int id,String param){Request request = new Request.Builder()//https://aip.baidubce.com/rest/2.0/wenxinworkshop/api/v1/template/info" />
测试
public class Main {public static void main(String[] args) throws InterruptedException {Chat chat = new Chat();boolean result = chat.getAccessToken();if (result){chat.getPrompt(7964,"zmbwcx");}}}
运行结果为
19:48:04,906 DEBUG Chat:48 - 获取accessToken成功
19:48:05,144 DEBUG Chat:99 - {"result":{"templateName":"测试接口调用","templateContent":"文章内容:{name}测试接口调用成功","templateId":7964,"content":"文章内容:zmbwcx测试接口调用成功","templateVariables":"name"},"log_id":"0hkyy9izb4azvsgp","success":true,"status":200}
19:48:05,145 DEBUG Chat:101 - {"templateName":"测试接口调用","templateContent":"文章内容:{name}测试接口调用成功","templateId":7964,"content":"文章内容:zmbwcx测试接口调用成功","templateVariables":"name"}
实现对话接口调用
同样是观察文档,不过实现对话接口调用比实现调用Prompt接口稍微复杂一些。需要创建一些类来设置我们的参数。
创建请求参数类
@Datapublic class RequestMessage {/** * 聊天上下文 */List messages = new ArrayList();/** * 范围(0~1.0] * 较高的数值会使输出更加随机 */float temperature = Float.parseFloat("0.95");/** * 影响文本的多样性,取值越大生成的文本多样性越强 * 建议该参数与temperature只设置一个。建议top_p和temperature不要同时更改 */float top_p = Float.parseFloat("0.8");/** * 通过对已生成的token增加惩罚,减少重复生成的现象 * 值越大,惩罚越大 * 取值范围[1,2] */float penalty_score = Float.parseFloat("1.0");/** * 是否以流式接口形式返回数据 */boolean stream = false;/** * 模型人设 */String system = null;/** * 表示用户唯一标识符,用于监测和检测滥用行为。防止接口恶意调用。 */String user_id = "";public void addMessage(Message message){this.messages.add(message);}}
创建Message类
@Datapublic class Message {/** * 用户角色 * 目前支持: * user 用户 * assistant 对话助手 */String role;/** * 对话内容。 */String content;public Message(String role, String content) {this.role = role;this.content = content;}}
设置接收响应信息类
@Datapublic class ResponseMessage {//本轮对话idString id;//回包类型。 chat.completion:多轮对话返回String object;//时间戳int created;//表示当前子句的序号。只有在流式接口模式下才会返回该字段int sentence_id;//表示当前子句是否是最后一句。只有在流式接口模式下会返回该字段。boolean is_end;//对话返回结果。String result;/** * 表示用户输入是否存在安全,是否关闭当前会话,清理历史回话信息。 * true:是,表示用户输入存在安全风险,建议关闭当前会话,清理历史会话信息。 * false:否,表示用户输入无安全风险。 */boolean need_clear_history;//token统计信息,token数 = 汉字数+单词数*1.3 (仅为估算逻辑)。Usage usage;}
设置Usage类
public class Usage {//问题token数int prompt_tokens;//回答token数int completion_tokens;//token总数int total_tokens;}
如果看文档不太清楚的话,我们可以通过在线调试平台观察一下请求所需要的必须参数与响应过来的参数结构。
接下来我们编写Chat类
@Slf4jpublic class Chat {private final String ACCESS_TOKEN_URI = "https://aip.baidubce.com/oauth/2.0/token";private final String CHAT_URI = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant";private String apiKey = "yourApikey";private String secretKey = "yourSecretkey";private String accessToken = "";private OkHttpClient client ;//请求参数private RequestMessage requestBody = new RequestMessage();//响应超时时间private int responseTimeOut = 5000;public Chat(){this.client = new OkHttpClient.Builder().readTimeout(responseTimeOut,TimeUnit.SECONDS).build();}public Chat(int responseTimeOut){this.client = new OkHttpClient.Builder().readTimeout(responseTimeOut,TimeUnit.SECONDS).build();} public boolean getAccessToken(){MediaType mediaType = MediaType.parse("application/json");RequestBody body = RequestBody.create(mediaType, "");//创建一个请求Request request = new Request.Builder().url(ACCESS_TOKEN_URI+"" />
测试
public class Main {public static void main(String[] args) throws InterruptedException {Chat chat = new Chat();boolean result = chat.getAccessToken();if (result){Scanner scanner = new Scanner(System.in);String question = scanner.nextLine();while(!"q".equals(question)){chat.getAnswer(question);chat.getRequestBody();question = scanner.nextLine();}}}}
运行测试
将返回的结果与requestBody转为JSON格式观察
格式转化正确。测试是否可以上下文联系
将最后一行格式转化观察
发现可以正常响应。至此,我们实现了调用千帆大模型的对话接口调用。