V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
C900612
V2EX  ›  OpenAI

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

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

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

    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   ·   实用小工具   ·   3176 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 13:37 · PVG 21:37 · LAX 05:37 · JFK 08:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.