Qt接入大语言模型,实现一个Ai聊天机器人
在 Qt 桌面应用中接入大语言模型,最直接的落地方式是先实现一个 AI 聊天机器人:用户输入问题,程序把消息交给模型,模型以流式方式返回内容,界面实时显示回复。
如果完全从零开始,需要自己处理 HTTP 请求、流式 SSE 解析、错误处理、停止生成、聊天界面和模型配置。Qt-UI AgentKit 已经把这些基础能力封装成一组 Qt/C++ 接口,可以更快完成第一版聊天机器人。
本文基于 UIGearsAgentKit Demo 中的基础对话能力,说明如何使用 AgentKit 实现一个可运行的 AI Chat Bot。

一、AgentKit 提供了什么
AgentKit 当前基础对话相关接口位于命名空间:
UIGQtLib::QtAgent
常用类包括:
ModelConfig:模型配置,包含 provider、baseUrl、apiKey、model、temperature、maxTokens、timeoutMs、stream。ChatRequest:聊天请求,负责保存 system/user/assistant 消息。ChatModel:模型抽象基类。MockChatModel:离线模拟模型,不需要网络和 API Key,适合 Demo 和本地验证。OpenAICompatibleModel:OpenAI-compatible 接口实现。ChatReply:一次模型回复对象,提供 delta、finished、failed、canceled 信号。AgentChatPanel:可嵌入 Qt Widgets 的聊天面板,包含消息区、输入区、发送、停止和清空按钮。ModelConfigWidget:模型配置控件,用于切换 Mock/OpenAI-compatible 并填写接口参数。
也就是说,一个基础聊天机器人并不需要直接写 QNetworkAccessManager,只需要组装 ChatRequest,选择一个 ChatModel,然后把 ChatReply 的信号连接到聊天面板即可。
二、最小工程接入
在 CMake 中链接 AgentKit 库:
target_link_libraries(MyQtChatBot PRIVATE
UIGearsAgentKitLib
)
在代码中包含聚合头文件:
#include "QtAgentKit.h"
如果只使用基础对话,也可以只包含:
#include "QtAgentChatModel.h"
#include "QtAgentWidgets.h"
三、准备模型配置
AgentKit 的模型配置由 ModelConfig 表示。
UIGQtLib::QtAgent::ModelConfig config;
config.provider = QStringLiteral("openai");
config.baseUrl = QStringLiteral("https://api.openai.com/v1");
config.apiKey = qEnvironmentVariable("OPENAI_API_KEY");
config.model = QStringLiteral("gpt-4.1-mini");
config.temperature = 0.2;
config.maxTokens = 1024;
config.timeoutMs = 60000;
config.stream = true;
如果没有 API Key,可以先使用 Mock 模型:
UIGQtLib::QtAgent::ModelConfig config; config.provider = QStringLiteral("mock"); config.model = QStringLiteral("mock"); config.stream = true;
AgentKit Demo 中还支持读取 agentkit.local.json:
{ "provider": "openai", "baseUrl": "https://api.openai.com/v1", "apiKey": "your-api-key", "model": "gpt-4.1-mini", "maxTokens": 1024, "timeoutMs": 60000, "stream": true }
实际项目中建议使用本地配置文件或环境变量,不要把 API Key 提交到仓库。
四、创建聊天窗口
下面是一个基于 AgentKit 的最小聊天窗口。它包含:
- 左侧模型配置面板。
- 右侧聊天面板。
- Mock 模型和 OpenAI-compatible 模型。
- 发送消息、流式追加、完成、失败和停止生成处理。
#include "QtAgentKit.h" #include <QtWidgets/QHBoxLayout> #include <QtWidgets/QWidget> class AgentChatBotWindow : public QWidget { Q_OBJECT public: explicit AgentChatBotWindow(QWidget* parent = nullptr) : QWidget(parent) { _mockModel = new UIGQtLib::QtAgent::MockChatModel(this); _openAiModel = new UIGQtLib::QtAgent::OpenAICompatibleModel(this); _configWidget = new UIGQtLib::QtAgent::ModelConfigWidget(this); _chatPanel = new UIGQtLib::QtAgent::AgentChatPanel(this); QHBoxLayout* layout = new QHBoxLayout(this); layout->setContentsMargins(12, 12, 12, 12); layout->setSpacing(12); layout->addWidget(_configWidget); layout->addWidget(_chatPanel, 1); initDefaultConfig(); rebuildModels(); _chatPanel->appendSystemMessage( QStringLiteral("请输入问题,AgentKit 会调用大语言模型生成回复。")); connect(_configWidget, &UIGQtLib::QtAgent::ModelConfigWidget::configChanged, this, &AgentChatBotWindow::rebuildModels); connect(_chatPanel, &UIGQtLib::QtAgent::AgentChatPanel::sendRequested, this, &AgentChatBotWindow::sendMessage); } private slots: void rebuildModels() { const UIGQtLib::QtAgent::ModelConfig config = _configWidget->config(); _mockModel->setConfig(config); _openAiModel->setConfig(config); } void sendMessage(const QString& text) { rebuildModels(); _chatPanel->appendUserMessage(text); _chatPanel->beginAssistantMessage(); _chatPanel->setRunning(true); UIGQtLib::QtAgent::ChatRequest request; request.addSystemMessage(QStringLiteral( "你是一个嵌入 Qt Widgets 程序中的 AI 助手,回答要简洁、准确。")); request.addUserMessage(text); UIGQtLib::QtAgent::ChatModel* model = currentModel(); UIGQtLib::QtAgent::ChatReply* reply = model->chat(request, {}, this); connect(reply, &UIGQtLib::QtAgent::ChatReply::deltaReceived, _chatPanel, &UIGQtLib::QtAgent::AgentChatPanel::appendDelta); connect(reply, &UIGQtLib::QtAgent::ChatReply::finished, this, [this, reply](const QString&) { _chatPanel->finishAssistantMessage(); _chatPanel->setRunning(false); reply->deleteLater(); }); connect(reply, &UIGQtLib::QtAgent::ChatReply::failed, this, [this, reply](const QString& error) { _chatPanel->appendSystemMessage(QStringLiteral("请求失败:") + error); _chatPanel->setRunning(false); reply->deleteLater(); }); connect(_chatPanel, &UIGQtLib::QtAgent::AgentChatPanel::stopRequested, reply, &UIGQtLib::QtAgent::ChatReply::cancel); } private: UIGQtLib::QtAgent::ChatModel* currentModel() const { if (_configWidget->useOpenAI()) { return _openAiModel; } return _mockModel; } void initDefaultConfig() { UIGQtLib::QtAgent::ModelConfig config; const QString apiKey = qEnvironmentVariable("OPENAI_API_KEY"); config.provider = apiKey.isEmpty() ? QStringLiteral("mock") : QStringLiteral("openai"); config.apiKey = apiKey; config.baseUrl = qEnvironmentVariable("OPENAI_BASE_URL"); config.model = qEnvironmentVariable("OPENAI_MODEL"); if (config.baseUrl.isEmpty()) { config.baseUrl = QStringLiteral("https://api.openai.com/v1"); } if (config.model.isEmpty()) { config.model = QStringLiteral("gpt-4.1-mini"); } config.stream = true; config.maxTokens = 1024; config.timeoutMs = 60000; _configWidget->setConfig(config); } private: UIGQtLib::QtAgent::ModelConfigWidget* _configWidget = nullptr; UIGQtLib::QtAgent::AgentChatPanel* _chatPanel = nullptr; UIGQtLib::QtAgent::MockChatModel* _mockModel = nullptr; UIGQtLib::QtAgent::OpenAICompatibleModel* _openAiModel = nullptr; };
这段代码和 UIGearsAgentKit Demo 中的基础对话逻辑一致,核心流程来自 Demo 的 sendBasicMessage():
ChatRequest request; request.addSystemMessage(...); request.addUserMessage(text); ChatReply* reply = model->chat(request, {}, this); connect(reply, &ChatReply::deltaReceived, chatPanel, &AgentChatPanel::appendDelta); connect(reply, &ChatReply::finished, ...); connect(reply, &ChatReply::failed, ...);
五、main.cpp 示例
创建一个普通 Qt Widgets 程序即可运行。
#include <QtWidgets/QApplication> int main(int argc, char* argv[]) { QApplication app(argc, argv); AgentChatBotWindow window; window.resize(1100, 720); window.show(); return app.exec(); }
如果希望和 AgentKit Demo 一样使用深色样式,可以加载 UIGearsAgentKit/styles/dark.qss:
QFile file("styles/dark.qss"); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { app.setStyleSheet(QString::fromUtf8(file.readAll())); }
六、ChatRequest 如何组织上下文
ChatRequest 是 AgentKit 对模型消息的封装。
UIGQtLib::QtAgent::ChatRequest request; request.addSystemMessage("你是一个 Qt 开发助手。"); request.addUserMessage("如何在 Qt 中创建按钮?");
它会生成符合 OpenAI-compatible messages 格式的 JSON:
[ { "role": "system", "content": "你是一个 Qt 开发助手。" }, { "role": "user", "content": "如何在 Qt 中创建按钮?" } ]
基础 Demo 每次只发送当前用户问题。如果要实现多轮上下文,可以在窗口中保存历史消息:
_history.addUserMessage(text); ChatRequest request; request.addSystemMessage("你是一个 Qt 开发助手。"); for (const ChatMessage& message : _history.messages()) { request.addMessage(message); }
也可以直接使用 AgentKit 的 ChatMemory 模块来管理多轮历史。对于真实产品,建议保留最近若干轮对话,并对更早的内容做摘要或检索。
七、为什么要保留 MockChatModel
AgentKit Demo 默认可以离线运行,这是因为它内置了 MockChatModel。
Mock 模型的价值很实际:
- 没有 API Key 时也能展示 UI。
- 没有网络时也能验证聊天流程。
- 可以测试流式输出、停止生成、按钮状态和消息追加。
- 方便演示软件能力,而不依赖外部服务稳定性。
所以在产品中建议保留 provider 切换:
ChatModel* model = configWidget->useOpenAI()
? static_cast<ChatModel*>(openAiModel)
: static_cast<ChatModel*>(mockModel);
这样 Demo、测试环境和真实环境可以共用同一套 UI。
八、OpenAICompatibleModel 做了哪些事
使用 OpenAICompatibleModel 后,应用层不需要手写网络请求。AgentKit 内部会处理:
- 拼接
{baseUrl}/chat/completions。 - 设置
Content-Type: application/json。 - 设置
Authorization: Bearer {apiKey}。 - 组装 model、messages、temperature、max_tokens、stream。
- 非流式响应解析。
- 流式 SSE 数据解析。
ChatReply::deltaReceived增量输出。ChatReply::finished完成通知。ChatReply::failed错误通知。ChatReply::cancel取消请求。
业务代码只需要关心“用户输入什么”和“界面如何显示模型回复”。
九、从聊天机器人扩展到智能体
基础聊天机器人只是 AgentKit 的第一步。Demo 中还演示了设备分析场景,它把聊天、工具调用、审批和 Trace 组合在一起:
ToolRegistry注册本地工具。FunctionTool把 C++ 函数暴露给模型。AgentExecutor负责模型循环、工具调用和最终回答。ToolCallTraceView显示工具调用过程。ApprovalDialog对文件写入等敏感操作进行确认。
例如 Demo 里注册了几个工具:
_toolRegistry->registerTool(new UIGQtLib::QtAgent::FunctionTool( "find_abnormal_devices", "查找预警或严重状态的演示设备。", objectSchema({}), UIGQtLib::QtAgent::ToolPermission::ReadOnly, [this](const QJsonObject& args) { return findAbnormalDevices(args); }, _toolRegistry));
当用户输入“查找异常设备并导出报告”时,智能体可以先调用查询工具,再调用导出工具;如果导出涉及文件系统权限,会触发 Approval 确认。
这就是从 AI 聊天机器人升级为 AI Agent 的关键区别:
- 聊天机器人只生成文本。
- 智能体可以理解任务、调用工具、记录过程,并在必要时请求人工确认。
十、实现效果
如果你要在自己的 Qt 项目中接入 AgentKit,可以按这个顺序推进:
- 先接入
AgentChatPanel,跑通 Mock 模型。 - 加入
ModelConfigWidget,支持填写 baseUrl、apiKey、model。 - 切换到
OpenAICompatibleModel,测试真实模型。 - 把常用业务函数包装成
FunctionTool。 - 对文件写入、网络访问、系统命令等操作增加 Approval。
- 使用
ToolCallTraceView给开发和用户展示调用过程。 - 对产品文档、日志、知识库接入 RAG 检索。
这样可以从一个可演示的聊天窗口,逐步演进为能解决业务问题的 Qt 智能体应用。
使用 Qt-UI AgentKit 接入大语言模型,不需要从零处理 HTTP、流式解析和聊天 UI。基础聊天机器人可以由四个核心对象完成:
AgentChatPanel:负责聊天界面。ModelConfigWidget:负责模型配置。ChatRequest:负责组织 system/user 消息。ChatModel+ChatReply:负责模型调用和流式返回。
这套接口已经在 UIGearsAgentKit Demo 中验证过:默认使用 Mock 模型离线运行,配置 API Key 后可以切换真实 OpenAI-compatible 模型。
当基础对话跑通后,再继续接入工具调用、审批、Trace、RAG 和状态工作流,就可以把 Qt 桌面程序从“有一个聊天框”升级为真正可用的 AI Agent 应用。
产品官网 www.qt-ui.com

浙公网安备 33010602011771号