编程的乐趣,藏在动手的瞬间! 光啃理论知识容易犯困,也容易打消兴致?🤯 今天咱们就来点有趣味性的调整,初次阅读本文的同学建议先看看系列课程第一到四节!今天咱们就用最近解锁的新技能验收一下,一起点亮回顾的灯塔,开启强化的引擎!
今天咱们用Trae编辑器结合Qwen-Turbo模型来自动生成一个问答系统,在做这件事之前,我们首先要思考要达到什么样的效果,常规的程序中涉及到前端界面、后端服务,并且都要运行在所属的容器或服务中,才能保障系统的正常运行。
一、要点回顾:
Trae编辑器:字节跳动发布的AI原生编程工具,支持图片识别,今天主要体验一下按图生成网页的功能;
Qwen-Turbo:是阿里通义千问系列中的文本对话模型,模型推理能力和复杂指令理解能力显著增强,困难任务上的表现更优,数学、代码能力显著提升。
模型调用方式:参考《构建AI智能体:一、初识AI大模型与API调用》
模型接口封装方式:参考《构建AI智能体:二、DeepSeek的Ollama部署FastAPI封装调用》
在任务开始前,我们先看一个已有的python文件,里面是调用模型的一些基本方法,接下来我们将让AI编辑器Trae读取这个文件,按文件中的内容格式生成新的内容;
情感分析.py
import json import os import dashscope from dashscope.api_entities.dashscope_response import Role # 从环境变量中,获取 DASHSCOPE_API_KEY api_key = os.environ.get('DASHSCOPE_API_KEY') dashscope.api_key = api_key # 封装模型响应函数 def get_response(messages): response = dashscope.Generation.call( model='deepseek-v3', messages=messages, result_format='message' # 将输出设置为message形式 ) return response review = '特别喜欢这款产品,使用起来很方便。' messages=[ {"role": "system", "content": "帮我判断产品表达的意思是正向还是负向,回复请用一个词语:正向 或者 负向"}, {"role": "user", "content": review} ] response = get_response(messages) print(response.output.choices[0].message.content)
这个文件提供给AI工具参考,让工具参考模型调用的方式!
二、Trae运用实践
1. 第一代问答系统
发送生成指令:"帮我写一个与AI大模型的聊天对话页面,大模型使用qwen-turbo,参考@情感分析.py"
接收到指令后开始思考和运行了:
先后逐步生成了我们需要的文件:
文件生成完毕后,我发送“开始运行”指令,服务开始自动运行!
运行成功后,第一个版本的问答系统已经可以使用,来看看效果:
按照默认端口的地址在浏览器中打开:http://localhost:5000/ 可以进行聊天;
2. 第二代问答系统
第一代的界面是默认的,接下来我们给定一张图片,让Trae按照我们给定的图片样式修改界面布局,给deepseek的首页试试;
发送新的指令:“参考图片修改页面样式”
在文件有变化后会提示文件需要审查,默认全部接受,看效果
新的文件生成完毕,自动重新启动
刷新浏览器页面看看效果:
样式有变化,但似乎差异还很大,于是我又发送了新的指令:
“样式和图片差距比较大,需要调整,发送信息后需要有加载的效果”
看看新的界面,增加了加载提示:
静态图效果:
至此,一个智能问答系统就生成成功了;
Trae的图片识别功能还需要进一步优化,时不时会提示没有看到具体的图片,当然把图片直接放在目录下也是可以的;
当遇到错误时,工具在接收到指令后也可以很好的处理;
经历多次优化,一个聊天助手也初步完成了!
三、文件概览
我们看看自动生成的文件部分,重要的地方做个注释解说;
1. README.md
项目的概要说明文件
# Qwen-Turbo聊天助手 这是一个使用Qwen-Turbo大模型的聊天对话应用,提供了命令行和Web界面两种版本。 ## 环境准备 1. 安装Python 3.8+环境 2. 安装所需依赖包 ```bash pip install dashscope flask ``` 3. 设置环境变量 需要设置阿里云DashScope API密钥: - Windows: ```cmd set DASHSCOPE_API_KEY=your_api_key ``` - Linux/Mac: ```bash export DASHSCOPE_API_KEY=your_api_key ``` ## 运行方式 ### 命令行版本 ```bash python 聊天对话.py ``` ### Web界面版本 ```bash python web_chat.py ``` 然后在浏览器中访问 http://localhost:5000 ## 功能说明 ### 命令行版本 - 支持与Qwen-Turbo模型进行对话 - 输入'退出'、'quit'或'exit'结束对话 - 聊天历史会保存到chat_history.json文件 ### Web界面版本 - 提供美观的聊天界面 - 支持发送和接收消息 - 支持清除聊天历史 - 会话保存在服务器端 ## 文件说明 - `聊天对话.py`: 命令行版本聊天程序 - `web_chat.py`: Web界面版本聊天程序 - `情感分析.py`: 参考文件,展示了如何使用dashscope库 - `templates/index.html`: Web界面的HTML模板 - `chat_history.json`: 命令行版本的聊天历史记录 ## 注意事项 1. 确保已正确设置DASHSCOPE_API_KEY环境变量 2. 网络连接需要保持通畅 3. Web界面版本默认运行在5000端口,如需更改,请修改web_chat.py中的port参数
2. web_chat.py
Python服务文件,包含了接口的初始化和开放调用,前端模板生成,以及首页路由配置等等,主要了解
import json import os import dashscope from flask import Flask, request, render_template, jsonify, session from dashscope.api_entities.dashscope_response import Role # 初始化Flask应用 app = Flask(__name__) app.secret_key = 'supersecretkey' # 用于会话管理 # 从环境变量中获取DASHSCOPE_API_KEY api_key = os.environ.get('DASHSCOPE_API_KEY') dashscope.api_key = api_key # 确保 templates 目录存在 if not os.path.exists('templates'): os.makedirs('templates') # 封装模型响应函数 def get_response(messages): response = dashscope.Generation.call( model='qwen-turbo', # 使用qwen-turbo模型 messages=messages, result_format='message', # 将输出设置为message形式 stream=False # 非流式输出 ) return response # 首页路由 .route('/') def index(): # 初始化会话中的聊天历史 if 'chat_history' not in session: session['chat_history'] = [ {"role": "system", "content": "你是一个智能助手,能回答用户的各种问题。"} ] return render_template('index.html') # 聊天接口 .route('/chat', methods=['POST']) def chat(): user_input = request.json.get('message') # 获取会话中的聊天历史 chat_history = session.get('chat_history', []) # 添加用户输入到聊天历史 chat_history.append({"role": "user", "content": user_input}) # 获取模型响应 try: response = get_response(chat_history) assistant_response = response.output.choices[0].message.content # 添加助手响应到聊天历史 chat_history.append({"role": "assistant", "content": assistant_response}) # 更新会话中的聊天历史 session['chat_history'] = chat_history return jsonify({'response': assistant_response}) except Exception as e: return jsonify({'error': str(e)}), 500 # 清除聊天历史接口 .route('/clear_history', methods=['POST']) def clear_history(): session['chat_history'] = [ {"role": "system", "content": "你是一个智能助手,能回答用户的各种问题。"} ] return jsonify({'status': 'success'}) # 创建HTML模板文件 .before_first_request def create_template(): template_content = ''' <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Qwen-Turbo聊天助手</title> <style> body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; background-color: #f5f5f5; } .chat-container { background-color: white; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); overflow: hidden; } .chat-header { background-color: #4a6ea9; color: white; padding: 15px; text-align: center; } .chat-messages { padding: 20px; height: 400px; overflow-y: auto; border-bottom: 1px solid #eee; } .message { margin-bottom: 15px; padding: 10px 15px; border-radius: 8px; max-width: 80%; } .user-message { background-color: #dcf8c6; margin-left: auto; } .assistant-message { background-color: #e5e5ea; } .chat-input { display: flex; padding: 15px; } .chat-input input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 4px; margin-right: 10px; } .chat-input button { padding: 10px 20px; background-color: #4a6ea9; color: white; border: none; border-radius: 4px; cursor: pointer; } .chat-input button:hover { background-color: #3a5a89; } .clear-btn { display: block; margin: 10px auto; padding: 8px 16px; background-color: #f44336; color: white; border: none; border-radius: 4px; cursor: pointer; } .clear-btn:hover { background-color: #d32f2f; } </style> </head> <body> <div class="chat-container"> <div class="chat-header"> <h2>Qwen-Turbo聊天助手</h2> </div> <div class="chat-messages" id="chat-messages"> <!-- 聊天消息将在这里显示 --> </div> <div class="chat-input"> <input type="text" id="message-input" placeholder="输入您的问题..."> <button id="send-btn">发送</button> </div> <button class="clear-btn" id="clear-btn">清除历史记录</button> </div> <script> document.addEventListener('DOMContentLoaded', function() { const chatMessages = document.getElementById('chat-messages'); const messageInput = document.getElementById('message-input'); const sendBtn = document.getElementById('send-btn'); const clearBtn = document.getElementById('clear-btn'); // 发送消息 function sendMessage() { const message = messageInput.value.trim(); if (message) { // 添加用户消息到聊天窗口 addMessage(message, 'user'); // 清空输入框 messageInput.value = ''; // 发送请求到后端 fetch('/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({message: message}) }) .then(response => response.json()) .then(data => { if (data.error) { addMessage('错误: ' + data.error, 'assistant'); } else { addMessage(data.response, 'assistant'); } }) .catch(error => { addMessage('请求失败: ' + error, 'assistant'); }); } } // 添加消息到聊天窗口 function addMessage(message, sender) { const messageElement = document.createElement('div'); messageElement.classList.add('message'); messageElement.classList.add(sender === 'user' ? 'user-message' : 'assistant-message'); messageElement.textContent = message; chatMessages.appendChild(messageElement); chatMessages.scrollTop = chatMessages.scrollHeight; } // 清除历史记录 function clearHistory() { fetch('/clear_history', { method: 'POST' }) .then(response => response.json()) .then(data => { chatMessages.innerHTML = ''; }); } // 点击发送按钮发送消息 sendBtn.addEventListener('click', sendMessage); // 按Enter键发送消息 messageInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { sendMessage(); } }); // 点击清除按钮清除历史记录 clearBtn.addEventListener('click', clearHistory); }); </script> </body> </html> ''' with open('templates/index.html', 'w', encoding='utf-8') as f: f.write(template_content) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000)
四:项目总结
项目执行的前提需要了解一定的基础,过程中会遇到一些小插曲,插件版本的冲突、样式不符合本意等,不同的Prompt生成的结果也会有差异,好在是逐步调优,看到从最初的样子一点点的变好也是个很有意义的过程!工具都要多结合使用,每个都有各自的优势,善于发现,灵活运用!