AI通用大模型编程需要的能力

发布于:2024-10-10 ⋅ 阅读:(11) ⋅ 点赞:(0)

        这几天研究通过通义千问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,  # 传递标签选项到模板
    })

        重新运行程序,这次对了