AI编程实战:Python + Qwen-agent 实现chat2SQL智能助手系统(三)
Windows 笔记本(原IDE PyCharm 2024.3.4 (Community Edition)已不合适使用)vue.js为了方便阅读,此系列文章,每一篇开头都保持上述【项目目标】和【项目背景】,以及【想法 + 使用AI工具实现过程】中的“工具与技术框架介绍”。上一篇文章说到,最后得到的SQL语句中有换行等其他格式的字符,导致得到的SQL无法直接复制粘贴,运行。也谈及了问题可能是出现在
项目目标
- 满足自己筛选基金经理;
- 写一个跟AI相关的项目;
- 学习与锻炼Python编程;
- 学习与使用开源框架 Qwen-agent。
项目背景
早在2020年底就尝试过爬取网上的基金数据用来解决自己的问题了,从网上学到一些筛选基金经理的理论,想着去实践,但是专业网站、APP都不能满足。
因此,就想着自己来写一个工具,从数据采集到最后数据分析结果呈现,尽可能地让整个过程自动化。可是,一直未去实践,仅是有想法而已,画画流程图而已。
2020年,随着 GPT-3火爆全球,AI正式进入科技领域的热门。而我是在近一年多才慢慢主动去关注这个领域,去学习一些应用层技术。之后,了解到有chan2SQL,觉得挺有意思的。很快就和自己以前构想的基金经理筛选项目结合到一起了。
好了,大概就这样,接下来就是实现的过程了。整个过程,基本上靠LLM chat工具来写代码,而我主要负责出想法,调试代码。
想法 + 使用AI工具实现过程
工具与技术框架介绍
工具:
- Windows 笔记本
- PyCharm 2025.1 (原IDE PyCharm 2024.3.4 (Community Edition) 已不合适使用)
技术框架:
- Qwen-agen 0.0.24;
- Python 3.12;
- flask 3.1.0;
- flask-cors 3.0.10;
- vue.js
Python解释器里关键包:
- mysql 0.0.3
- mysql-connector-python 8.4.0
- mysqlclient 2.2.7
为了方便阅读,此系列文章,每一篇开头都保持上述【项目目标】和【项目背景】,以及【想法 + 使用AI工具实现过程】中的“工具与技术框架介绍”。
上一篇文章说到,最后得到的SQL语句中有换行等其他格式的字符,导致得到的SQL无法直接复制粘贴,运行。也谈及了问题可能是出现在 prompt上。
而经过验证,确实可通过修改 system prompt来解决这个问题。
新的 system prompt 定义如下:(只是修改了第4点)
# 构建 system_prompt
system_prompt = f'''
你是一个数据库助手,能将自然语言转换为 SQL。请遵循以下规则:
1. 始终参考以下表结构:
{get_table_schema()}
2. 生成的 SQL 必须严格符合表结构和字段名。
3. 如果问题涉及未提及的表或字段,请直接告知用户。
4. 你只需输出 SQL 语句,不要存在格式化的内容,不要执行它,也不要解释。
'''
基于初版代码优化过程
本次主要优化内容
- 实现 Vue + Flask 前后端分离;
- 探索 Qwen-agent 是否支持其他 LLM
初始代码如下
主程序 app.py
from flask import Flask, render_template, request
import mysql.connector
from mysql.connector import Error
import os
from dotenv import load_dotenv
from qwen_agent.agents import Assistant
app = Flask(__name__)
# 加载环境变量(用于数据库配置)
load_dotenv()
# 数据库连接配置(从 .env 文件读取)
def get_db_connection():
try:
connection = mysql.connector.connect(
host=os.getenv('DB_HOST'),
user=os.getenv('DB_USER'),
password=os.getenv('DB_PASSWORD'),
database=os.getenv('DB_NAME')
)
return connection
except Error as e:
print(f"数据库连接失败: {e}")
return None
# 获取表结构信息(供 LLM 使用)
def get_table_schema():
return """
表结构如下:
- 表名: fund_list
字段(字段注释 | 字段类型): fund_id (基金ID | varchar), fund_name (基金名称 | varchar), company_id (基金公司编码 | varchar),
company_name (基金公司名称 | varchar), manager_ids (当前管理人ID | varchar), manager_names (当前管理人名称 | varchar),
fund_type (基金类型 | varchar), fund_size (基金规模(元) | decimal), create_user (创建人 | varchar), create_time (创建时间 | datetime), update_time (更新时间 | datetime)
- 表名: fund_manager
字段(字段注释 | 字段类型): manager_id (基金经理ID | varchar), manager_name (基金经理名称 | varchar), company_id (基金公司编码 | varchar),
company_name (基金公司名称 | varchar), work_duration (从业时长 | varchar), work_years (从业年份 | decimal),
manager_link (基金经理详情链接 | varchar), create_user (创建人 | varchar), create_time (创建时间 | datetime), update_time (更新时间 | datetime)
- 表名: manager_fund_rel
字段(字段注释 | 字段类型): id (主键 | int), manager_id (基金经理ID | varchar), manager_name (基金经理名称 | varchar),
company_id (基金公司编码 | varchar), company_name (基金公司名称 | varchar), fund_id (基金ID | varchar), fund_name (基金名称 | varchar),
fund_type (基金类型 | varchar), fund_size (基金规模(元) | decimal), fund_managing_time (基金管理时间 | varchar),
fund_managing_duration (管理时长 | varchar), fund_managing_years (管理年份 | decimal), term_return_rate (任期回报率(保留4位小数存储) | decimal),
year_return_rate (年化收益率(保留4位小数存储) | decimal), create_user (创建人 | varchar), create_time (创建时间 | datetime), update_time (更新时间 | datetime)
"""
import re
# 正则表达式提取 SQL
def extract_sql(text):
# 匹配以 SELECT/INSERT/UPDATE/DELETE 开头的 SQL
match = re.search(r'(SELECT\s+.*?;|INSERT\s+.*?;|UPDATE\s+.*?;|DELETE\s+.*?;)', text, re.DOTALL | re.IGNORECASE)
if match:
return match.group(0).strip()
return ''
# 构建 system_prompt,强调只生成 SQL 不执行
system_prompt = f'''
你是一个数据库助手,能将自然语言转换为 SQL。请遵循以下规则:
1. 始终参考以下表结构:
{get_table_schema()}
2. 生成的 SQL 必须严格符合表结构和字段名。
3. 如果问题涉及未提及的表或字段,请直接告知用户。
4. 你只需输出 SQL 语句,不要存在格式化的内容,不要执行它,也不要解释。
'''
# 初始化 Qwen 助手(不注册任何工具)
llm_cfg = {
'model': 'qwen-plus', #'qwen-max',
'model_server': 'dashscope'
}
bot = Assistant(
llm=llm_cfg,
system_message=system_prompt
)
messages = []
@app.route('/', methods=['GET', 'POST'])
def index():
global messages
execution_result = None
if request.method == 'POST':
user_input = request.form.get('query', '')
execute_sql = request.form.get('execute_sql') # 是否点击了执行按钮
if user_input.lower() in ['exit', 'quit']:
return render_template('index.html', history=messages, sql="")
if not execute_sql:
# 用户输入自然语言,让 AI 生成 SQL
messages.append({'role': 'user', 'content': user_input})
# 获取 AI 最终生成的 SQL
final_content = ''
for r in bot.run(messages=messages):
if isinstance(r, dict):
content = r.get('content', '')
else:
content = str(r)
final_content = content.strip() # 保留最后一次的内容
# 提取SQL
extract_sql_str = extract_sql(final_content)
messages.append({'role': 'assistant', 'content': final_content})
messages.append({'role': 'assistant_sql', 'content': extract_sql_str})
else:
# 用户点击“执行 SQL”,使用后端手动执行
sql_to_run = request.form.get('sql_to_execute', '').strip()
conn = get_db_connection()
if conn and conn.is_connected():
cursor = conn.cursor(dictionary=True)
try:
cursor.execute(sql_to_run)
execution_result = cursor.fetchall()
except Error as e:
execution_result = f"执行错误:{str(e)}"
finally:
cursor.close()
conn.close()
else:
execution_result = "数据库连接失败"
return render_template(
'index.html',
history=messages,
execution_result=execution_result
)
if __name__ == '__main__':
app.run(debug=True)
前端页面 \templates\index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>SQL 生成助手</title>
<!-- 引入 CodeMirror 样式 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.css">
<style>
.CodeMirror {
border: 1px solid #ccc;
height: auto;
}
</style>
</head>
<body>
<h1>AI SQL 生成助手</h1>
{% for msg in history %}
<div style="margin-bottom: 10px;">
<strong>{{ msg.role }}:</strong>
<pre>{{ msg.user_custom_content }}</pre>
<pre>{{ msg.content }}</pre>
</div>
{% endfor %}
<form method="post">
<textarea name="query" rows="4" cols="50" placeholder="请输入你的自然语言查询..."></textarea><br/>
<input type="submit" value="生成 SQL">
</form>
{% if formatted_sql %}
<h2>格式化后的 SQL:</h2>
<textarea id="sqlEditor" rows="10" cols="80">{{ formatted_sql }}</textarea>
<button onclick="copyToClipboard()">复制 SQL 到剪贴板</button>
{% endif %}
<!-- 引入 CodeMirror JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.js"></script>
<script>
// 初始化 CodeMirror 编辑器
var editor = CodeMirror.fromTextArea(document.getElementById('sqlEditor'), {
lineNumbers: true,
mode: 'text/x-mysql',
theme: 'dracula'
});
// 复制到剪贴板功能
function copyToClipboard() {
const sqlText = editor.getValue();
navigator.clipboard.writeText(sqlText).then(() => {
alert("SQL 已复制到剪贴板!");
}, () => {
alert("复制失败,请手动复制。");
});
}
</script>
</body>
</html>
优化1:实现 Vue + Flask前后端分离
一、前言:
为啥要实现前后端分离架构呢,是为了更好地调试与使用吧,在技术开发上来说,这是实现了前端工程师与后端开发工程的分工。而为啥前端选择了vue,选择了这样一套前后端分离架构呢?
Python后端选择 Flask 的理由如下截图所示,何况前面一直 app.py 就是在使用 Flask。

而之所以选择 vue.js,是因为不想倒腾其他前端框架了,没用过,也不在项目目标中。其他较不错的前端框架,比如 React、Angular等。
二、过程:
回到优化内容来,怎么实现这么一个目标呢,直接让 LLM Chat 给写一份初始代码。
prompt:
app.py 代码内容如下:
复制粘贴 app.py 的全部代码,将上述初始代码粘贴下来,这里就不重复粘贴了
前端 \templates\index.html 代码如下:
复制粘贴 index.html 的全部代码,将上述初始代码粘贴下来,这里就不重复粘贴了
****
请根据上述代码,将其架构改为前后端分离,前端使用 vue,后端继续使用 flash,请给出完整且可运行的项目代码
这里建议大家新创建一个项目。
(1)更换 IDE
本次的代码涉及到 vue.js 的使用,原来使用 IDE PyCharm 2024.3.4 (Community Edition) 是不支持的,PyCharm 的专业版才支持,这个大家看情况解决吧。
我的办法是下载了 PyCharm 2025.1版本,下载地址:Other Versions - PyCharm
然后某宝买了一个好东西,就可没烦恼的长期使用了。
(2)安装 node.js、npm
在处理代码前,请大家确保已安装了 node.js、npm。
这里给大家一个 npm 安装教程,NPM安装与配置全流程详解(2025最新版)-CSDN博客
避免用到哪些点赞与阅读量都不少,而质量有待商榷的文章,自己就是在上面浪费了近一个小时。只要按照如下截图部分操作即可:

搞完上述准备工作,就到代码编译运行了……
LLM 给出来的代码版本,在结构上来说,是不错的。但是一运行起来,就遇到了各种各样的问题,主要问题点如下:
- 前端生成未使用到的引用,致使发生编译错误,无法运行;
- 前后端分离常见问题,404(路由、代理)、跨域;
- 前端还出现了 vue 加载语法错误的代码,致使代码无法像预期一样执行,属于运行时错误。
三、最终代码:
项目结构

app.py
from flask import Flask, jsonify, request
from flask_cors import CORS
import mysql.connector
from mysql.connector import Error
import os
from dotenv import load_dotenv
from qwen_agent.agents import Assistant
# 加载环境变量
load_dotenv()
app = Flask(__name__)
CORS(app) # 启用跨域请求
import sys
print(sys.executable)
# 数据库连接配置(从 .env 文件读取)
def get_db_connection():
try:
connection = mysql.connector.connect(
host=os.getenv('DB_HOST'),
user=os.getenv('DB_USER'),
password=os.getenv('DB_PASSWORD'),
database=os.getenv('DB_NAME')
)
return connection
except Error as e:
print(f"数据库连接失败: {e}")
return None
# 获取表结构信息(供 LLM 使用)
def get_table_schema():
return """
表结构如下:
- 表名: fund_list
字段(字段注释 | 字段类型): fund_id (基金ID | varchar), fund_name (基金名称 | varchar), company_id (基金公司编码 | varchar),
company_name (基金公司名称 | varchar), manager_ids (当前管理人ID | varchar), manager_names (当前管理人名称 | varchar),
fund_type (基金类型 | varchar), fund_size (基金规模(亿元) | decimal), create_user (创建人 | varchar), create_time (创建时间 | datetime), update_time (更新时间 | datetime)
- 表名: fund_manager
字段(字段注释 | 字段类型): manager_id (基金经理ID | varchar), manager_name (基金经理名称 | varchar), company_id (基金公司编码 | varchar),
company_name (基金公司名称 | varchar), work_duration (从业时长 | varchar), work_years (从业年份 | decimal),
manager_link (基金经理详情链接 | varchar), create_user (创建人 | varchar), create_time (创建时间 | datetime), update_time (更新时间 | datetime)
- 表名: manager_fund_rel
字段(字段注释 | 字段类型): id (主键 | int), manager_id (基金经理ID | varchar), manager_name (基金经理名称 | varchar),
company_id (基金公司编码 | varchar), company_name (基金公司名称 | varchar), fund_id (基金ID | varchar), fund_name (基金名称 | varchar),
fund_type (基金类型 | varchar), fund_size (基金规模(亿元) | decimal), fund_managing_time (基金管理时间 | varchar),
fund_managing_duration (管理时长 | varchar), fund_managing_years (管理年份 | decimal), term_return_rate (任期回报率(保留4位小数存储) | decimal),
year_return_rate (年化收益率(保留4位小数存储) | decimal), create_user (创建人 | varchar), create_time (创建时间 | datetime), update_time (更新时间 | datetime)
"""
import re
# 正则表达式提取 SQL
def extract_sql(text):
# 匹配以 SELECT/INSERT/UPDATE/DELETE 开头的 SQL
match = re.search(r'(SELECT\s+.*?;|INSERT\s+.*?;|UPDATE\s+.*?;|DELETE\s+.*?;)', text, re.DOTALL | re.IGNORECASE)
if match:
return match.group(0).strip()
return ''
# 构建 system_prompt
system_prompt = f'''
你是一个数据库助手,能将自然语言转换为 SQL。请遵循以下规则:
1. 始终参考以下表结构:
{get_table_schema()}
2. 生成的 SQL 必须严格符合表结构和字段名。
3. 如果问题涉及未提及的表或字段,请直接告知用户。
4. 你只需输出 SQL 语句,不要存在格式化的内容(比如换行符\n等),不要执行它,也不要解释。
'''
# 初始化 Qwen 助手(不注册任何工具)
llm_cfg = {
'model': 'qwen-max', # 'qwen-plus',
'model_server': 'dashscope'
}
bot = Assistant(
llm=llm_cfg,
system_message=system_prompt
)
messages = []
@app.route('/api/generate-sql', methods=['POST'])
def generate_sql():
global messages
data = request.json
user_input = data.get('query', '')
if not user_input:
return jsonify({'error': '缺少查询内容'}), 400
if user_input.lower() in ['exit', 'quit']:
return jsonify({'sql': ''})
# 用户输入自然语言,让 AI 生成 SQL
messages.append({'role': 'user', 'content': user_input})
# 获取 AI 最终生成的 SQL
final_content = ''
for r in bot.run(messages=messages):
if isinstance(r, dict):
content = r.get('content', '')
else:
content = str(r)
final_content = content.strip() # 保留最后一次的内容
# 提取SQL
extract_sql_str = extract_sql(final_content)
messages.append({'role': 'assistant', 'content': final_content})
return jsonify({'sql': extract_sql_str})
@app.route('/api/execute-sql', methods=['POST'])
def execute_sql():
data = request.json
sql_to_run = data.get('sql', '').strip()
if not sql_to_run:
return jsonify({'error': '缺少 SQL 语句'}), 400
conn = get_db_connection()
if not conn or not conn.is_connected():
return jsonify({'error': '数据库连接失败'}), 500
cursor = conn.cursor(dictionary=True)
try:
# 判断是否是 SELECT 查询
if sql_to_run.strip().lower().startswith('select'):
result = cursor.fetchall()
return jsonify({'result': result})
else:
conn.commit() # 提交事务
return jsonify({'message': 'SQL 执行成功', 'rows_affected': cursor.rowcount})
except Error as e:
return jsonify({'error': str(e)}), 400
finally:
cursor.close()
conn.close()
if __name__ == '__main__':
app.run(debug=True)
config.py
class Config:
DEBUG = False
SQLALCHEMY_TRACK_MODIFICATIONS = False
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
DEBUG = False
config = {
'development': DevelopmentConfig,
'production': ProductionConfig
}
index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>SQL 生成助手</title>
<!-- 引入 CodeMirror 样式 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.0/codemirror.min.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
SqlAssistant.vue
<template>
<div class="sql-assistant">
<h1>SQL 生成智能助手</h1>
<div class="chat-container">
<div v-for="(message, index) in chatMessages" :key="index" class="message">
<strong>{{ message.role }}:</strong>
<pre v-if="message.content">{{ message.content }}</pre>
</div>
</div>
<form @submit.prevent="generateSql" class="query-form">
<textarea v-model="userQuery" rows="4" placeholder="请输入你的自然语言查询..."></textarea>
<button type="submit">生成 SQL</button>
</form>
<div v-if="generatedSql" class="sql-output">
<h2>生成的 SQL:</h2>
<textarea id="sqlEditor" v-model="generatedSql" rows="10" cols="80"></textarea>
<div class="sql-actions">
<button @click="copyToClipboard">复制 SQL 到剪贴板</button>
<button @click="executeSql">执行 SQL</button>
</div>
</div>
<div v-if="executionResult" class="execution-result">
<h2>执行结果:</h2>
<pre>{{ JSON.stringify(executionResult, null, 2) }}</pre>
</div>
<div v-if="errorMessage" class="error-message">
{{ errorMessage }}
</div>
</div>
</template>
<script>
import axios from 'axios'
import CodeMirror from 'codemirror'
import 'codemirror/mode/sql/sql'
import 'codemirror/theme/dracula.css'
export default {
name: 'SqlAssistant',
data() {
return {
userQuery: '',
generatedSql: '',
chatMessages: [],
executionResult: null,
errorMessage: '',
editor: null
}
},
mounted() {
// 初始化 CodeMirror 编辑器
this.$nextTick(() => {
const editorElement = document.getElementById('sqlEditor');
if (editorElement) {
CodeMirror.fromTextArea(editorElement, {
lineNumbers: true,
mode: 'sql',
readOnly: true
});
} else {
console.error("未能找到 ID 为 'sqlEditor' 的元素");
}
});
},
methods: {
async generateSql() {
this.errorMessage = '';
this.executionResult = null;
if (!this.userQuery.trim()) {
this.errorMessage = '请输入查询内容';
return;
}
try {
// 添加用户消息到聊天记录
this.chatMessages.push({ role: 'User', content: this.userQuery });
// 调用 API 生成 SQL
const response = await axios.post('/api/generate-sql', { query: this.userQuery });
console.log('resp -------- ', response)
// 更新生成的 SQL
this.generatedSql = response.data.sql || '';
// 更新编辑器内容
if (this.editor && this.generatedSql) {
this.editor.setValue(this.generatedSql);
}
// 添加 AI 回复到聊天记录
this.chatMessages.push({ role: 'Assistant', content: `生成的 SQL:\n${this.generatedSql}` });
// 清空输入框
this.userQuery = '';
} catch (error) {
this.errorMessage = `生成 SQL 失败: ${error.message}`;
console.error('生成 SQL 错误:', error);
}
},
async executeSql() {
this.errorMessage = '';
this.executionResult = null;
if (!this.generatedSql.trim()) {
this.errorMessage = '没有可执行的 SQL 语句';
return;
}
try {
// 执行 SQL
const response = await axios.post('/api/execute-sql', { sql: this.generatedSql });
if (response.data.error) {
throw new Error(response.data.error);
}
this.executionResult = response.data.result;
} catch (error) {
this.errorMessage = `执行 SQL 失败: ${error.message}`;
console.error('执行 SQL 错误:', error);
}
},
copyToClipboard() {
const sqlText = this.editor ? this.editor.getValue() : this.generatedSql;
if (!sqlText) {
this.errorMessage = '没有可复制的 SQL 语句';
return;
}
navigator.clipboard.writeText(sqlText).then(() => {
alert("SQL 已复制到剪贴板!");
}, () => {
this.errorMessage = "复制失败,请手动复制。";
});
}
}
}
</script>
<style scoped>
.sql-assistant {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
}
h1, h2 {
color: #333;
}
.chat-container {
border: 1px solid #ddd;
padding: 15px;
margin-bottom: 20px;
max-height: 400px;
overflow-y: auto;
}
.message {
margin-bottom: 10px;
}
.query-form {
margin-bottom: 20px;
}
textarea {
width: 100%;
padding: 10px;
font-size: 16px;
box-sizing: border-box;
margin-bottom: 10px;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 15px;
margin-right: 10px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #45a049;
}
.sql-output {
margin-top: 20px;
}
.sql-actions {
margin-top: 10px;
}
.execution-result {
margin-top: 20px;
background-color: #f8f8f8;
padding: 15px;
border: 1px solid #ddd;
}
.error-message {
margin-top: 20px;
color: red;
background-color: #fff0f0;
padding: 15px;
border: 1px solid #ffcccc;
}
</style>
index.js
import { createRouter, createWebHistory } from 'vue-router'
import SqlAssistant from '../components/SqlAssistant.vue'
const routes = [
{ path: '/', component: SqlAssistant }
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
App.vue
<template>
<router-view />
</template>
<script>
export default {
name: 'App'
}
</script>
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
pakage.json
{
"name": "sql-assistant",
"version": "1.0.0",
"description": "AI SQL Assistant",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "eslint ."
},
"dependencies": {
"axios": "^1.6.7",
"codemirror": "^5.65.0",
"vue": "^3.4.21",
"vue-router": "^4.3.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^5.0.8",
"@vue/cli-plugin-eslint": "^5.0.8",
"@vue/cli-service": "^5.0.8",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-vue": "^9.23.0"
}
}
package-lock.json,上面截图忘记说明了,这个也是运行过程生成的,不需理会。
vue.config.js
module.exports = {
lintOnSave: false, // 关闭 ESLint 校验
devServer: {
proxy: {
'/api': {
target: 'http://localhost:5000', // 后端地址
changeOrigin: true, // 允许跨域
pathRewrite: {
// '^/api': '' // 把请求路径中的 /api 替换为空
}
}
},
port: 8080 // 可选:指定前端开发端口
}
}
至此,代码都在上面了,整个项目完整代码:夸克网盘分享
运行 app.py 启动后端服务,在PyCharm 终端,项目路径\frontend> 执行命令:npm run serve,启动前端。
启动成功后,浏览器访问:http://localhost:8080/

优化2:探索 Qwen-agent 是否支持其他 LLM
大家,可以从上述的运行效果来看,都没能生成想要的SQL,我猜想是 api_key 的问题,是受到了使用限制,也还不知在那里充值,在阿里云百炼上没找到,找到的朋友麻烦评论区留言告知一声,谢谢。
然后呢,也怀疑会不会是模型 qwen-max 在自然语言生成SQL上能力不够。于是,就想着能不能实现动态配置 llm。经过查询资料,查看Qwen-agent,得知目前官方是不支持的,需要修改 Qwen-agent 框架底层代码,太技术了,暂时不倒腾了。
未完待续…
回看项目目标,接下来最关键的就是要实现“筛选基金经理”,也就是要能按自然语言描述的需求,生成SQL,这里就会涉及到复杂查询SQL的问题。经过了解,要解决这个问题并非易事,这就是要学习之所在吧。对此的优化思路如下:
- 优化 prompt;
- 考证 DeepSeek 给出的思路:(先验证给出的解决方案是否是 Qwen-Agent 真的支持的,然后结合其他 LLM Chat给出的方案,综合考虑。再而,编码测试验证)
- 采用 Qwen-Agent 的 三级代理架构;
- Qwen-Agent 的逐步推理(Stepwise Reasoning)通过工具链实现多跳决策:将复杂问题分解为原子化子查询;
- 工具增强:领域专属工具包(解决知识盲区);
- 验证反馈闭环(降低错误率)。
这里放一下之前文章的链接吧,方便大家阅读。
更多推荐




所有评论(0)