自学内容网 自学内容网

我把「AI数学老师」接入了「小爱」,拍照解题,微信直出

上篇给大家分享了免费AI数学老师的本地搭建:

有朋友问:有什么方式可以体验一下么?

今天就来安排:把免费AI数学老师接入之前搭建的微信机器人小爱

实操才发现,并非容易。因为Qwen-Math默认输出 Markdown 格式,且公式是 Latex 代码,如果直接文本输出,实在不忍直视。所以需要把 Latex 文本渲染成图片进行展示。

这里折腾了好久,实操过程分享给大家。

1. 新增意图识别

零风险!零付费!我把 AI 接入微信群,爸妈玩嗨了~附教程(下)中,我把意图识别任务交给了大模型,因此,这里可以新增一个意图类别:数学题解,判断用户是否需要小爱调用数学题解服务。

至此,小爱可以识别的意图共有 9 个:

['天气', '步行规划', '骑行规划', '驾车规划', '公交规划', '地点推荐', '图片生成', '视频生成', '数学题解']

2. 核心思路实现

一旦触发数学题解意图,小爱需要根据用户输入的:图片+问题描述,去调用后端的AI数学老师大模型,并将模型回复渲染成图片,发送到微信端。

所以,核心实现逻辑包括以下几步:

  • 意图识别:根据用户聊天记录,进行意图识别,一旦判定为数学题解,则执行下一步;
  • 图片输入:从数据库中检索到用户发送的最近一张图片,作为AI数学老师的图片输入;
  • 文本输入:从用户输入中提取和问题相关的内容;
  • 请求模型:结合图片输入文本输入,请求上篇部署的AI数学老师
  • 后处理:由于Qwen-Math返回的是 Latex 文本,需要渲染成图片,答复用户;

3. Latex 文本转图片

Qwen-Math返回的是 Latex 文本示例如下:

要解二次方程 $(x^2 - 4x + 3 = 0)$,我们可以使用因式分解的方法。以下是步骤:

1. **识别二次方程**:给定的方程是 $(x^2 - 4x + 3 = 0)$。

2. **因式分解**:我们需要找到两个数,它们相乘等于常数项(3),并且相加等于线性项的系数(-4)。这两个数是 -1 和 -3,因为 $((-1) \times (-3) = 3)$ 和 $((-1) + (-3) = -4)$。

3. **重写二次方程**:使用这些数,我们可以将二次方程因式分解为 $((x - 1)(x - 3) = 0)$。

4. **解每个因子**:将每个因子等于零并解出 $(x)$。
   $[
   x - 1 = 0 \quad \text{或} \quad x - 3 = 0
   ]$
   $[
   x = 1 \quad \text{或} \quad x = 3
   ]$

5. **写出解**:方程 $(x^2 - 4x + 3 = 0)$ 的解是 $(x = 1)$ 和 $(x = 3)$。

因此,最终答案是 $(\boxed{1 \text{ 和 } 3})$。

直接返回给用户,显然没法看。

这里尝试了两种方案:

  • markdown + imgkit
  • matplotlib

其中第一种方案:首先采用 markdown 库 将文本渲染成 html 文件,然后再采用 imgkit 库 将 html 文件渲染成图片,尝试失败了。。。

下面主要介绍第二种方案,matplotlib 可以渲染最基本的 Latex 公式。

对于 Ubuntu/Debian,首先安装字体依赖包:

sudo apt-get install fonts-noto-cjk 

然后,下载字体文件,比如 SIMKAI.TTF,SimHei.ttf

依赖包引入:

import re
from matplotlib import pyplot as plt
from matplotlib import rcParams
rcParams['font.family'] = 'SimHei'  # 用来正常显示中文标签
rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

如果需要 matplotlib 支持所有 Latex 公式,可以加上下面这一行,不过需要先安装号 LaTeX,还比较麻烦。

rcParams['text.usetex'] = True

如果提示找不到字体文件,可以采用 fm 引入自定义字体:

import matplotlib.font_manager as fm

font_path = 'data/SIMKAI.TTF'
font_prop = fm.FontProperties(fname=font_path)

plt.figure()
plt.text(0.1, 0.5, markdown_text, fontproperties=font_prop, fontsize=14, va="center", ha="left")
plt.axis('off')  # 隐藏坐标轴
plt.savefig("output_image.png", bbox_inches='tight')

最后我们来看一张渲染结果:

当然,因为matplotlib 对 Latex 的支持有限,你会发现很多公式无法搞定,所以最好加上一些正则表达式的前置处理:

def markdown_to_img(markdown_text, image_path='output.png'):
    try:
        markdown_text = re.sub(r"\\boxed\{([^$]*)\}", r"\1", markdown_text)
        markdown_text = re.sub(r"\\text\{([^}]*)\}", r"\1", markdown_text)
        markdown_text = re.sub(r"(\$\[)(.*?)(\]\$)", lambda m: m.group(1) + re.sub(r"\s*\n\s*", " ", m.group(2)) + m.group(3), markdown_text, flags=re.DOTALL)
        markdown_text = markdown_text.replace(r"\quad", " ")
        markdown_text = markdown_text.replace("和", "&").replace("或", "|")
        plt.figure()
        plt.text(0.1, 0.5, markdown_text, fontproperties=font_prop, fontsize=14, va="center", ha="left")
        plt.axis('off')  # 隐藏坐标轴
        plt.savefig(image_path, bbox_inches='tight')
    except Exception as e:
        print(e)

最终效果展示如下:

4. 效果展示

最后,我们接入微信机器人,看看测试效果吧:

默认会从数据库中检索用户最近上传的一张图片,如果没有,则完全基于文本输入进行回答。

写在最后

本文通过简单两步为小爱接入了 AI数学题解 的能力,你只需拍照上传图片,任性向他提问。

希望这款免费AI老师,能帮你省下一笔家教费~

如果对你有帮助,不妨点赞收藏备用。

大家有更好的想法,欢迎来聊。


为方便大家交流,新建了一个 AI 交流群,欢迎感兴趣的小伙伴加入。

小爱(AI)也在群里,公众号后台「联系我」,拉你进群。


原文地址:https://blog.csdn.net/u010522887/article/details/142969104

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!