当前位置:   article > 正文

Python Flask项目方式接入阿里云通义AI大模型API 实现一个简单的AI聊天Web项目(流式传输+多轮对话+会话记录+代码高亮)----- noob学生_阿里ai api

阿里ai api

效果图

数据库记录:

流式输出就不展示了

准备工作

 前往阿里云大模型服务平台使用自己账号开通大模型服务平台百炼 

地址:大模型服务平台_通义大模型_自然语言处理_达摩院-阿里云 (aliyun.com)

1.进入自己的控制台--模型广场--通义千问--找到自己要使用的模型  我这里使用通义千问Max

一般是有免费额度可以使用的   后期可以自己买额度 很便宜 

然后到我的应用   创建好自己的应用  选择相应的模型 这时我们就哟APIkey和 自己的appid了  

2.在自己电脑安装好Redis (用于存储聊天缓存) 如果使用服务器就在服务器安装好并运行就行

3.安装好mysql数据库  推荐使用5.7版本

实施

        创建一个Python Flask项目并创建好虚拟环境解释器使用python3.8  项目结构如下图所示

key.py及其下方文件为我个人测试部署时使用  可以忽略  

app.py

运行项目的文件 也就是后端  

  1. # -*- coding: utf-8 -*-
  2. from flask import Flask, request, jsonify, Response, render_template, session
  3. from flask_session import Session
  4. from dashscope import Generation
  5. from http import HTTPStatus
  6. from flask_cors import CORS
  7. import redis
  8. import json
  9. from database import save_conversation
  10. app = Flask(__name__)
  11. CORS(app)
  12. #可以自己生成一串
  13. app.secret_key = '3ddd8f0da764cb34850e1da48d03da24'
  14. # 配置 Redis
  15. app.config['SESSION_TYPE'] = 'redis'
  16. app.config['SESSION_REDIS'] = redis.Redis(host='localhost', port=6379)
  17. app.config['SESSION_PERMANENT'] = False
  18. app.config['SESSION_USE_SIGNER'] = True
  19. Session(app)
  20. @app.route('/ChatView')
  21. def index():
  22. return render_template('index.html')
  23. @app.route('/chat', methods=['POST'])
  24. def chat():
  25. user_message = request.json.get('message', '')
  26. if not user_message:
  27. return jsonify({'error': '未提供消息'}), HTTPStatus.BAD_REQUEST
  28. # 从会话中加载消息或初始化一个新列表 可以自己自定义角色 修改'你是一个ai助手'内容就行
  29. messages = session.get('messages', [{'role': 'system', 'content': '你是一个ai助手'}])
  30. # 将用户的消息添加到列表中
  31. messages.append({'role': 'user', 'content': user_message})
  32. session['messages'] = messages # 在添加用户消息后立即保存
  33. def generate():
  34. responses = Generation.call(
  35. "qwen-max",
  36. app_id='自己的应用id',
  37. api_key='自己的api key',
  38. messages=messages,
  39. result_format='message',
  40. stream=True,
  41. incremental_output=True
  42. )
  43. buffer = ''
  44. for response in responses:
  45. if response.status_code == HTTPStatus.OK:
  46. content = response.output.choices[0]['message']['content'].strip()
  47. print(content)
  48. buffer += content
  49. yield f"{content}"
  50. else:
  51. yield f"Error: {response.message}\n\n"
  52. break
  53. return Response(generate(), mimetype='text/event-stream')
  54. @app.route('/update', methods=['POST'])
  55. def update():
  56. try:
  57. data = request.json
  58. bot_message = data.get('bot_message', '')
  59. user_message = data.get('user_message', '')
  60. conversation_id = data.get('conversation_id', '')
  61. if not bot_message or not user_message or not conversation_id:
  62. app.logger.error('Missing bot_message, user_message, or conversation_id')
  63. return jsonify({'error': '未提供消息或对话ID'}), HTTPStatus.BAD_REQUEST
  64. messages = session.get('messages', [])
  65. messages.append({'role': 'assistant', 'content': bot_message})
  66. session['messages'] = messages
  67. save_conversation(conversation_id, user_message, bot_message) # 保存对话
  68. return jsonify({'status': 'updated'}), HTTPStatus.OK
  69. except Exception as e:
  70. app.logger.error(f"Error in /update: {str(e)}")
  71. return jsonify({'error': str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
  72. @app.route('/clear', methods=['POST'])
  73. def clear():
  74. session.pop('messages', None)
  75. return jsonify({'status': 'cleared'}), HTTPStatus.OK
  76. if __name__ == '__main__':
  77. app.run(debug=True)
  78. # 这里是自定义本地运行的端口号和ip地址
  79. # app.run(host='0.0.0.0', port=8080, debug=True)

database.py

指向数据库操作 保存记录的后端文件  需要修改为自己的数据库账户和密码  

  1. # -*- coding: utf-8 -*-
  2. import mysql.connector
  3. def get_db_connection():
  4. return mysql.connector.connect(
  5. host="localhost",
  6. user="用户名",
  7. password="密码",
  8. database="数据库名"
  9. )
  10. def save_conversation(conversation_id, user_message, bot_message):
  11. try:
  12. connection = get_db_connection()
  13. cursor = connection.cursor()
  14. # 检查对话是否存在
  15. conversation_query = "SELECT 1 FROM conversations WHERE conversation_id = %s"
  16. cursor.execute(conversation_query, (conversation_id,))
  17. conversation_exists = cursor.fetchone()
  18. if not conversation_exists:
  19. # 插入对话记录
  20. conversation_query = """
  21. INSERT INTO conversations (conversation_id)
  22. VALUES (%s)
  23. """
  24. cursor.execute(conversation_query, (conversation_id,))
  25. # 插入聊天记录
  26. chat_record_query = """
  27. INSERT INTO chat_records (conversation_id, user_message, bot_message)
  28. VALUES (%s, %s, %s)
  29. """
  30. cursor.execute(chat_record_query, (conversation_id, user_message, bot_message))
  31. connection.commit()
  32. except mysql.connector.Error as err:
  33. print(f"Error: {err}")
  34. raise
  35. finally:
  36. if connection.is_connected():
  37. cursor.close()
  38. connection.close()

数据库结构   sql语句   

  1. SET NAMES utf8mb4;
  2. SET FOREIGN_KEY_CHECKS = 0;
  3. -- ----------------------------
  4. -- Table structure for chat_records
  5. -- ----------------------------
  6. DROP TABLE IF EXISTS `chat_records`;
  7. CREATE TABLE `chat_records` (
  8. `id` int(11) NOT NULL AUTO_INCREMENT,
  9. `conversation_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  10. `user_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
  11. `bot_message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
  12. PRIMARY KEY (`id`) USING BTREE,
  13. INDEX `conversation_id`(`conversation_id`) USING BTREE,
  14. CONSTRAINT `chat_records_ibfk_1` FOREIGN KEY (`conversation_id`) REFERENCES `conversations` (`conversation_id`) ON DELETE CASCADE ON UPDATE CASCADE
  15. ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  16. -- ----------------------------
  17. -- Table structure for conversations
  18. -- ----------------------------
  19. DROP TABLE IF EXISTS `conversations`;
  20. CREATE TABLE `conversations` (
  21. `id` int(11) NOT NULL AUTO_INCREMENT,
  22. `conversation_id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  23. `conversation_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  24. PRIMARY KEY (`id`) USING BTREE,
  25. INDEX `conversation_id`(`conversation_id`) USING BTREE
  26. ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  27. SET FOREIGN_KEY_CHECKS = 1;

前端页面和样式

/templates/index.html   

头像图片可以自定义  修改就行 

  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8"/>
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0"/>
  6. <title>顶顶顶顶顶</title>
  7. <script src="https://cdn.tailwindcss.com"></script>
  8. <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github-dark.min.css"/>
  9. <script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js"></script>
  10. <script src="https://cdn.jsdelivr.net/npm/highlightjs-line-numbers.js@2.8.0/dist/highlightjs-line-numbers.min.js"></script>
  11. <script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.11/dist/clipboard.min.js"></script>
  12. <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
  13. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"/>
  14. <link rel="stylesheet" href="/static/css/style.css" />
  15. <link rel="icon" href="/static/images/favicon.ico" type="image/x-icon">
  16. </head>
  17. <body class="bg-blue-200 font-sans leading-normal tracking-normal">
  18. <div class="loader" id="loader">
  19. <div class="loader-text">Loading...</div>
  20. <h2>正在加载...请稍候</h2>
  21. <div class="loader-bar"></div>
  22. </div>
  23. <div class="w-full h-full sm:container sm:mx-auto sm:my-8 sm:p-4 bg-white dark:bg-zinc-800 shadow-md rounded-lg sm:overflow-hidden max-w-4xl">
  24. <div class="flex flex-col h-[100vh] sm:h-[80vh] md:h-[85vh]">
  25. <div class="px-4 py-3 border-b dark:border-zinc-700">
  26. <div class="flex justify-between items-center">
  27. <h1 class="text-2xl font-semibold text-zinc-800 dark:text-white">
    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/880262
    推荐阅读
    相关标签