Chatgpt 角色 AI 开发 so easy:我用几行代码实现了 prompt 和云端化 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
C900612
V2EX    OpenAI

Chatgpt 角色 AI 开发 so easy:我用几行代码实现了 prompt 和云端化

  •  
  •   C900612 2023-07-27 11:00:37 +08:00 1238 次点击
    这是一个创建于 814 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近本人花了不到一天的时间,开发了一个简单的 AI 角色 Android 小软件,可以实现 AI 角色的云端化,可以指定大量的 AI 角色和对应 prompt 。闲话少说,先直接上图,再简单分解开发过程。如果你对文章没兴趣,可以跳过下面的内容,直接获取源码。/p>

    https://github.com/bmob/Bmob-Android-AI-Prompt

    一、数据表的设计

    角色表

    登录 Bmob 后端云账号,创建应用之后,创建角色表( Character ):

    聊天内容表

    聊天内容表( Message ):

    二、java bean 设计

    创建和数据表对应的 Character 、Message 和 User 的 java bean 。

    角色类

    Character 类的代码如下:

    public class Character extends BmobObject { /** * 这个 AI 助手有多少人在用 */ String userNum; /** * AI 助手的名称 */ String title; /** * 角色的英文名 */ String name; /** * AI 助手的图片 */ String img; /** * AI 助手的 prompt */ String prompt; /** * AI 助手的描述信息 */ String description; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getImg() { return img; } public void setImg(String img) { this.img = img; } public String getPrompt() { return prompt; } public void setPrompt(String prompt) { this.prompt = prompt; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getUserNum() { return userNum; } public void setUserNum(String userNum) { this.userNum = userNum; } } 

    消息类

    Message 类的代码如下:

     /** * 聊天内容类 */ public class Message extends BmobObject { public static String SEND_BY_ME="me"; public static String SEND_BY_BOT="bot"; /** * 会话 */ String session; /** * 内容的归属权 */ String username; /** * 发送的内容 */ String message; /** * 发送者( me 和 bot 两种类型) */ String sendBy; /** * 获取用户的名字 * @return */ public String getUsername() { return username; } /** * 设置用户的名字 * @param username */ public void setUsername(String username) { this.username = username; } /** * 获取会话信息 * @return */ public String getSession() { return session; } /** * 设置会话信息 * @param session */ public void setSession(String session) { this.session = session; } /** * 获取聊天内容 * @return */ public String getMessage() { return message; } /** * 设置聊天内容 * @param message */ public void setMessage(String message) { this.message = message; } /** * 获取发送者 * @return */ public String getSendBy() { return sendBy; } /** * 设置发送者 * @param sendBy */ public void setSendBy(String sendBy) { this.sendBy = sendBy; } /** * 聊天内容的构造函数 * @param message 聊天内容 * @param sendBy 发送者 */ public Message(String message, String sendBy,String session,String username) { this.message = message; this.sendBy = sendBy; this.session = session; this.username = username; } } 

    用户类

    User 类的代码如下:

     public class User extends BmobUser { } 

    三、初始化 Bmob 和 AI

    创建 BmobApp 类,继承自 Application 类,代码如下:

    public class BmobApp extends Application { public static BmobAI bmobAI; @Override public void onCreate() { super.onCreate(); //初始化 Bmob 后端云 Bmob.initialize(this,"这个替换为你自己的 application id"); //初始化 AI bmobAI = new BmobAI(); } } 

    四、登录页面核心代码

    登录页面直接调用了 BmobSMS 类的发送方法( requestSMSCode )和 BmobUser 类的短信验证码自动注册登录方法( signOrLoginByMobilePhone )。

     public void onClick(View v) { if(v==getCodeBt){ if(!radioButton.isChecked()){ Toast.makeText(v.getContext(),"请同意以上服务条款",Toast.LENGTH_SHORT).show(); return; } //获取验证码 String phOne= phoneEdit.getText().toString().trim(); //这里不检查 phone 的更多合规性问题,自行补上 if(phone.length()!=11){ Toast.makeText(v.getContext(),"请输入正确的手机号码",Toast.LENGTH_SHORT).show(); return; } //发送验证码 BmobSMS.requestSMSCode(phone, "", new QueryListener<Integer>() { @Override public void done(Integer integer, BmobException e) { if(e==null){ //获取到验证码 Toast.makeText(v.getContext(),"验证码发送成功",Toast.LENGTH_SHORT).show(); } } }); }else if(v==submitBt){ //注册登录 String phOne= phoneEdit.getText().toString().trim(); String code = codeEdit.getText().toString().trim(); if(code.isEmpty() || code.length()!=6){ Toast.makeText(v.getContext(),"请输入验证码",Toast.LENGTH_SHORT).show(); return; } //执行登录操作 BmobUser.signOrLoginByMobilePhone(phone, code, new LogInListener<BmobUser>() { @Override public void done(BmobUser o, BmobException e) { if(e==null){ startActivity(new Intent(LoginActivity.this,MainActivity.class)); } else{ Toast.makeText(v.getContext(),"短信验证失败",Toast.LENGTH_SHORT).show(); } } }); } } 

    五、角色列表页面核心代码

    角色列表页面主要是从 Bmob 后端云上面获取角色列表,呈现在 RecycleView 上面。代码如下:

     //从 Bmob 上面获取 AI 角色信息 BmobQuery<Character> query = new BmobQuery<>(); query.findObjects(new FindListener<Character>() { @Override public void done(List<Character> characterList, BmobException e) { CharacterAdapter characterAdapter = new CharacterAdapter(characterList,getContext()); prompt_recycle_view.setAdapter(characterAdapter); LinearLayoutManager llm = new LinearLayoutManager(getActivity()); llm.setStackFromEnd(true); prompt_recycle_view.setLayoutManager(llm); } }); 

    六、聊天对话页面核心代码

    获取历史聊天记录的代码如下:

     BmobQuery<Message> query = new BmobQuery<>(); query.addWhereEqualTo("username",username); query.addWhereEqualTo("session",session); query.findObjects(new FindListener<Message>() { @Override public void done(List<Message> list, BmobException e) { if(e==null && list!=null){ messageList.addAll(list); } chatAdapter = new ChatAdapter(messageList,logo); recyclerView.setAdapter(chatAdapter); LinearLayoutManager llm = new LinearLayoutManager(getApplicationContext()); llm.setStackFromEnd(true); recyclerView.setLayoutManager(llm); } }); 

    聊天对话的核心代码如下(主要是通过设置 prompt 实现角色):

     //设置 prompt 信息 if(prompt!=null && !prompt.isEmpty()) BmobApp.bmobAI.setPrompt(prompt); //点击发送提问到 AI 服务器的按钮 sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //获取问题 String quesion = messageEditText.getText().toString().trim(); if(quesion.isEmpty() || quesion.trim()=="") return; //连接 AI 服务器(这个代码为了防止 AI 连接中断) BmobApp.bmobAI.Connect(); //显示问题 addToChat(quesion,Message.SEND_BY_ME); messageEditText.setText(""); //发送内容到 AI 中 BmobApp.bmobAI.Chat(quesion, session, new ChatMessageListener() { @Override public void onMessage(String s) { //消息流的形式返回 AI 的结果 addToLastMessage(s); Log.d("ai",s); } @Override public void onFinish(String s) { //一次性返回全部结果,这个方法需要等待一段时间,友好性较差 //addToChat(s,Message.SEND_BY_BOT); Message newmessage = new Message(s,Message.SEND_BY_BOT,session,username); newmessage.save(new SaveListener<String>() { @Override public void done(String s, BmobException e) { } }); sendButton.setEnabled(true); } @Override public void onError(String s) { //OpenAI 的密钥错误或者超过 OpenAI 并发时,会返回这个错误 Log.d("ai",s); sendButton.setEnabled(true); } @Override public void onClose() { //连接关闭了 Log.d("ai","close"); sendButton.setEnabled(true); } }); } }); 
    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2451 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 02:01 PVG 10:01 LAX 19:01 JFK 22:01
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86