fastapp-微信开发GPT项目第一课-3. AI助理

时间:2024-09-30 10:30:27

3.1 基于文生文实现AI会话

pip install -U langchain
pip install -U langchain-openai

3.1 服务端调用langchain对接ChatGPT

提供接口,chat/views.py代码:

import os, openai, gradio as gr
from langchain_openai import OpenAI
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationSummaryBufferMemory

# 解决请求超时问题
os.environ["http_proxy"] = "http://localhost:7890"
os.environ["https_proxy"] = "http://localhost:7890"

os.environ["OPENAI_API_KEY"] = "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"
openai.api_key = os.environ["OPENAI_API_KEY"]

memory = ConversationSummaryBufferMemory(
    llm=ChatOpenAI(
        # openai_api_key="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", # 从OpenAI官方申请秘钥[可以是用户秘钥,也可以是项目秘钥]
        # model_name="gpt-3.5-turbo" # 默认是gpt-3.5-turbo
    ),
    max_token_limit=2048
)

conversation = ConversationChain(
    llm=OpenAI(
        # api_key="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",
        max_tokens=2048,
        temperature=0.5),
    memory=memory,
)

"""基于记忆体实现对话的历史上下文管理"""
def chat(input, history=[]):
    history.append(input)
    response = conversation.predict(input=input)
    history.append(response)
    # history[::2] 切片语法,每隔两个元素提取一个元素,即提取出所有的输入,
    # history[1::2]表示从历史记录中每隔2个元素提取一个元素,即提取出所有的输出
    # zip函数把两个列表元素打包为元组的列表的方式
    responses = [(u, b) for u, b in zip(history[::2], history[1::2])]
    print("用户输入:", history[::2])
    print("AI回答:", history[1::2])
    print("上下文:", responses)
    return responses, history


"""可视化界面中实现AI对话"""
with gr.Blocks(css="#chatbot{height:800px} .overflow-y-auto{height:800px}") as demo:
    chatbot = gr.Chatbot(elem_id="chatbot")
    state = gr.State([])

    with gr.Row():
        txt = gr.Textbox(show_label=False, placeholder="请输入你的问题.")

    txt.submit(chat, [txt, state], [chatbot, state])

# 启动项目
demo.launch(share=True)

3.2 客户端请求服务端接口

<template>
  <view class="content">    
    <view class="loginBox">
      <h3 style="text-align: center;margin-bottom:120rpx;">欢迎登录</h3>
      <view class="inputBox">
        <view class="ipt">
          <uni-icons type="contact" size="24" color="rgb(66,157,250)"></uni-icons>
          <input type="text" value="" placeholder="请输入账号"/>
        </view>
        <view class="ipt">
          <uni-icons type="eye" size="24" color="rgb(66,157,250)"></uni-icons>
          <input type="passsword" value="" placeholder="请输入密码"/>
        </view>
        <view class="ipt">
          <uni-icons type="checkmarkempty" size="24" color="rgb(66,157,250)"></uni-icons>
          <input type="text" value="" placeholder="请输入验证码"/>
          <view class="yzm">验证码</view>
        </view>
        <button class="login-btn">登录</button>
      </view>
      <view class="tipbox">
        <view class="txt"> —— 其他账号登录 —— </view>
        <view class="otherUser">
          <button>
              <uni-icons type="qq" size="40" color="rgb(66,157,250)"></uni-icons>
          </button>
          <button open-type="getUserInfo" @getuserinfo="wxLogin">
              <uni-icons type="weixin" size="40" color="rgb(2,187,17)"></uni-icons>
          </button>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>

</script>

<style scoped>
  svg {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height:40%;
    box-sizing: border-box;
    display: block;
    background-color: #ffffff;
  }
  
  .loginBox{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-60%);
    width: 90%;
    border-radius: 20rpx;
    padding: 60rpx;
    box-sizing: border-box;
  }
  h3{
    color:rgb(66,157,250);
    font-size: 40rpx;
    letter-spacing: 10rpx;
    margin-bottom: 40rpx;
  }
  .inputBox{
    
  }
  .ipt{
    height: 86rpx;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    margin-bottom: 40rpx;
    background-color: #f5f5f5;
    border-radius: 10rpx;
    padding-left: 10rpx;
  }
  .ipt input{
    margin-left: 20rpx;
    font-size: 28rpx;
  }
  .ipt input{
    margin-left: 20rpx;
  }
  .forgetPwd{
    margin-top: 30rpx;
    font-size: 26rpx;
    color: #b5b5b5;
    text-align: end;
    padding:0 10rpx;
    display: flex;
    justify-content: space-between;
  }
  .login-btn{
    margin-top: 20rpx;
    line-height: 85rpx;
    text-align: center;
    background: rgb(66,157,250);
    border-radius: 40rpx;
    color: #fff;
    margin-top: 40rpx;
  }
  
  .tip{
    text-align: center;
    font-size: 28rpx;
    position: fixed;
    bottom: 50rpx;
    left: 50%;
    transform: translate(-50%,-50%);
    color: #f4f4f4;
  }
  .tipbox {
    text-align: center;
    margin-top: 100rpx;
  }
  
  .otherUser {
    margin-top: 30rpx;
    display: flex;
    justify-content: center;
  }
  .otherUser button{
      margin: 0 10px;
      padding: 0;
      height: 42px;
      line-height: 42px;
      background: transparent;
      border: 1px solid transparent;
      outline: none;
  }
  .txt {
    font-size: 28rpx;
    color: #cbcbcb;
  }
  
  .otherUser .uni-icons {
    margin-left: 20rpx;
  }
  .yzm{
    text-align: end;
    font-size: 24rpx;
    background: rgb(66,157,250);
    height: 60rpx;
    width: 150rpx;
    line-height: 60rpx;
    text-align: center;
    border-radius: 10rpx;
    color: #fff;
  }
</style>