前言:
2025年开年大作应该可以有DeepSeek的一席之地了,而且现在可以说是日活跃度非常高的一个大模型,所以说了解并掌握他的API是一个必要的开发过程。博主通过之前的百度AI开发心路写了一下关于DeepSeek的一个简单demo,以供大家参考学习。
正文:
一、构思
其实这个项目对于我来说已经不陌生了,参考我之前的项目文章就可以略知一二。利用Qt制作基于百度Ai的智能语音聊天机器人_基于qt的智能机器人-优快云博客文章浏览阅读2.8k次,点赞9次,收藏41次。在学习和使用Qt框架制作ui的过程中,渐渐发现自己可以搞一个智能机器人的ui界面用于聊天和前端控制底层的Ros框架,于是就开始了断断续续长达5day的项目开发周期。技术栈:在这个项目里,首先就是要用到Qt的设计框架,用到了一个类作为聊天窗口,一个QlineEdit作为聊天输入框,还有一些作为控制交互单元,一些QLabel作为显示单元,当然还有布局器等等...最后就是用到http请求和js解析。语音录入->语音识别转文字->文字内容上传得到Ai回答->Ai回答内容转语音。_基于qt的智能机器人https://blog.youkuaiyun.com/qq_60640693/article/details/131167764?spm=1001.2014.3001.5502其实,原理都是差不多的,利用JSON数据的填充、发送、接收和解析来完成对API的调用。
二、了解API
这一步其实是很重要的,需要我们到对应的官网找到API的一些相关文档,了解数据结构和CURL已经创建自己的Key。
通过DeepSeek来创建自己的API的key,进入后,选择API开放平台,进入后该注册注册,该登录登录
OK,当你去到接口文档中,就可以看到我下面绿色框内的信息,这其实就是我们发送的JSON数据的填充方式,也就是我所说的数据结构,而且他也提供了CURL,现在只是差一个key了,你只需要回到上一个页面去申请一个,并复制就好了。
三、开始开发
提示: 由于DeepSeek是在是太火爆了服务器经常挺不住,博主针对上面的文档开发完了也不能正常使用,于是我就换了另一个支持DeepSeek的服务商硅基流动统一登录,注册API会送14元余额,够学习使用了。
和DeepSeek一样,注册登录后直接去API秘钥(创建自己的key)和文档中心(查看API的调用方式)。
文档中心中点击API手册就可以看到类似DeepSeek文档的东西了那么最关键的就是这个字符串
curl --request POST \
--url https://api.siliconflow.cn/v1/chat/completions \
--header 'Authorization: Bearer <我们申请的KEY token>' \
--header 'Content-Type: application/json' \
--data '{
"model": "deepseek-ai/DeepSeek-V3",
"messages": [
{
"role": "user",
"content": "中国大模型行业2025年将会迎来哪些机遇和挑战?"
}
],
"stream": false,
"max_tokens": 512,
"stop": [
"null"
],
"temperature": 0.7,
"top_p": 0.7,
"top_k": 50,
"frequency_penalty": 0.5,
"n": 1,
"response_format": {
"type": "text"
},
"tools": [
{
"type": "function",
"function": {
"description": "<string>",
"name": "<string>",
"parameters": {},
"strict": false
}
}
]
}'
我们就只需要将我们申请的KEY填入再用Qt的NetWork模块相关功能来填充和发送出去就好了。
代码:
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp(界面相关的代码)
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(&n,&Net::Answer,this,&Widget::getAnswer);
//this->setWindowState(Qt::WindowMaximized);//界面最大化
ui->label->setWordWrap(true);
n.init();
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
ui->label->setText("让我找找^_^ 看怎么回答你...");
QString word =ui->textEdit->toPlainText();
ui->textEdit->clear();
n.send(word);
}
void Widget::getAnswer(QString word)
{
ui->label->setText(word);
}
net.cpp(Json请求和数据解析的相关代码)
#include "net.h"
Net::Net()
{
}
void Net::init()
{
_manager = new QNetworkAccessManager();
_request.setUrl(QUrl(_curl_https));
// 头部信息
_request.setRawHeader("Authorization", ("Bearer " + _api_key).toUtf8());
_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
// qDebug() << "QSslSocket=" << QSslSocket::sslLibraryBuildVersionString();
// qDebug() << "OpenSSL支持情况:" << QSslSocket::supportsSsl();
}
int Net::send(QString word)
{
//qDebug() << word;
// messages部分
QJsonArray messages;
QJsonObject text1;
text1["role"] = "user";
text1["content"] = word;
messages.append(text1);
QJsonObject data;
data["model"] = _model;
data["messages"] = messages;
data["stream"] = false;
data["max_tokens"] = 512;
data["stop"] = QJsonArray({"null"});
data["temperature"] = 0.7;
data["top_p"] = 0.7;
data["top_k"] = 50;
data["frequency_penalty"] = 0.5;
data["n"] = 1;
data["response_format"] = QJsonObject{{"type", "text"}};
QJsonArray tools;
QJsonObject tool;
tool["type"] = "function";
QJsonObject function;
function["description"] = ""; //Fill in if needed
function["name"] = ""; //Fill in if needed
function["parameters"] = QJsonObject{};
function["strict"] = false;
tool["function"] = function;
tools.append(tool);
data["tools"] = tools;
QJsonDocument doc(data);
QByteArray postData = doc.toJson();
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setProtocol(QSsl::AnyProtocol);
config.setPeerVerifyMode(QSslSocket::VerifyNone);
_request.setSslConfiguration(config);
//发送post请求
_reply = _manager->post(_request, postData);
// 链接槽函数
// 连接信号槽处理响应
connect(_reply, &QNetworkReply::finished,this,&Net::getAnswer);
return true;
}
void Net::getAnswer()
{
if(_reply != nullptr && _reply->error() == QNetworkReply::NoError)
{
//得到返回的数据
QByteArray read_data = (_reply->readAll());
//对返回的json数据进行解析
QJsonObject obj = QJsonDocument::fromJson(read_data).object();
QJsonArray choicesarray = obj.value("choices").toArray();
if (!choicesarray.isEmpty())
{
QJsonObject choiceobj = choicesarray[0].toObject();
if (choiceobj.contains("message") && choiceobj["message"].isObject())
{
QJsonObject messageobj = choiceobj["message"].toObject();
if (messageobj.contains("content") && messageobj["content"].isString())
{
QString rawContent = messageobj["content"].toString();
QRegularExpression regex("```json\\n(.*?)\\n```");
QRegularExpressionMatch match = regex.match(rawContent);
if (match.hasMatch())
{
QString innerJsonStr = match.captured(1);
QJsonDocument innerDoc = QJsonDocument::fromJson(innerJsonStr.toUtf8());
if (!innerDoc.isNull() && innerDoc.isObject())
{
QJsonObject innerObj = innerDoc.object();
if(innerObj["key"].toString().isEmpty())
{
emit Answer("你让我怎么回答你嘛...@_@");
}
else
{
emit Answer(innerObj["key"].toString());
}
}
}
else
{
emit Answer(messageobj["content"].toString());
}
}
}
}
}
else
{
emit Answer( "https request error:"+_reply->errorString());
}
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#define LB_HEIGHT 30
#define LB_WIDTH 100
#include <QWidget>
#include "net.h"
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void getAnswer(QString word);
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
Net n;
};
#endif // WIDGET_H
net.h
#ifndef NET_H
#define NET_H
#include <QObject>
#include <QtNetwork>
#include <QNetworkAccessManager>
#include <QString>
class Net:public QObject
{
Q_OBJECT //对信号和槽至关重要
public:
Net();
void init();
int send(QString word);
private slots:
void getAnswer();
private:
QNetworkRequest _request; // 封装网络请求信息
QNetworkAccessManager *_manager; // 管理网络请求和响应
QNetworkReply *_reply; // 网络请求响应
QString _curl_https = "https://api.siliconflow.cn/v1/chat/completions";
QString _model = "deepseek-ai/DeepSeek-V3";
QString _api_key = "你的秘钥";
QString _read_text;
signals:
void Answer(QString word);
};
#endif // NET_H
widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>819</width>
<height>580</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="styleSheet">
<string notr="true">background-color: rgb(85, 87, 83);
color: rgb(138, 226, 52);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTextEdit" name="textEdit">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>60</height>
</size>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>问你</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
CMakeLista.txt
cmake_minimum_required(VERSION 2.8)
project(deepSeek)
find_package(Qt5 COMPONENTS Widgets Core Gui REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(SOURCES
src/main.cpp
src/widget.cpp
src/net.cpp
src/widget.ui
)
set(HEADS
include/widget.h
include/net.h
)
#加载头文件到环境中
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include/
${Qt_INCLUDE_DIRS}
)
add_executable(deepSeek ${SOURCES} ${HEADS})
#链接所有动态链接库
target_link_libraries(deepSeek Qt5::Widgets Qt5::Core Qt5::Gui)
项目链接
git地址https://github.com/xs-sam/DeepSeek.git
百度网盘链接https://pan.baidu.com/s/1HBJUmR-HZiif05e1KNyYDg?pwd=xs66
四、实现效果
点击 问你......等待一会儿。
完成啦...
结语:
该说不说,这个DeepSeek确实可以称得上国产大语言模型的骄傲,用更低的成本达到了同等水平的GPT性能,为这些科研人员点赞;关键是这东西还开源,我感觉这能被玩出花样了,以后把他本地部署在自己的机器人上,甚至可以用来处理一些逻辑性强的问题,不过就是现在的服务器压力太大了,还是给他点时间我相信会发展的更好 哈哈哈 ,完结 撒花...