构建一个AI聊天机器人来运行代码和调整图表

社区文章 发布于2023年12月21日

由 Panel 和 Mixtral 8x7B 提供支持

作者:Andrew HuangSophia Yang

您是否曾经为了演示文稿或学术论文而浪费了数小时调整图表,例如在 StackOverflow 上搜索如何更改标签的字体大小?未来已来;让 LLM 为您改进图表!

image/jpeg

在这篇博客文章中,我们将使用 Panel 和 Mixtral 8x7b 构建一个 AI 聊天机器人,它将帮助您生成代码并执行代码以调整 Matplotlib 图表。它有两个功能:

  1. 您可以与 AI 助手聊天,对 Matplotlib 图表进行小幅调整,或者要求它“使此图表适合海报演示”。当我们遇到样式问题但不知道从何开始时,这尤其有用。这个 AI 聊天机器人不仅会生成想法,还会直接生成可运行的代码来改进您的图表。

image/gif

  1. 您还可以检查图表的代码,直接编辑代码,并获取更新版本的图表。当您想从自己的图表开始时,这很有帮助。您可以将自己图表的代码复制粘贴到此处,作为 AI 改进的起点。

image/gif

托管应用程序和代码

如何制作这个聊天机器人?

在开始之前,我们先从 https://console.mistral.ai/users/api-keys/ 生成一个 Mistral API 密钥

image/png

生成密钥后,请务必将其保存为环境变量:export MISTRAL_API_KEY="TYPE YOUR API KEY"

Mistral API 有三个聊天端点:

  • Mistral-tiny:Mistral 7B Instruct v0.2,是最初 Mistral-7B 的更好微调版本。
  • Mistral-small:Mixtral 8x7B,精通多种语言和代码。
  • Mistral-medium:顶级服务模型,性能优于 GPT3.5。

Mistral-small 和 Mistral-medium 在生成代码方面都比 Mistral-tiny 强得多。Mistral-small 响应更快且成本更低,因此我们将使用 Mistral-small。但如果输出质量是您的首要考虑,我们绝对推荐 Mistral-medium,因为它生成最佳的代码响应。

查看我们之前的博客文章 使用 Panel 构建 Mixtral 聊天机器人,了解我们如何使用 Mistral API、transformers、llama.cpp 和 Panel 来创建使用 Mixtral 8x7B Instruct 模型的 AI 聊天机器人。

步骤 0:导入包

现在我们开始编写实际代码。请确保在您的 Python 环境中安装了所需的 `panel` 和 `mistralai` 包,并导入所需的包。

import re
import os
import panel as pn
from mistralai.async_client import MistralAsyncClient
from mistralai.models.chat_completion import ChatMessage
from panel.io.mime_render import exec_with_return

pn.extension("codeeditor", sizing_mode="stretch_width")

步骤 1:定义默认行为

这是此步骤的代码,我们可以定义以下内容:

  • 我们想要使用的 LLM 模型:LLM_MODEL="mistral-small"
  • 系统消息
You are a renowned data visualization expert
with a strong background in matplotlib.
Your primary goal is to assist the user
in edit the code based on user request
using best practices. Simply provide code 
in code fences (```python). You must have `fig`
as the last line of code
  • 用户内容的格式,我们将用户消息与当前的 Python 代码结合起来。
  • 用户与聊天机器人交互时看到的默认 Matplotlib 图表。

您可以根据自己的用例随意更改这些默认设置。

步骤 2:定义 callback 函数

此函数定义了我们的聊天机器人如何响应用户消息。此代码看起来比我们之前博客文章中的示例稍微复杂一些,因为 AI 不仅需要响应文本,还需要响应代码。

  • 我们将所有消息历史记录存储在 `messages` 列表中。
  • 当用户发送消息时,我们将消息文本和来自 `code_editor` 小部件(参见步骤 3)的当前代码状态合并,并添加到 `messages` 列表中。
  • 我们将所有这些消息发送到 Mistral 模型。
  • 然后我们从模型输出中提取 Python 代码,并更新 `code_editor` 中的 Python 代码。
client = MistralAsyncClient(api_key=os.environ["MISTRAL_API_KEY"])

async def callback(content: str, user: str, instance: pn.chat.ChatInterface):
    # system
    messages = [SYSTEM_MESSAGE]

    # history
    messages.extend([ChatMessage(**message) for message in instance.serialize()[1:-1]])

    # new user contents
    user_content = USER_CONTENT_FORMAT.format(
        content=content, code=code_editor.value
    )
    messages.append(ChatMessage(role="user", content=user_content))

    # stream LLM tokens
    message = ""
    async for chunk in client.chat_stream(model=LLM_MODEL, messages=messages):
        if chunk.choices[0].delta.content is not None:
            message += chunk.choices[0].delta.content
            yield message

    # extract code
    llm_code = re.findall(r"```python\n(.*)\n```", message, re.DOTALL)[0]
    if llm_code.splitlines()[-1].strip() != "fig":
        llm_code += "\nfig"
    code_editor.value = llm_code

步骤 3:定义小部件

  1. ChatInterface:Panel 提供了一个内置的 ChatInterface 小部件,为各种消息提供了用户友好的前端聊天机器人界面。`callback` 指向我们在上一步中定义的函数。它在用户发送消息时执行。
chat_interface = pn.chat.ChatInterface(
    callback=callback,
    show_clear=False,
    show_undo=False,
    show_button_name=False,
    message_params=dict(
        show_reaction_icons=False,
        show_copy_icon=False,
    ),
    height=700,
    callback_exception="verbose",
)
  1. matplotlib_pane 是一个 Panel 对象,它显示 Python 代码中的 Matplotlib 图表。它是如何执行 Python 代码并返回图表的呢?秘密在于 exec_with_return 函数,它执行代码片段并返回结果输出。默认情况下,matplotlib_pane 执行我们在步骤 1 中定义的默认 Matplotlib 代码。
matplotlib_pane = pn.pane.Matplotlib(
    exec_with_return(DEFAULT_MATPLOTLIB),
    sizing_mode="stretch_both",
    tight=True,
)

image/png

  1. code_editor 是另一个 Panel 对象,它允许嵌入代码编辑器。
code_editor = pn.widgets.CodeEditor(
    value=DEFAULT_MATPLOTLIB,
    sizing_mode="stretch_both",
)

image/png

图表如何更新?

只要代码发生变化,图表就会更新。具体来说,`matplotlib_pane` 使用 `param.watch` 方法监视 `code_editor` 中的代码变化。

# watch for code changes
def update_plot(event):
    matplotlib_pane.object = exec_with_return(event.new)
code_editor.param.watch(update_plot, "value")

那么代码何时更新呢?

  • 每当 AI 助手输出 Python 代码时,此 Python 代码将成为 `code_editor` 的新值。这在步骤 2 的 `callback` 函数中定义。
  • 无论何时我们直接在 `code_editor` 中更改代码,代码都会更改,并且图表将自动更新。

步骤 4:定义布局

最后,我们可以定义如何在我们应用程序中放置每个小部件。

# lay them out
tabs = pn.Tabs(
    ("Plot", matplotlib_pane),
    ("Code", code_editor),
)

sidebar = [chat_interface]
main = [tabs]
template = pn.template.FastListTemplate(
    sidebar=sidebar,
    main=main,
    sidebar_width=600,
    main_layout=None,
    accent_base_color="#fd7000",
    header_background="#fd7000",
)
template.servable()

然后运行 `panel serve app.py` 以使用 CLI 启动服务器并与此应用程序交互。

结论

如果您使用 Python 可视化数据,如果 AI 聊天机器人能够帮助您编写 Python 代码并自动改进您的可视化,那将是一件非常棒的事情。科学家和研究人员可以专注于可视化的实际信息,让 AI 帮助处理样式和其他方面。这篇博客文章介绍了如何使用 Panel 和 Mixtral 8x7b 构建这样一个 AI 聊天机器人。我们希望您能发现这个聊天机器人和本教程很有帮助!

如果您有兴趣了解更多关于如何使用 Panel 构建 AI 聊天机器人的信息,请阅读我们的相关博客文章:

如果您觉得 Panel 有用,请考虑在 Github 上给我们一颗星 (https://github.com/holoviz/panel)。如果您有任何问题,请随时在我们的 Discourse 上提问。祝您编码愉快!

社区

嗨,我真的非常感谢您的努力。仅仅一个月前,我还在学习 Pandas 和 NumPy,现在我已经完成了一个完整的带有活动仪表板的数据分析项目,并在 Hugging Face 上实现。我的导师对这一成就印象深刻,这一切都归功于您的教程。我还有很多东西要学,但我必须先花点时间表达我的感激之情。

这是我的仪表板(仍在开发中,但我已经做出来了!):
https://huggingface.co/spaces/KillD00zer/PeakFit_activDash

注册登录 发表评论