这几天研究通过通义千问AI大模型编程,有三点感受,分享给大家。如果将来有新的感受,会继续分享。
1、清晰的提示词指令,让输出的成功率更高
2、了解点代码知识,虽不会写,但能看的懂
3、定位代码问题的能力
通过提示词的方法使用通义千问AI大模型编程的方法,已经在前一篇文章中分享过了,这篇文章将介绍定位问题的能力和方法。
在使用AI进行代码编程时,AI大模型有时候不能完全理解你的意思,即便输入了几次提示词,依然得不到期望的结果,这时候,解决问题的方法就是打印日志,定位到出现问题的那一行代码,然后告诉AI,这一行代码写错了。
3.1 案例
以我使用AI通义千问做网站开发为例,分享一个问题定位的过程。我通过提示词要求AI大模型做一个饼图的统计模块,AI给出的views.py代码如下:
def record_count_by_tag(request):
is_admin = request.user.is_superuser
user = request.user
# 初始化表单
if request.method == 'GET':
form = DateRangeForm(request.GET)
else:
form = DateRangeForm()
if form.is_valid():
start_date = form.cleaned_data.get('start_date')
end_date = form.cleaned_data.get('end_date')
stat_type = form.cleaned_data.get('stat_type')
else:
start_date = None
end_date = None
stat_type = None
# 根据用户权限和日期筛选记录
if is_admin and stat_type == 'by_tag':
all_records = Record.objects.all()
if start_date and end_date:
all_records = all_records.filter(date__range=(start_date, end_date))
elif is_admin and stat_type == 'by_creator':
all_records = Record.objects.all()
if start_date and end_date:
all_records = all_records.filter(date__range=(start_date, end_date))
else:
all_records = Record.objects.filter(user=user)
if start_date and end_date:
all_records = all_records.filter(date__range=(start_date, end_date))
# 统计标签
if is_admin and stat_type == 'by_tag':
all_tag_counts = all_records.values('tag').annotate(count=Count('tag')).order_by('-count')
elif is_admin and stat_type == 'by_creator':
all_tag_counts = all_records.values('user__username').annotate(count=Count('id')).order_by('-count')
else:
all_tag_counts = all_records.values('tag').annotate(count=Count('tag')).order_by('-count')
# 生成饼图的函数
def generate_pie_chart(data, title, labels=None):
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体或其他支持中文的字体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
if not data:
return None # 如果没有数据,返回 None
counts = [item['count'] for item in data]
if not labels:
labels = [item['tag'] if 'tag' in item else item['user__username'] for item in data]
# 自定义 autopct 函数,显示标签名、百分比和数量
def autopct_generator(labels, counts):
total = sum(counts)
def autopct(pct):
val = int(round(pct * total / 100.0))
index = min(int(pct / 100. * len(counts)), len(counts) - 1) # 确保索引不超出范围
return f'{labels[index]}\n{pct:.1f}%\n({val})'
return autopct
fig, ax = plt.subplots()
wedges, texts, autotexts = ax.pie(counts, labels=None, autopct=autopct_generator(labels, counts), startangle=90)
ax.axis('equal')
ax.set_title(title)
# 设置文本样式
for text in texts + autotexts:
text.set_fontsize(10) # 调整字体大小
text.set_color('white') # 设置文本颜色为白色
buf = io.BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
string = base64.b64encode(buf.read())
uri = 'data:image/png;base64,' + quote(string)
return uri
# 生成所有记录的饼图
all_tags_pie_chart = generate_pie_chart(all_tag_counts, '所有标签' if is_admin else f'{user.username} 的标签')
return render(request, 'records/tag_count.html', {
'is_admin': is_admin,
'all_tags_pie_chart': all_tags_pie_chart,
'form': form, # 传递表单到模板
'tag_counts': all_tag_counts, # 传递标签统计信息到模板
'tag_choices': Record.TAG_CHOICES, # 传递标签选项到模板
})
AI给出的forms.py代码如下:
class DateRangeForm(forms.Form):
start_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
end_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}))
# tag = forms.ChoiceField(choices=[('', '所有')] + Record.TAG_CHOICES, required=False)
stat_type = forms.ChoiceField(
choices=[('by_tag', '按标签统计'), ('by_creator', '按创建者统计')],
required=False,
widget=forms.Select(attrs={'class': 'form-control mr-2'})
)
tag_count.html代码如下:
{% extends "base_generic.html" %}
{% load custom_filters %} <!-- 加载自定义过滤器 -->
{% block title %}标签统计{% endblock %}
{% block content %}
<div class="content-header">
<h2>标签统计</h2>
</div>
<!-- 时间范围和标签选择表单 -->
<div class="bordered-section mb-3">
<form method="GET" action="" class="form-inline">
<div class="form-group d-flex align-items-center">
<label for="id_start_date" class="mr-2">开始日期:</label>
<input type="date" name="start_date" id="id_start_date" value="{{ form.start_date.value|default:'' }}" class="form-control mr-2">
</div>
<div class="form-group d-flex align-items-center">
<label for="id_end_date" class="mr-2">结束日期:</label>
<input type="date" name="end_date" id="id_end_date" value="{{ form.end_date.value|default:'' }}" class="form-control mr-2">
</div>
{% if is_admin %}
<div class="form-group d-flex align-items-center">
<label for="id_stat_type" class="mr-2">统计方式:</label>
<select name="stat_type" id="id_stat_type" class="form-control mr-2">
<option value="by_tag" {% if form.stat_type.value == "by_tag" %}selected{% endif %}>按标签统计</option>
<option value="by_creator" {% if form.stat_type.value == "by_creator" %}selected{% endif %}>按创建者统计</option>
</select>
</div>
{% endif %}
<button type="submit" class="btn btn-secondary">统计</button>
</form>
</div>
{% if all_tags_pie_chart %}
<div class="bordered-section">
<img src="{{ all_tags_pie_chart }}" alt="饼图" class="img-fluid" />
</div>
{% else %}
<div class="bordered-section">
<p>没有统计数据。</p>
</div>
{% endif %}
{% endblock %}
<style>
.bordered-section {
border: 1px solid #ddd;
padding: 15px;
margin-bottom: 15px;
border-radius: 5px;
}
.form-inline .form-group {
margin-right: 10px;
}
.form-inline .form-control, .form-inline select, .form-inline .btn {
height: calc(1.5em + 0.75rem + 2px); /* 确保输入框、下拉框和按钮的高度一致 */
}
.d-flex.align-items-center label {
line-height: 1.5; /* 确保标签文本垂直居中 */
}
</style>
网站输出的结果如下,问题是饼图的扇区姓名和百分比错位,橙色20%是suxxx,而蓝色80%是waxxx。
我通过提示词告诉AI不是我想要的,标签错位,需要定位代码问题,但是AI几次都没能解决。
为了解决这个问题,我在取值的地方都打了print输出,其中在views.py中autopct(pct):函数打了输出日志
def autopct(pct):
val = int(round(pct * total / 100.0))
index = min(int(pct / 100. * len(counts)), len(counts) - 1) # 确保索引不超出范围
print('用户列表:{}'.format(labels), '\n', '百分比:{}'.format(pct), '\n', '用户索引:{}'.format(index))
return f'{labels[index]}\n{pct:.1f}%\n({val})'
在访问饼图统计功能时,后台显示日志如下,从日志中可以看到用户列表索引index错位了,所以饼图展示错位了,数据本身没有问题。
为了解决这个问题,重新给AI输入提示词:
views.py文件中,index = min(int(pct / 100. * len(counts)), len(counts) - 1) 这一行有问题,导致列表索引错位
AI重新输出views.py:
def record_count_by_tag(request):
is_admin = request.user.is_superuser
user = request.user
# 初始化表单
if request.method == 'GET':
form = DateRangeForm(request.GET)
else:
form = DateRangeForm()
if form.is_valid():
start_date = form.cleaned_data.get('start_date')
end_date = form.cleaned_data.get('end_date')
stat_type = form.cleaned_data.get('stat_type')
else:
start_date = None
end_date = None
stat_type = None
# 根据用户权限和日期筛选记录
if is_admin and stat_type == 'by_tag':
all_records = Record.objects.all()
if start_date and end_date:
all_records = all_records.filter(date__range=(start_date, end_date))
elif is_admin and stat_type == 'by_creator':
all_records = Record.objects.all()
if start_date and end_date:
all_records = all_records.filter(date__range=(start_date, end_date))
else:
all_records = Record.objects.filter(user=user)
if start_date and end_date:
all_records = all_records.filter(date__range=(start_date, end_date))
# 统计标签
if is_admin and stat_type == 'by_tag':
all_tag_counts = all_records.values('tag').annotate(count=Count('tag')).order_by('-count')
elif is_admin and stat_type == 'by_creator':
all_tag_counts = all_records.values('user__username').annotate(count=Count('id')).order_by('-count')
else:
all_tag_counts = all_records.values('tag').annotate(count=Count('tag')).order_by('-count')
# 生成饼图的函数
def generate_pie_chart(data, title, labels=None):
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体或其他支持中文的字体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
if not data:
return None # 如果没有数据,返回 None
counts = [item['count'] for item in data]
if not labels:
labels = [item['tag'] if 'tag' in item else item['user__username'] for item in data]
# 自定义 autopct 函数,显示标签名、百分比和数量
index = 0 # 初始化计数器
def autopct(pct):
nonlocal index # 使用外部变量
total = sum(counts)
val = int(round(pct * total / 100.0))
label = labels[index]
index += 1 # 更新计数器
return f'{label}\n{pct:.1f}%\n({val})'
fig, ax = plt.subplots()
wedges, texts, autotexts = ax.pie(counts, labels=None, autopct=autopct, startangle=90)
ax.axis('equal')
ax.set_title(title)
# 设置文本样式
for text in texts + autotexts:
text.set_fontsize(10) # 调整字体大小
text.set_color('white') # 设置文本颜色为白色
buf = io.BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
string = base64.b64encode(buf.read())
uri = 'data:image/png;base64,' + quote(string)
return uri
# 生成所有记录的饼图
all_tags_pie_chart = generate_pie_chart(all_tag_counts, '所有标签' if is_admin else f'{user.username} 的标签')
return render(request, 'records/tag_count.html', {
'is_admin': is_admin,
'all_tags_pie_chart': all_tags_pie_chart,
'form': form, # 传递表单到模板
'tag_counts': all_tag_counts, # 传递标签统计信息到模板
'tag_choices': Record.TAG_CHOICES, # 传递标签选项到模板
})
重新运行程序,这次对了