编程的乐趣,藏在动手的瞬间! 光啃理论知识容易犯困,也容易打消兴致?🤯 今天咱们就来点有趣味性的调整,初次阅读本文的同学建议先看看系列课程第一到四节!今天咱们就用最近解锁的新技能验收一下,一起点亮回顾的灯塔,开启强化的引擎!
今天咱们用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
# 首页路由
@app.route('/')
def index():
# 初始化会话中的聊天历史
if 'chat_history' not in session:
session['chat_history'] = [
{"role": "system", "content": "你是一个智能助手,能回答用户的各种问题。"}
]
return render_template('index.html')
# 聊天接口
@app.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
# 清除聊天历史接口
@app.route('/clear_history', methods=['POST'])
def clear_history():
session['chat_history'] = [
{"role": "system", "content": "你是一个智能助手,能回答用户的各种问题。"}
]
return jsonify({'status': 'success'})
# 创建HTML模板文件
@app.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生成的结果也会有差异,好在是逐步调优,看到从最初的样子一点点的变好也是个很有意义的过程!工具都要多结合使用,每个都有各自的优势,善于发现,灵活运用!