| Id |
Title |
Content |
Published |
Framework Id |
User Id |
Created |
Modified |
Actions |
| 1 |
Ubuntu24.04安装Apache2和PHP8 |
<p>先安装Aapache</p>
<pre class=""><code class="language-bash hljs">sudo apt install apache2</code></pre>
<p> </p>
<p>然后安装PHP的支持</p>
<pre class=""><code class="language-bash hljs">sudo apt install php libapache2-mod-php php-cli php-mysql php-curl php-intl php-gd php-mbstring php-xml php-zip -y
sudo systemctl restart apache2</code></pre>
<p> </p>
<p>最后重启Apache</p>
<pre class=""><code class="language-bash hljs">sudo systemctl restart apache2</code></pre>
<p> </p> |
1 |
34 |
1 |
1/4/26, 6:29 PM |
1/22/26, 10:55 AM |
View Edit Delete |
| 2 |
Ubuntu24.04安装MySQL8.4 |
<p>1、添加 MySQL 官方 APT 仓库</p>
<pre class=""><code class="language-bash hljs">wget https://dev.mysql.com/get/mysql-apt-config_0.8.35-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.35-1_all.deb</code></pre>
<p> </p>
<p>2、更新软件源并安装</p>
<pre class=""><code class="language-bash hljs">sudo apt update
sudo apt install mysql-server</code></pre>
<p> </p>
<p>3、允许远程登录</p>
<pre class=""><code class="language-sql hljs">use mysql;
UPDATE user SET Host='%' WHERE User='root' AND Host='localhost';</code></pre>
<p> </p>
<p>4、刷新权限</p>
<pre class=""><code class="language-sql hljs">FLUSH PRIVILEGES;</code></pre>
<p> </p>
<p>5、创建可远程登录的新用户</p>
<pre class=""><code class="language-sql hljs">CREATE USER '帐号'@'%' IDENTIFIED BY '密码';</code></pre>
<p> </p>
<p>6、给新用户对应表的使用权</p>
<pre class=""><code class="hljs language-sql">GRANT ALL PRIVILEGES ON 表名.* TO '帐号'@'%';</code></pre>
<p> </p>
<p>7、刷新权限</p>
<pre class=""><code class="language-sql hljs">FLUSH PRIVILEGES;</code></pre>
<p> </p>
<p> </p> |
1 |
34 |
1 |
1/4/26, 6:38 PM |
1/22/26, 10:55 AM |
View Edit Delete |
| 3 |
Ubuntu24.04及以下版本安装配置SVN并设置钩子 |
<p>1、下载安装</p>
<pre class=""><code class="language-bash hljs">sudo apt install subversion</code></pre>
<p> </p>
<p>2、选择SVN服务文件及配置文件的放置位置</p>
<pre class=""><code class="language-bash hljs">sudo mkdir /svn</code></pre>
<p> </p>
<p>3、建立版本仓库</p>
<pre class=""><code class="language-bash hljs">sudo svnadmin create /svn/timeless</code></pre>
<p> </p>
<p>4、修改配置并修改对应参数(这么改就可以帐号密码登录了),顶格书写</p>
<pre class=""><code class="language-bash hljs">cd /svn/timeless/conf
sudo vim svnserve.conf</code></pre>
<p> </p>
<pre class=""><code class="language-bash hljs">anon-access = none
auth-access = write
password-db = passwd
authz-db = authz</code></pre>
<p> </p>
<p>5、设置用户密码</p>
<pre class=""><code class="language-bash hljs">sudo vim passwd</code></pre>
<p> </p>
<pre class=""><code class="language-bash hljs">[users]
yonghuming=mima</code></pre>
<p> </p>
<p>6、设置权限</p>
<pre class=""><code class="language-bash hljs">vim authz</code></pre>
<p> </p>
<pre class=""><code class="language-bash hljs">[aliases]
[groups]
admin = yonghuming
[/]
@admin = rw
</code></pre>
<p> </p>
<p>7、启动svn</p>
<pre class=""><code class="language-bash hljs">sudo svnserve -d -r /svn/</code></pre>
<p> </p>
<p>8、设置钩子</p>
<ul>
<li>先把设置钩子的路径确定好,并且checkout出来
<pre class=""><code class="language-bash hljs">svn co svn://192.168.1.1/svn/timeless /Projects/timeless ./ --username yonghuming --password mima</code></pre>
</li>
</ul>
<p> </p>
<ul>
<li>进入仓库目录下的的hooks目录
<pre class=""><code class="hljs language-bash">cd /svn/hooks/</code></pre>
</li>
</ul>
<p> </p>
<ul>
<li>修改/添加post-commit文件
<pre class=""><code class="language-bash hljs">#!/bin/bash
export LANG=en_US.UTF-8
#export PATH=$PATH:/var/www/console
/usr/bin/svn update /项目路径 --username yonghuming--password mima --no-auth-cache
</code></pre>
</li>
</ul>
<p> </p>
<ul>
<li>给post-commit执行权限
<pre class=""><code class="language-bash hljs">chmod 777 post-commit</code></pre>
</li>
</ul>
<p> </p>
<p>9、重启svn服务</p>
<pre class=""><code class="language-bash hljs">killall svnserve
sudo svnserve -d -r /svn/</code></pre>
<p><br /><br /></p>
<p><br /><br /></p> |
1 |
34 |
1 |
1/5/26, 3:03 PM |
1/22/26, 10:54 AM |
View Edit Delete |
| 4 |
Ubuntu中 禁止Apache2可以通过IP直接访问 |
<p>1、如果对应的ip或者域名没有配置虚拟主机,会默认访问第一个配置,第一个虚拟主机配置通常是在000-default.conf中,</p>
<pre class=""><code class="hljs language-bash">cd /etc/apache2/sites-available</code></pre>
<p> </p>
<p>2、编辑 000-default.conf</p>
<pre class=""><code class="language-bash hljs">vim 000-default.conf</code></pre>
<p> </p>
<p>3、在DocumentRoot /var/www/html下面增加</p>
<pre class=""><code class="language-bash hljs">RewriteEngine On
RewriteCond %{HTTP_HOST} !^(www\.)?你的域名\.com$ [NC]
RewriteRule ^ - [F]</code></pre>
<p> </p> |
1 |
34 |
1 |
1/6/26, 1:46 PM |
1/22/26, 10:47 AM |
View Edit Delete |
| 5 |
cakephp5 登录 |
<p>1、建表</p>
<pre class=""><code class="hljs language-sql">CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
created DATETIME,
modified DATETIME
);</code></pre>
<p> </p>
<p>2、在有composer.json的目录下(通常为根目录)执行</p>
<pre class=""><code class="hljs language-bash">composer require cakephp/authentication</code></pre>
<p> </p>
<p>3、在当前cake项目的根目录下执行</p>
<pre class=""><code class="hljs language-bash">bin/cake bake all users</code></pre>
<p> </p>
<p>4、在 src/Model/Entity/User.php 中 添加一句话和一个方法使密码加密</p>
<pre class=""><code class="language-php hljs">use Authentication\PasswordHasher\DefaultPasswordHasher;</code></pre>
<pre class=""><code class="hljs language-php">protected function _setPassword(string $password) : ?string
{
if (strlen($password) > 0) {
return (new DefaultPasswordHasher())->hash($password);
}
return null;
}</code></pre>
<p> </p>
<p>5、修改src/Application.php文件</p>
<pre class=""><code class="language-php hljs">//添加导入
use Authentication\AuthenticationService;
use Authentication\AuthenticationServiceInterface;
use Authentication\AuthenticationServiceProviderInterface;
use Authentication\Middleware\AuthenticationMiddleware;
use Cake\Routing\Router;
use Psr\Http\Message\ServerRequestInterface;</code></pre>
<p> </p>
<pre class=""><code class="language-php hljs">//添加接口实现implements AuthenticationServiceProviderInterface
class Application extends BaseApplication implements AuthenticationServiceProviderInterface</code></pre>
<p> </p>
<pre class=""><code class="language-php hljs">//修改方法,在middleware方法中 找到->add(new BodyParserMiddleware())这句话 在他下面添加一句
->add(new AuthenticationMiddleware($this))</code></pre>
<p> </p>
<pre class=""><code class="language-php hljs">//添加方法
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
$authenticationService = new AuthenticationService([
'unauthenticatedRedirect' => Router::url('/users/login'),
'queryParam' => 'redirect',
]);
// Load the authenticators, you want session first
$authenticationService->loadAuthenticator('Authentication.Session');
// Configure form data check to pick email and password
$authenticationService->loadAuthenticator('Authentication.Form', [
'fields' => [
'username' => 'email',
'password' => 'password',
],
'loginUrl' => Router::url('/users/login'),
'identifier' => [
'Authentication.Password' => [
'fields' => [
'username' => 'email',
'password' => 'password',
],
],
],
]);
return $authenticationService;
}</code></pre>
<p> </p>
<p>6、在src/Controller/AppController.php中添加</p>
<pre class=""><code class="language-php hljs">$this->loadComponent('Authentication.Authentication');</code></pre>
<p> </p>
<p>7、在 UsersController 中添加</p>
<pre class=""><code class="language-php hljs">public function login()
{
$this->request->allowMethod(['get', 'post']);
$result = $this->Authentication->getResult();
// regardless of POST or GET, redirect if user is logged in
if ($result && $result->isValid()) {
// redirect to /articles after login success
$redirect = $this->request->getQuery('redirect', [
'controller' => 'Articles',
'action' => 'index',
]);
return $this->redirect($redirect);
}
// display error if user submitted and authentication failed
if ($this->request->is('post') && !$result->isValid()) {
$this->Flash->error(__('Invalid username or password'));
}
}
public function beforeFilter(\Cake\Event\EventInterface $event): void
{
parent::beforeFilter($event);
// Configure the login action to not require authentication, preventing
// the infinite redirect loop issue
$this->Authentication->addUnauthenticatedActions(['login']);
}
</code></pre>
<p> </p>
<p>8、创建/templates/Users/login.php</p>
<pre class=""><code class="language-php hljs"><div class="users form">
<?= $this->Flash->render() ?>
<h3>Login</h3>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Please enter your username and password') ?></legend>
<?= $this->Form->control('email', ['required' => true]) ?>
<?= $this->Form->control('password', ['required' => true]) ?>
</fieldset>
<?= $this->Form->submit(__('Login')); ?>
<?= $this->Form->end() ?>
<?= $this->Html->link("Add User", ['action' => 'add']) ?>
</div></code></pre>
<p> </p>
<p>9、在src/Controller/AppController.php中添加以下代码,以开放对应页面不用登录即可访问</p>
<pre class=""><code class="language-php hljs">public function beforeFilter(\Cake\Event\EventInterface $event): void
{
parent::beforeFilter($event);
// for all controllers in our application, make index and view
// actions public, skipping the authentication check
$this->Authentication->addUnauthenticatedActions(['index', 'view']);
}</code></pre>
<p> </p>
<p>10、注销,在src/Controller/UsersController.php添加</p>
<pre class=""><code class="language-php hljs">public function logout()
{
$result = $this->Authentication->getResult();
// regardless of POST or GET, redirect if user is logged in
if ($result && $result->isValid()) {
$this->Authentication->logout();
return $this->redirect(['controller' => 'Users', 'action' => 'login']);
}
}</code></pre>
<p> </p> |
1 |
3 |
1 |
1/7/26, 7:30 AM |
1/7/26, 7:38 AM |
View Edit Delete |
| 6 |
cakephp5 设置action后面.json的支持 |
<p>1、在config/routes.php里 添加以下代码,已开启.json访问的模式</p>
<pre class=""><code class="language-php hljs">$builder->setExtensions(['json']);</code></pre>
<p> </p>
<p>2、在AppController里面添加一个引用一个方法,也可以直接将下面代码添加到单个Controller里面</p>
<pre class=""><code class="language-php hljs">use Cake\View\JsonView;</code></pre>
<p> </p>
<pre class=""><code class="language-php hljs">public function viewClasses(): array
{
return [JsonView::class];
}</code></pre>
<p> </p>
<p>3、在具体的控制器(Controller)方法(Action)里最后添加一句话,其中users是$this->set(compact('users'));传递的变量</p>
<pre class=""><code class="language-php hljs">$this->viewBuilder()->setOption('serialize', ['users']);</code></pre> |
1 |
3 |
1 |
1/7/26, 7:36 AM |
1/22/26, 10:46 AM |
View Edit Delete |
| 7 |
Ubuntu24.04安装docker |
<p>1、下载地址:https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/</p>
<p> </p>
<p>2、选择对应平台:</p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>amd64是x86平台</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>arm64是arm平台</span></p>
<p> </p>
<p><span style="white-space: normal;">3、</span>需要下载的软件包</p>
<p>必要下载</p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>containerd.io_1.7.27-1_amd64.deb #它是Docker引擎的核心底层组件,负责管理容器的整个生命周期</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>docker-buildx-plugin_0.25.0-1~ubuntu.24.04~noble_amd64.deb #提供buildx插件</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>docker-ce-cli_28.3.1-1~ubuntu.24.04~noble_amd64.deb #提供Docker 命令行接口</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>docker-ce_28.3.1-1~ubuntu.24.04~noble_amd64.deb #Docker社区版核心引擎包</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>docker-compose-plugin_2.38.1-1~ubuntu.24.04~noble_amd64.deb #Docker Compose组件包</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>可选下载</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>docker-ce-rootless-extras_28.3.1-1~ubuntu.24.04~noble_amd64.deb #允许非root用户启动并运行Docker的组件</span></p>
<p> </p>
<p>4、服务器自动下载(与上面步骤选一个就行)</p>
<pre class=""><code class="language-bash hljs">sudo cat > docker_wget.txt <<EOF
https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/containerd.io_1.7.27-1_amd64.deb
https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-buildx-plugin_0.25.0-1~ubuntu.24.04~noble_amd64.deb
https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-ce-cli_28.3.1-1~ubuntu.24.04~noble_amd64.deb
https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-ce_28.3.1-1~ubuntu.24.04~noble_amd64.deb
https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-compose-plugin_2.38.1-1~ubuntu.24.04~noble_amd64.deb
https://download.docker.com/linux/ubuntu/dists/noble/pool/stable/amd64/docker-ce-rootless-extras_28.3.1-1~ubuntu.24.04~noble_amd64.deb
EOF
sudo wget -i docker_wget.txt</code></pre>
<p> </p>
<p>5、安装</p>
<pre class=""><code class="language-bash hljs">sudo dpkg -i ./containerd.io_* \
./docker-ce_* \
./docker-ce-cli_* \
./docker-buildx-plugin_* \
./docker-compose-plugin_* </code></pre>
<p>6、启动服务并设置开机启动</p>
<pre class=""><code class="language-bash hljs">sudo systemctl start docker
sudo systemctl enable docker</code></pre>
<p> </p>
<p>7、设置当前用户不需要sudo 使用docker命令</p>
<pre class=""><code class="language-bash hljs">#将登录用户加入docker组
sudo usermod -aG docker $USER
#更新用户组
sudo newgrp docker</code></pre>
<p> </p>
<p>8、退出当前用户,重新登录,重新连接一次终端也可以</p>
<pre class=""><code class="language-bash hljs">docker run hello-world //这个可能有代理问题,如果是阿里云的服务器可以配置阿里云的代理,如果不是用下面的临时替代测试是否成功
docker run m.daocloud.io/docker.io/library/hello-world 测试是否安装成功</code></pre>
<p> </p>
<p>9、配置镜像</p>
<pre class=""><code class="language-bash hljs">sudo vim /etc/docker/daemon.json</code></pre>
<p> </p>
<p>在文件内输入</p>
<pre class=""><code class="hljs language-json">{
"registry-mirrors": [
"https://mirrors.tuna.tsinghua.edu.cn",
"https://mirrors.sohu.com",
"https://ustc-edu-cn.mirror.aliyuncs.com",
"https://ccr.ccs.tencentyun.com",
"https://docker.m.daocloud.io",
"https://docker.awsl9527.cn",
"https://mirror.ccs.tencentyun.com",
"https://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn"
]
}</code></pre>
<p> </p>
<p>10、重新加载并重启docker</p>
<pre class=""><code class="language-bash hljs">sudo systemctl daemon-reload
sudo systemctl restart docker</code></pre>
<p><br /><br /></p> |
1 |
37 |
1 |
1/7/26, 7:50 AM |
1/22/26, 10:46 AM |
View Edit Delete |
| 8 |
创建Vue3项目 |
<p>1、创建项目</p>
<pre class=""><code class="language-bash hljs">npm create vue@latest</code></pre>
<p> </p>
<p>2、切换到项目路径</p>
<pre class=""><code class="language-bash hljs">cd Timeless</code></pre>
<p> </p>
<p>3、初始化运行项目</p>
<pre class=""><code class="language-bash hljs">npm install
npm run dev</code></pre>
<p> </p>
<p> </p> |
1 |
20 |
1 |
1/8/26, 5:13 PM |
1/22/26, 10:45 AM |
View Edit Delete |
| 9 |
Vue3 安装Element-Plus支持 |
<pre class=""><code class="language-bash hljs">npm install element-plus --save</code></pre> |
1 |
20 |
1 |
1/8/26, 5:34 PM |
1/8/26, 5:34 PM |
View Edit Delete |
| 10 |
Vue3 安装axios支持 |
<pre class=""><code class="language-bash hljs">npm install axios</code></pre> |
1 |
20 |
1 |
1/8/26, 5:34 PM |
1/8/26, 5:34 PM |
View Edit Delete |
| 11 |
Ubuntu24.04安装Oracle JDK 25 |
<p>1、官网下载deb格式的安装包(x64 Debian Package)</p>
<pre class=""><code class="language-bash hljs">https://www.oracle.com/java/technologies/downloads/</code></pre>
<p> </p>
<p>2、将deb文件存放到/目录下去安装,不要在~目录下去安装,不然会产生权限问题</p>
<p> </p>
<p>3、给文件权限</p>
<pre class=""><code class="language-bash hljs">chmod 777 jdk-25_linux-x64_bin.deb</code></pre>
<p> </p>
<p>4、sudo apt install ./jdk-25_linux-x64_bin.deb</p>
<p><br /><br /></p> |
1 |
34 |
1 |
1/9/26, 2:00 AM |
1/22/26, 10:44 AM |
View Edit Delete |
| 12 |
Ubuntu 压缩/解压缩 |
<p>压缩</p>
<pre class=""><code class="language-bash hljs">tar -czvf 文件名.tar.gz 文件或目录</code></pre>
<p> </p>
<p>解压缩</p>
<pre class=""><code class="language-bash hljs">tar -xzvf 文件名.tar.gz</code></pre>
<p><br />ZIP解压缩</p>
<pre class=""><code class="language-sql hljs">apt update && apt install unzip
unzip xxxxx.zip</code></pre>
<p> </p> |
1 |
34 |
1 |
1/11/26, 7:42 AM |
7/6/26, 3:24 AM |
View Edit Delete |
| 13 |
Ubuntu24.04安装Docker下的Ubuntu16.04+Apache2+PHP7+MySQL5.7环境 |
<p>1、设置yml文件</p>
<p>docker-compose.yml</p>
<pre class=""><code class="language-yaml hljs">version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile
container_name: ubuntu-apache-php
ports:
- "8080:80"
volumes:
- /Projects/PHP/qmjt_docker:/var/www/html
- /docker/qmjt/apache2/logs:/var/log/apache2
restart: unless-stopped
networks:
- timeless-network
depends_on:
- mysql # 确保 MySQL 服务先启动
mysql:
image: mysql:5.7 # 使用官方 MySQL 5.7 镜像
container_name: mysql57
restart: always
environment:
MYSQL_ROOT_PASSWORD: pass # 设置 root 用户密码
MYSQL_DATABASE: database # 容器启动时创建的默认数据库
MYSQL_USER: user1 # (可选)创建新用户
MYSQL_PASSWORD: pass1 # (可选)新用户的密码
ports:
- "3307:3306" # 将宿主机的 3307 端口映射到容器的 3306 端口,避免与宿主机上可能已运行的 MySQL 服务冲突
volumes:
- /docker/mysql57/mysql_data:/var/lib/mysql # 持久化数据卷
- /docker/mysql57/my.cnf:/etc/mysql/conf.d/my.cnf # 自定义配置文件(可选)
networks:
- timeless-network
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --default-authentication-plugin=mysql_native_password # 确保使用 PHP 7.2 兼容的认证插件
networks:
timeless-network:
name: timeless
driver: bridge
volumes:
mysql_data: # 命名卷,确保数据库数据持久化</code></pre>
<p> </p>
<p>2、设置Dockerfile文件</p>
<p>Dockerfile</p>
<pre class=""><code class="hljs language-bash">FROM ubuntu:16.04
# 设置非交互式前端,避免安装过程中提示
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
# 安装Apache、PHP及常用扩展
RUN apt-get update && \
apt-get install -y --no-install-recommends \
software-properties-common \
apache2 \
&& add-apt-repository ppa:ondrej/php -y \
&& apt-get update && \
apt-get install -y \
php \
php-cli \
php-common \
php-intl \
php-curl \
php-gd \
php-json \
php-mbstring \
php-xml \
php-zip \
php-mysql \
libapache2-mod-php \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# 启用Apache的rewrite模块,并配置DocumentRoot
RUN a2enmod rewrite
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
COPY 000-default.conf /etc/apache2/sites-available/000-default.conf
# 将Apache设置为前台运行,这是容器保持运行的关键
CMD ["apache2ctl", "-D", "FOREGROUND"]
# 设置工作目录
WORKDIR /var/www/html
RUN chmod -R 777 /var/www/html</code></pre>
<p> </p>
<p>3、对应的000-default.conf文件,主要是要在默认的文件里面加上<Directory /var/www/html>这段</p>
<p>000-default.conf</p>
<pre class=""><code class="hljs language-bash"><VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
#ServerName www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory /var/www/html>
Options FollowSymLinks
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
</VirtualHost>
</code></pre>
<p> </p>
<p>4、都设置好放在同一目录下后过后,用以下命令启动</p>
<pre class=""><code class="hljs language-undefined">docker compose up</code></pre>
<p> </p>
<p>5、该环境数据库的host要用mysql</p> |
1 |
34 |
1 |
1/12/26, 9:08 AM |
1/22/26, 10:37 AM |
View Edit Delete |
| 14 |
docker镜像操作 |
<p>查看本地的镜像</p>
<pre class=""><code class="hljs language-undefined">docker images</code></pre>
<p> </p>
<p>删除镜像</p>
<pre class=""><code class="hljs language-bash">docker rmi nginx:1.20.2
# 或者
docker rmi 74cc54e27dc4</code></pre>
<p> </p>
<p>自己构建镜像</p>
<pre class=""><code class="hljs language-bash"># -t 是给镜像起名,格式也是名字:版本,不指定版本默认为latest
# . 是指定Dockerfile所在目录,如果在当前目录,则指定为.
docker build -t myImage:1.0 .
</code></pre>
<p> </p>
<p>打包镜像</p>
<pre class=""><code class="hljs language-bash"># 在当前路径下保存一个文件名为nginx-1.20.2.tar的文件,里面包含nginx:1.20.2的镜像
docker -o nginx-1.20.2.tar nginx:1.20.2 </code></pre>
<p> </p>
<p>加载打包的镜像</p>
<pre class=""><code class="hljs language-css">docker load -i nginx-1.20.2.tar</code></pre> |
1 |
37 |
1 |
1/12/26, 2:22 PM |
1/12/26, 2:22 PM |
View Edit Delete |
| 15 |
docker容器操作 |
<p>查看正在运行的容器</p>
<pre class=""><code class="hljs language-undefined">docker ps</code></pre>
<p> </p>
<p>启动容器</p>
<pre class=""><code class="hljs language-bash"># 启动名为nginx的容器
docker start nginx</code></pre>
<p> </p>
<p>停止容器</p>
<pre class=""><code class="language-bash hljs"># 停止名为nginx的容器
docker stop nginx</code></pre>
<p> </p>
<p>删除容器</p>
<pre class=""><code class="hljs language-bash"># 前提必须stop容器
docker rm ngxin
#或者-f强制删除
或者 docker rm -f ngxin(IMAGE ID和IMAGE NAME都可以)</code></pre>
<p> </p>
<p>查看日志</p>
<pre class=""><code class="language-bash hljs">docker logs</code></pre>
<p> </p>
<p>进入某个容器内部</p>
<pre class=""><code class="language-bash hljs"># 进入nginx这个容器内部
docker exec -it nginx bash</code></pre>
<p> </p>
<p>从容器内部回到宿主机</p>
<pre class=""><code class="hljs language-bash">exit</code></pre>
<p> </p>
<p> </p> |
1 |
37 |
1 |
1/12/26, 2:26 PM |
1/22/26, 10:43 AM |
View Edit Delete |
| 16 |
docker数据卷操作 |
<p>创建数据卷</p>
<pre class=""><code class="hljs language-lua">docker volume create </code></pre>
<p> </p>
<p>查看所有数据卷</p>
<pre class=""><code class="hljs language-bash">docker volume ls</code></pre>
<p> </p>
<p>删除指定数据卷</p>
<pre class=""><code class="hljs language-bash">docker volume rm</code></pre>
<p> </p>
<p>查看某个数据卷的详情</p>
<pre class=""><code class="language-bash hljs">docker volume inspect
docker volume inspect nginx</code></pre>
<p> </p>
<p>清除所有未使用的数据卷</p>
<pre class=""><code class="hljs language-undefined">docker volume prune</code></pre> |
1 |
37 |
1 |
1/12/26, 2:28 PM |
1/12/26, 2:28 PM |
View Edit Delete |
| 17 |
docker 网络操作 |
<p>创建一个网络</p>
<pre class=""><code class="language-bash hljs">docker network create
docker network create timeless
</code></pre>
<p> </p>
<p>查看所有网络</p>
<pre class=""><code class="language-bash hljs">docker network ls</code></pre>
<p> </p>
<p>删除一个网络</p>
<pre class=""><code class="hljs language-bash">docker network rm</code></pre>
<p> </p>
<p>清除所有未使用的网络</p>
<pre class=""><code class="hljs language-undefined">docker network prune</code></pre>
<p> </p>
<p>使指定容器连接加入某网络</p>
<pre class=""><code class="language-perl hljs"># 同一网络内的容器 可以用容器名互相访问
docker network connect
docker network connect timeless mysql</code></pre>
<p> </p>
<p> </p>
<p>使指定容器连接离开某网络</p>
<pre class=""><code class="hljs language-sql">docker network disconnect</code></pre>
<p> </p>
<p>查看网络详情</p>
<pre class=""><code class="hljs language-undefined">docker network inspect</code></pre> |
1 |
37 |
1 |
1/12/26, 2:31 PM |
1/22/26, 10:43 AM |
View Edit Delete |
| 18 |
Dockerfile 操作 |
<p>FROM 指定基础镜像</p>
<pre class=""><code class="hljs language-css">From centos:7</code></pre>
<p> </p>
<p>ENV 设置环境变量</p>
<pre class=""><code class="hljs language-vbnet">ENV key=value</code></pre>
<p> </p>
<p>COPY 拷贝本地文件到镜像的指定目录</p>
<pre class=""><code class="hljs language-bash">COPY ./jdk17.tar.gz /tmp</code></pre>
<p> </p>
<p>RUN 执行linux的shell命令,一般是安装过程的命令 </p>
<pre class=""><code class="hljs language-bash">RUN tar -zxvf /tmp/jdk17.tar.gz</code></pre>
<p> </p>
<p>EXPOSE 指定容器运行时监听的端口,是给镜像使用者看的</p>
<pre class=""><code class="hljs language-yaml">ESPOSE 8080</code></pre>
<p> </p>
<p>ENTRYPOINT 镜像中应用的启动命令,容器运用时调用</p>
<pre class=""><code class="hljs language-undefined">ENTRYPOINT java -jar xx.jar</code></pre>
<p> </p> |
1 |
37 |
1 |
1/13/26, 12:34 AM |
1/22/26, 10:42 AM |
View Edit Delete |
| 19 |
docker compose 操作 |
<p>docker compose [Options] [command]</p>
<p>Options:</p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>-f<span style="white-space: pre;"> </span>指定compse文件的路径和名称</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>-p 指定project名称</span></p>
<p> </p>
<p>Commands:</p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>up<span style="white-space: pre;"> </span>创建并启动所有service容器</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>down 停止并移除所有容器、网络</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>ps 列出所有启动的容器</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>logs 查看指定的容器日志</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>stop 停止容器</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>start 启动容器</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>restart 重启容器</span></p>
<p><span style="white-space: normal;"><span style="white-space: pre;"> </span>top 查看运行的进程</span></p> |
1 |
37 |
1 |
1/13/26, 12:35 AM |
1/13/26, 12:35 AM |
View Edit Delete |
| 20 |
cakephp5 连ElasticSearch |
<p>1、在es里面先添加好规则</p>
<pre class=""><code class="language-json hljs">{
"mappings":{
"properties":{
"id":{
"type":"keyword"
},
"title":{
"type":"text",
"analyzer":"ik_max_word",
"copy_to":"all"
},
"content":{
"type":"text",
"analyzer":"ik_max_word",
"copy_to":"all"
},
"framework_id":{
"type":"keyword"
},
"framework_name":{
"type":"text",
"analyzer":"ik_max_word",
"copy_to":"all"
},
"published": {
"type": "boolean"
},
"user_id": {
"type": "keyword"
},
"created": {
"type": "date"
},
"modified": {
"type": "date"
},
"all":{
"type":"text",
"analyzer":"ik_max_word"
}
}
}
}</code></pre>
<p> </p>
<p>2、安装ES插件,在项目根目录下执行</p>
<pre class=""><code class="hljs language-bash">composer require cakephp/elastic-search</code></pre>
<p> </p>
<p>3、加载插件,在src/Application.php文件的bootstrap()方法的parent::bootstrap();下面添加</p>
<pre class=""><code class="language-php hljs">$this->addPlugin('Cake/ElasticSearch');</code></pre>
<p> </p>
<p>4、配置ES帐号密码config/app_local.php的Datasources下,添加下面这段话,帐号密码端口自行替换</p>
<pre class=""><code class="language-php hljs"> 'elastic' => [
'className' => 'Cake\ElasticSearch\Datasource\Connection',
'driver' => 'Cake\ElasticSearch\Datasource\Connection',
'hosts' => ['http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201'],
],</code></pre>
<p> </p>
<p>5、在对应的模型层里面,添加afterSave和afterDelete代码,对应字段自行替换</p>
<pre class=""><code class="hljs language-php"> public function afterSave(EventInterface $event, EntityInterface $entity, ArrayObject $options){
try {
// 连接ElasticSearch
$notesIndex = $this->getElasticsearchIndex();
// 定义数据
$data = [
'id' => (string)$entity ->get('id'),
'title' => $entity ->get('title'),
'content' => $entity ->get('content'),
'framework_id' => $entity ->get('framework_id'),
'published' => $entity ->get('published'),
'user_id' => $entity ->get('user_id'),
'created' => $entity ->get('created'),
'modified' => $entity ->get('modified'),
];
if (!$entity->has('framework') && $entity->framework_id) {
// 通过 loadInto 方法加载关联
$entity = $this->loadInto($entity, ['Frameworks']);
}
if ($entity->has('framework') && !empty($entity->framework)) {
$data['framework_name'] = $entity->framework->name;
} else if ($entity->framework_id) {
// 如果关联加载失败,可以直接查询数据库获取框架名
$framework = $this->Frameworks->find()
->select(['name'])
->where(['id' => $entity->framework_id])
->first();
if ($framework) {
$data['framework_name'] = $framework->name;
}
}
// 保存数据
$document = $notesIndex->newEntity($data);
if ($notesIndex->save($document)) {
Log::info("Note ID {$entity->id} 同步到 Elasticsearch 成功");
} else {
Log::error("Note ID {$entity->id} 同步到 Elasticsearch 失败");
}
} catch (Exception $e) {
Log::error("Elasticsearch 同步异常,Note ID: {$entity->id}, 错误: " . $e->getMessage());
}
}
/**
* 在删除笔记后触发,用于从 Elasticsearch 删除文档
*
* @param \Cake\Event\EventInterface $event
* @param \Cake\Datasource\EntityInterface $entity
* @param \ArrayObject $options
* @return void
*/
public function afterDelete(EventInterface $event, EntityInterface $entity, ArrayObject $options)
{
try {
// 连接ElasticSearch
$notesIndex = $this->getElasticsearchIndex();
try {
$document = $notesIndex->get((string)$entity->id);
if ($notesIndex->delete($document)) {
Log::info("ID {$entity->id} 删除成功");
} else {
Log::warning("⚠️ 删除操作返回 false,Note ID: {$entity->id}");
}
} catch (\Cake\Datasource\Exception\RecordNotFoundException $e) {
// 文档不存在,无需删除
Log::debug("Note ID {$entity->id} 在 Elasticsearch 索引中不存在,无需删除");
}
} catch (MissingDocumentException $e) {
Log::debug("Note ID {$entity->id} 在 Elasticsearch 索引中不存在,无需删除");
} catch (Exception $e) {
// 捕获其他所有可能的异常(如连接失败、语法错误等)
Log::error("🔥 从 Elasticsearch 删除文档时发生异常,Note ID: {$entity->id}");
Log::error("错误信息: " . $e->getMessage());
}
}
private function getElasticsearchIndex()
{
// 单例模式,避免重复创建连接
static $notesIndex = null;
if ($notesIndex === null) {
$connection = ConnectionManager::get('elastic');
$notesIndex = new Index([
'connection' => $connection,
'name' => 'notes'
]);
}
return $notesIndex;
}</code></pre>
<p> </p>
<p>6、关于搜索,目前cake官方插件where条件只存在and不能用or。所以自己写了一下。还没优化,先凑活用。</p>
<pre class=""><code class="hljs language-php"> public function search()
{
$this->request->allowMethod(['get']);
$keyword = $this->request->getQuery('q');
$framework_id = $this->request->getQuery('framework_id');
$page = $this->request->getQuery('page', 1);
$limit = $this->request->getQuery('limit', 10);
// 检查Datasources配置
$requestUrl = ConnectionManager::get('elastic')->config()['hosts'][0] . '/notes/_search';
$from = ($page - 1) * $limit;
$query = [
'query' => [
'bool' => [
'must' => [
['term' => ['published' => true]]
]
]
],
'from' => $from,
'size' => $limit,
'sort' => [
[
'created' => [
'order' => 'desc'
]
]
]
];
// 添加搜索条件
if (!empty($framework_id)) {
$query['query']['bool']['must'][] = ['term' => ['framework_id' => $framework_id]];
}
if (!empty($keyword)) {
$query['query']['bool']['must'][] = ['match' => ['all' => $keyword]];
}
// echo "请求体: " . json_encode($query, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "<br>";
// 解析URL获取认证信息
$parsedUrl = parse_url($requestUrl);
// 重新构建不带认证信息的URL
$cleanUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . ':' . $parsedUrl['port'] . $parsedUrl['path'];
// 发送POST请求(CakePHP HttpClient的GET请求不支持请求体)
$http = new Client();
$options = [
'type' => 'json',
'headers' => ['Content-Type' => 'application/json']
];
// 添加认证头部
if (isset($parsedUrl['user']) && isset($parsedUrl['pass'])) {
$auth = base64_encode($parsedUrl['user'] . ':' . $parsedUrl['pass']);
$options['headers']['Authorization'] = 'Basic ' . $auth;
}
// 发送POST请求
$response = $http->post($cleanUrl, json_encode($query), $options);
if ($response->isOk()) {
$data = json_decode($response->getStringBody(),true);
// pr($data);
// 处理响应数据
$notes = [];
$total = $data['hits']['total']['value'] ?? 0;
if (isset($data['hits']['hits'])) {
foreach ($data['hits']['hits'] as $hit) {
$note = $hit['_source'];
$note['id'] = $hit['_id'];
$notes[] = $note;
}
}
// 创建分页数据
$paging = [
'count' => $total,
'current' => count($notes),
'perPage' => $limit,
'page' => $page,
'pages' => $total > 0 ? ceil($total / $limit) : 1,
'prevPage' => $page > 1,
'nextPage' => ($page * $limit) < $total,
'start' => $from + 1,
'end' => min($from + $limit, $total)
];
// 7. 设置视图变量
$this->set(compact('notes', 'paging','page','limit','total'));
$this->viewBuilder()->setOption('serialize', ['notes', 'paging']);
}
}</code></pre>
<p> </p> |
1 |
3 |
1 |
1/13/26, 8:34 AM |
1/22/26, 10:42 AM |
View Edit Delete |
| 21 |
Ubuntu24.04中Nginx 配置vue3项目 |
<p>1、在/etc/nginx/sites-available/中新建一个文件比如timeless</p>
<pre class=""><code class="language-makefile hljs">server {
listen 80;
listen [::]:80;
error_log /var/log/nginx/timeless_error.log;
access_log /var/log/nginx/timeless_access.log;
# 项目路径
root /Projects/Vue3/xxxxx;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name domain.com www.domain.com;
# vue3的项目必须加try_files $uri $uri/ /index.html;
location / {
try_files $uri $uri/ /index.html;
}
# 反向代理,接口转发
location /api/ {
proxy_pass http://xxxx.com/;
}
}
</code></pre>
<p> </p>
<p>2、然后在/etc/nginx/sites-enabled中,把该文件软链过去</p>
<pre class=""><code class="hljs language-bash">ln -s ../sites-available/timeless</code></pre>
<p> </p>
<p>3、重启</p>
<pre class=""><code class="hljs language-undefined">systemctl reload nginx
systemctl restart nginx</code></pre>
<p> </p> |
1 |
34 |
1 |
1/13/26, 8:42 AM |
1/22/26, 10:41 AM |
View Edit Delete |
| 22 |
Ubuntu24.04下 svn的导入导出 |
<p>导出命令</p>
<pre class=""><code class="hljs language-bash">sudo svnadmin dump /svn/sports > /tmp/sports_repo.dump</code></pre>
<p> </p>
<p>导入命令</p>
<pre class=""><code class="hljs language-lua">sudo svnadmin create /svn/sports_new
sudo svnadmin load /svn/sports_new < /path/to/sports_repo.dump</code></pre> |
1 |
34 |
1 |
1/13/26, 9:22 AM |
1/22/26, 10:40 AM |
View Edit Delete |
| 23 |
Ubuntu24.04更换国内源 |
<p>1、切换到下面目录</p>
<pre class=""><code class="language-bash hljs">cd /etc/apt/sources.list.d</code></pre>
<p> </p>
<p>2、修改源文件</p>
<pre class=""><code class="language-bash hljs">sudo vim ubuntu.sources</code></pre>
<p> </p>
<p>3、替换以下清华镜像源,原来的可以删除</p>
<pre class=""><code class="language-makefile hljs">Types: deb
URIs: https://mirrors.ustc.edu.cn/ubuntu/
Suites: noble noble-updates noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: https://mirrors.aliyun.com/ubuntu/
Suites: noble noble-updates noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIs: https://repo.huaweicloud.com/ubuntu/
Suites: noble noble-updates noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
Types: deb
URIS: https://mirrors.tuna.tsinghua.edu.cn/ubuntu/
Suites: noble noble-updates noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg</code></pre>
<p> </p>
<p>4、测试,如果是从镜像源下载的,说明配置成功了</p>
<pre class=""><code class="hljs language-sql">sudo apt update
sudo apt -y upgrade</code></pre>
<p> </p> |
1 |
34 |
1 |
1/13/26, 9:27 AM |
4/16/26, 1:46 PM |
View Edit Delete |
| 24 |
Ubuntu24.04安装ElasticSearch |
<p>1、下载deb文件(默认端口9200、默认只支持https、安装信息中可以看到密码,默认账号elastic)</p>
<pre class=""><code class="hljs language-bash">https://www.elastic.co/downloads/elasticsearch</code></pre>
<p> </p>
<p>2、安装</p>
<pre class=""><code class="language-bash hljs">sudo dpkg -i elasticsearch-9.2.2-amd64.deb</code></pre>
<p> </p>
<p>3、将es添加到开机启动</p>
<pre class=""><code class="hljs language-bash">sudo systemctl enable elasticsearch.service</code></pre>
<p> </p>
<p>4、安装IK分词器</p>
<pre class=""><code class="language-bash hljs">cd /usr/share/elasticsearch
# 版本号写自己的es版本
bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/9.2.2
sudo systemctl restart elasticsearch</code></pre>
<p> </p>
<p>5、从https改为http访问</p>
<pre class=""><code class="language-bash hljs">vim /etc/elasticsearch/elasticsearch.yml</code></pre>
<p> </p>
<pre class=""><code class="language-yaml hljs"># 把true改为false就默认http了
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
</code></pre>
<p> </p>
<pre class=""><code class="language-bash hljs">sudo systemctl restart elasticsearch</code></pre>
<p> </p>
<p><br /><br /></p> |
1 |
34 |
1 |
1/13/26, 10:33 AM |
1/22/26, 10:39 AM |
View Edit Delete |
| 25 |
ElasticSearch基本操作 |
<p>1、创建一个名为note的空索引</p>
<pre class=""><code class="hljs language-bash">PUT
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note</code></pre>
<p> </p>
<p>2、查询一个名为note的索引</p>
<pre class=""><code class="hljs language-bash">GET
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note</code></pre>
<p> </p>
<p>3、删除一个名为note的索引</p>
<pre class=""><code class="hljs language-bash">DELETE
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note</code></pre>
<p> </p>
<p>4、创建note索引映射并指定分词器</p>
<pre class=""><code class="hljs language-css">PUT
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note
{
"mappings":{
"properties":{
"id":{
"type":"keyword"
},
"title":{
"type":"text",
"analyzer":"ik_max_word",
"copy_to":"all"
},
"content":{
"type":"text",
"analyzer":"ik_max_word",
"copy_to":"all"
},
"framework_id":{
"type":"keyword"
},
"framework_name":{
"type":"text",
"analyzer":"ik_max_word",
"copy_to":"all"
},
"published": {
"type": "boolean"
},
"user_id": {
"type": "keyword"
},
"created": {
"type": "date"
},
"modified": {
"type": "date"
},
"all":{
"type":"text",
"analyzer":"ik_max_word"
}
}
}
}</code></pre>
<p> </p>
<p>5、查看索引映射</p>
<pre class=""><code class="hljs language-bash">GET
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note/_mapping</code></pre>
<p> </p>
<p>6、创建文档数据</p>
<pre class=""><code class="hljs language-bash">POST
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note/_doc
{
"title":"今天天气不错4",
"content":"今天天气确实不错4,风和日丽",
"framework_id":1,
"framework_name":"测试数据"
}</code></pre>
<p> </p>
<p>7、自定义id创建note的文档数据</p>
<pre class=""><code class="hljs language-bash">POST
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note/_doc/1
{
"title":"今天天特别气不错",
"content":"这是自定义id创建的天气不错",
"framework_id":1,
"framework_name":"测试数据"
}</code></pre>
<p> </p>
<p>8、根据id修改note的文档数据</p>
<pre class=""><code class="hljs language-bash">POST
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note/_update/1
{
"doc":{
"content":"这是自定义id创建的天气不错2222"
}
}</code></pre>
<p> </p>
<p>9、根据id查询note的文档数据</p>
<pre class=""><code class="hljs language-bash">GET
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note/_doc/1
</code></pre>
<p> </p>
<p>10、根据id删除note的文档数据</p>
<pre class=""><code class="hljs language-bash">DELETE
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note/_doc/c-hgDZsBGizCsGCMESuU
</code></pre>
<p> </p>
<p>11、查询所有note的文档数据</p>
<pre class=""><code class="hljs language-bash">GET
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note/_search
</code></pre>
<p> </p>
<p>12、根据特定条件查询note的文档数据</p>
<pre class=""><code class="hljs language-bash">POST
http://elastic:A3MZa=H5sjtyIyE+7aSr@localhost:9201/note/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"published": true
}
},
{
"term": {
"framework_id": 4
}
},
{
"match": {
"all": "古"
}
}
]
}
},
"size": 20
}</code></pre> |
1 |
30 |
1 |
1/13/26, 1:09 PM |
1/21/26, 2:23 PM |
View Edit Delete |
| 26 |
UniApp使用uni-ui |
<p>1、在uni-app项目中安装uni-ui</p>
<pre class=""><code class="language-bash hljs">npm i @dcloudio/uni-ui</code></pre>
<p> </p>
<p>2、添加配置到page.json里</p>
<pre class=""><code class="language-json hljs"> "easycom": {
"autoscan": true,
"custom": {
// uni-ui 规则如下配置
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
},</code></pre>
<p> </p>
<p>3、导入任意组件(如卡片)</p>
<pre class=""><code class="language-xml hljs"> <view>
<uni-card
title="基础卡片"
sub-title="副标题"
extra="额外信息"
thumbnail="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png"
>
<text class="multiline-ellipsis">这是一个带头像和双标题的基础卡片。</text>
</uni-card>
</view></code></pre>
<p> </p>
<p> </p> |
1 |
22 |
1 |
1/15/26, 12:58 AM |
1/21/26, 2:22 PM |
View Edit Delete |
| 27 |
VS Code添加对UniApp的支持 |
<p>1、搜索插件uni-create-view,作者毛先生,并安装</p>
<p>2、搜索插件uni-helper,作者Uni Helper,并安装</p>
<p>3、搜索插件uniapp小程序扩展,作者evils,并安装</p> |
1 |
22 |
1 |
1/16/26, 4:19 AM |
1/16/26, 4:19 AM |
View Edit Delete |
| 28 |
Ollama安装 |
<p>1、Linux安装(WSL一样)</p>
<pre class=""><code class="hljs language-bash">curl -fsSL https://ollama.com/install.sh | sh</code></pre>
<p> </p>
<p>2、Windows安装</p>
<p>https://ollama.com/download/windows 这个地址先下载好<br />在命令提示符中安装,不然无法更换盘符</p>
<pre class=""><code class="hljs language-bash">.\OllamaSetup.exe /DIR="D:\Ollama"</code></pre>
<p> </p>
<p>设置环境变量</p>
<pre class=""><code class="language-makefile hljs">变量名OLLAMA_MODELS
变量值D:\Ollama\Models
变量名OLLAMA_HOST
变量值0.0.0.0</code></pre>
<p> </p>
<p>重启电脑</p>
<p>安装完成可在命令行查看当前版本</p>
<pre class=""><code class="hljs language-css">ollama --version </code></pre>
<p> </p>
<p>或者在浏览器看是否能访问</p>
<pre class=""><code class="hljs language-bash">http://localhost:11434/</code></pre>
<p> </p> |
1 |
45 |
1 |
1/20/26, 3:19 AM |
5/14/26, 8:27 PM |
View Edit Delete |
| 29 |
Ollama 基本操作 |
<p>1、启动 Ollama 服务</p>
<pre class=""><code class="hljs language-undefined">ollama serve</code></pre>
<p> </p>
<p>2、列出本地模型</p>
<pre class=""><code class="hljs language-undefined">ollama list</code></pre>
<p> </p>
<p>3、拉取模型</p>
<pre class=""><code class="hljs language-xml">ollama pull <model_name></code></pre>
<p> </p>
<p>4、创建模型</p>
<pre class=""><code class="hljs language-xml">ollama create <model_name> -f <Modelfile></code></pre>
<p> </p>
<p>5、查看模型信息</p>
<pre class=""><code class="hljs language-xml">ollama show <model_name></code></pre>
<p> </p>
<p>6、复制模型</p>
<pre class=""><code class="hljs language-xml">ollama cp <source_model> <destination_model></code></pre>
<p> </p>
<p>7、 删除模型</p>
<pre class=""><code class="hljs language-bash">ollama rm <model_name></code></pre>
<p> </p>
<p>8、运行模型</p>
<pre class=""><code class="hljs language-xml">ollama run <model_name></code></pre>
<p> </p>
<p>9、停止运行的模型</p>
<pre class=""><code class="hljs language-xml">ollama stop <model_name></code></pre>
<p> </p>
<p>10、查看正在运行的模型</p>
<pre class=""><code class="hljs language-undefined">ollama ps</code></pre>
<p> </p>
<p>11、查看帮助信息</p>
<pre class=""><code class="hljs language-bash">ollama help</code></pre>
<p> </p>
<p>12、查看版本信息</p>
<pre class=""><code class="hljs language-undefined">ollama -v</code></pre>
<p> </p> |
1 |
45 |
1 |
1/20/26, 3:27 AM |
1/20/26, 3:28 AM |
View Edit Delete |
| 30 |
Python 连接Ollama 并实现最基础的聊天功能 |
<p>1、安装python对ollama的支持</p>
<pre class=""><code class="hljs language-undefined">pip install ollama</code></pre>
<p> </p>
<p>2、连接ollama</p>
<pre class=""><code class="language-python hljs">import ollama
client = ollama.Client(host='http://localhost:11434')</code></pre>
<p> </p>
<p>3、列出可用模型</p>
<pre class=""><code class="language-python hljs">print(client.list())</code></pre>
<p> </p>
<p>4、展示模型的详细信息</p>
<pre class=""><code class="language-python hljs">print(client.show('deepseek-r1:14b'))</code></pre>
<p> </p>
<p>5、列出正在运行的模型</p>
<pre class=""><code class="language-python hljs">print(client.ps())</code></pre>
<p> </p>
<p>6、和模型对话</p>
<pre class=""><code class="language-python hljs">while True:
prompt = input('>>> ')
response = client.chat(
model='deepseek-r1:14b',
messages=[{"role":"user","content":prompt}]
)
print(response['message']['content'])</code></pre>
<p> </p> |
1 |
58 |
1 |
1/21/26, 2:02 PM |
1/21/26, 2:22 PM |
View Edit Delete |
| 31 |
Python 调用streamlit |
<p>1、添加python对streamlit的支持</p>
<pre class=""><code class="language-bash hljs">pip install streamlit</code></pre>
<p> </p>
<p> </p>
<p>2、通过命令行启动streamlit,首次需要输入自己邮箱</p>
<pre class=""><code class="language-bash hljs">streamlit hello</code></pre>
<p> </p>
<p>3、通过python来调用streamlit,创建一个python文件,名字不能用streamlit,会冲突</p>
<pre class=""><code class="language-python hljs">import time
import streamlit as st
# 显示标题
st.title("测试标题")
# write方法,可以在网页中显示你输入的内容
st.write("Hello Timeless")
# 分隔符
st.divider()
# 聊天输入框
name = st.chat_input(">>>请输入姓名:")
if name:
st.write("你好"+name)
# 等待提示框
with st.spinner("思考中"):
time.sleep(5)
st.write("思考完成")
# 消息容器
# 角色支持:user、assistant、ai、human
st.chat_message('user').markdown("你是谁")
st.chat_message('assistant').markdown("我是Timeless")
</code></pre>
<p> </p>
<p>4、不要通过pycharm直接执行这个文件,而是要通过命令行执行</p>
<pre class=""><code class="language-bash hljs">streamlit run streamlit_test.py</code></pre>
<p> </p>
<p>5、执行第四步后,会自动打开网页</p>
<pre class=""><code class="hljs language-bash">http://localhost:8501/mapping_demo</code></pre>
<p> </p> |
1 |
58 |
1 |
1/21/26, 4:27 PM |
1/21/26, 4:39 PM |
View Edit Delete |
| 32 |
Python 利用 streamlit 连接 ollama 实现简单的聊天功能 |
<p>1、创建Python文件,如:chat_demo.py</p>
<pre class=""><code class="language-python hljs">import streamlit as st
import ollama
# 连接ollama
try:
client = ollama.Client(host='http://localhost:11434')
except Exception as e:
st.error(f"连接 Ollama 服务失败,请确保 Ollama 已运行在 11434 端口。错误: {e}")
st.stop()
# 2. 初始化会话状态,用于存储完整的对话历史
if 'message' not in st.session_state:
st.session_state['message'] = []
# 添加标题
st.title("Timeless聊天机器人")
# 分割线
st.divider()
# 提示
prompt = st.chat_input("请输入")
if prompt:
# 将用户提问添加到历史记录中
st.session_state['message'].append({"role": "user", "content": prompt})
# 历史提问保留
for message in st.session_state['message']:
st.chat_message(message['role']).markdown(message['content'])
with st.spinner("思考中"):
response = client.chat(
model="deepseek-r1:14b",
messages=[{"role": "user", "content": prompt}]
)
# 历史回答保留
st.session_state['message'].append({"role": "assistant", "content": response['message']['content']})
# 在页面中渲染AI回答
st.chat_message("assistant").markdown(response['message']['content'])
</code></pre>
<p> </p>
<p>2、运行</p>
<pre class=""><code class="hljs language-undefined">streamlitchat_demo.py</code></pre> |
1 |
58 |
1 |
1/22/26, 10:34 AM |
1/22/26, 10:34 AM |
View Edit Delete |
| 33 |
Python 添加langchian的支持 |
<p>1、安装langchain核心包:</p>
<pre class=""><code class="language-bash hljs">pip install langchain</code></pre>
<p> </p>
<p>2、安装langchain_community社区支持包:</p>
<pre class=""><code class="hljs language-undefined">pip install langchain-community</code></pre>
<p> </p>
<p>3、安装langchain-ollama对ollama的支持包</p>
<pre class=""><code class="hljs language-undefined">pip install langchain-ollama</code></pre>
<p> </p>
<p>4、安装dashscope阿里云通义千问的Python SDK</p>
<pre class=""><code class="hljs language-undefined">pip install dashscope</code></pre>
<p> </p>
<p>5、安装chromadb轻量向量数据库</p>
<pre class=""><code class="hljs language-undefined">pip install chromadb</code></pre>
<p> </p> |
1 |
58 |
1 |
1/22/26, 1:12 PM |
2/17/26, 8:34 PM |
View Edit Delete |
| 34 |
UniApp 添加微信小程序的分享功能 |
<p>1、page.json中在要添加分享的页面的style下面增加两句话</p>
<pre class=""><code class="language-json hljs">"enableShareAppMessage": true,
"enableShareTimeline": true</code></pre>
<p> </p>
<p>2、在对应页面的<script>里添加</p>
<pre class=""><code class="hljs language-xml">// 在 <script setup> 中直接定义分享函数
const onShareAppMessage = (res) => {
if (res.from === 'button') {
console.log(res.target)
}
return {
title: 'title',
path: '/pages/index/index',
}
}
// 如果需要分享到朋友圈
const onShareTimeline = () => {
return {
title: 'title',
query: `q=${searchKeyword.value}`
}
}
// 在onLoad中启用分享菜单
onLoad(() => {
// 显示转发按钮
uni.showShareMenu({
withShareTicket: true,
// 如果需要分享到朋友圈,添加以下配置
// #ifdef MP-WEIXIN
menus: ['shareAppMessage', 'shareTimeline']
// #endif
})
})</code></pre> |
1 |
22 |
1 |
1/24/26, 2:04 AM |
1/24/26, 9:55 AM |
View Edit Delete |
| 35 |
激活函数介绍 |
<p> 激活函数的目的:</p>
<p> 给模型增加非线性功能, 让模型(神经元)既可以做分类, 还可以做回归问题.</p>
<p> 激活函数的分类:</p>
<p> Sigmoid:</p>
<p> ReLU:</p>
<p> Tanh:</p>
<p> Softmax:</p>
<p> </p>
<p> Sigmoid激活函数:</p>
<p> 主要应用于 二分类的输出层, 且适用于 浅层神经网络(不超过5层).</p>
<p> 数据在 [-6, 6]之间有效果, 在[-3, 3]之间效果明显, 会将数据值映射到: [0, 1]</p>
<p> 求导后范围在 [0, 0.25]</p>
<p> </p>
<p> Tanh:</p>
<p> 主要应用于 隐藏层, 且适用于 浅层神经网络(不超过5层).</p>
<p> 数据在 [-3, 3]之间有效果, 在[-1, 1]之间效果明显, 会将数据值映射到: [-1, 1]</p>
<p> 求导后范围在 [0, 1], 较之于Sigmoid, 收敛速度快.</p>
<p> </p>
<p> ReLU:</p>
<p> 计算公式为: max(0, x), 计算量相对较小, 训练成本低. 多应用于 隐藏层, 且适合 深层神经网络.</p>
<p> 求导后, 值要么是0, 要么是1, 较之于Tanh, 收敛速度更快.</p>
<p> 默认情况下ReLU只考虑 正样本, 可以使用LeakyReLU, PReLU 来考虑 正负样本.</p>
<p> </p>
<p> </p>
<p> Softmax:</p>
<p> 将多分类的结果以概率的形式展示, 且概率和相加为1, 最终选取概率值最大的分类 作为最终结果.</p>
<p> </p>
<p>记忆: 如何选择激活函数</p>
<p> 隐藏层:</p>
<p> ReLU > Leaky ReLU > PReLU > Tanh > Sigmoid</p>
<p> 输出层:</p>
<p> 二分类: Sigmoid</p>
<p> 多分类: Softmax</p>
<p> 回归问题: identity</p> |
1 |
1 |
1 |
1/31/26, 6:01 PM |
1/31/26, 6:01 PM |
View Edit Delete |
| 36 |
Pytorch神经网络参数初始化方式 |
<p>参数初始化的目的:</p>
<p> 1. 防止梯度消失 或者 梯度爆炸.</p>
<p> 2. 提高收敛速度.</p>
<p> 3. 打破对称性.</p>
<p> </p>
<p>参数初始化的方式:</p>
<p> 无法打破对称性的:</p>
<p> 全0, 全1, 固定值</p>
<p> 可以打破对称性的:</p>
<p> 随机初始化, 正态分布初始化, kaiming初始化, xavier初始化</p>
<p> </p>
<p>总结:</p>
<p> 1. 记忆 kaiming初始化, xavier初始化, 全0初始化.</p>
<p> 2. 关于初始化的选择上:</p>
<p> 激活函数ReLU及其系列: 优先用 kaiming</p>
<p> 激活函数非ReLU: 优先用 xavier</p>
<p> 如果是浅层网络: 可以考虑使用 随机初始化</p>
<pre class=""><code class="language-python hljs"># 导包
import torch.nn as nn # neural network: 神经网络
import torch.nn as nn
# 1. 均匀分布随机初始化
def dm01():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行随机初始化, 从0-1均匀分布产生参数
nn.init.uniform_(linear.weight)
# 3. 对偏置(b)进行随机初始化, 从0-1均匀分布产生参数
nn.init.uniform_(linear.bias)
# 4. 打印生成结果.
print(linear.weight.data)
print(linear.bias.data)
# 2. 固定初始化
def dm02():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 设置固定值为: 3
nn.init.constant_(linear.weight, 3)
# 3. 对偏置(b)进行初始化, 设置固定值为: 3
nn.init.constant_(linear.bias, 3)
# 4. 打印生成结果.
print(linear.weight.data)
print(linear.bias.data)
# 3. 全0初始化
def dm03():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 全0初始化
nn.init.zeros_(linear.weight)
# 3. 对偏置(b)进行初始化, 全0初始化
nn.init.zeros_(linear.bias)
# 4. 打印生成结果.
print(linear.weight.data)
print(linear.bias.data)
# 4. 全1初始化
def dm04():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 全1初始化
nn.init.ones_(linear.weight)
# 3. 打印生成结果.
print(linear.weight.data)
# 5. 正态分布随机初始化
def dm05():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 正态分布初始化(均值为0, 标准差为1)
nn.init.normal_(linear.weight)
# 3. 打印生成结果.
print(linear.weight.data)
# 6. kaiming 初始化
def dm06():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 正态分布初始化(均值为0, 标准差为1)
# kaiming 正态分布初始化
# nn.init.kaiming_normal_(linear.weight)
# kaiming 均匀分布初始化
nn.init.kaiming_uniform_(linear.weight)
# 3. 打印生成结果.
print(linear.weight.data)
# 7. xavier 初始化
def dm07():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 正态分布初始化(均值为0, 标准差为1)
# xavier 正态分布初始化
# nn.init.xavier_normal_(linear.weight)
# xavier 均匀分布初始化
nn.init.xavier_uniform_(linear.weight)
# 3. 打印生成结果.
print(linear.weight.data)
# 测试
if __name__ == '__main__':
# dm01() # 均匀分布随机初始化
# dm02() # 固定初始化
# dm03() # 全0初始化
# dm04() # 全1初始化
# dm05() # 正态分布
# dm06() # kaiming初始化
dm07() # xavier初始化</code></pre> |
1 |
1 |
1 |
2/1/26, 8:05 AM |
2/4/26, 3:33 PM |
View Edit Delete |
| 37 |
Pytorch常用损失函数 |
<p>损失函数介绍:</p>
<p> 概述:</p>
<p> 损失函数也叫成本函数, 目标函数, 代价函数, 误差函数, 就是用来衡量 模型好坏(模型拟合情况)的.</p>
<p> 分类:</p>
<p> 分类问题:</p>
<p> <strong>多分类交叉熵损失: CrossEntropyLoss </strong>【实际情况可替代BCELoss】</p>
<p> 二分类交叉熵损失: BCELoss</p>
<p> 回归问题:</p>
<p> MAE: Mean Absolute Error, 平均绝对误差.</p>
<p> MSE: Mean Squared Error, 均方误差.</p>
<p> <strong> Smooth L1: 结合上述两个的特点做的升级, 优化.</strong>【实际情况可替代MAE和MSE】</p>
<p> </p>
<p>多分类交叉熵损失: CrossEntropyLoss</p>
<p> 设计思路:</p>
<p> Loss = - Σylog(S(f(x)))</p>
<p> 简单记忆:</p>
<p> x: 样本</p>
<p> f(x): 加权求和</p>
<p> S(f(x)): 处理后的概率</p>
<p> y: 样本x属于某一个类别的 真实概率.</p>
<p> 大白话解释:</p>
<p> 损失函数结果 = 最小化 正确类别所对应的 预测概率的对数的 负值(损失值最小)...</p>
<p> 细节:</p>
<p> CrossEntropyLoss = Softmax() + 损失计算, 后续如果用这个损失函数, 则: 输出层就不用额外调用 softmax()激活函数了.</p>
<pre class=""><code class="language-python hljs"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 演示: 多分类交叉熵损失.
def dm01():
# 1. 手动创建样本的真实值 -> 就是上述公式中的 y
y_true = torch.tensor([[0, 1, 0], [1, 0, 0]], dtype=torch.float)
# y_true = torch.tensor([1, 2])
# 2. 手动创建样本的预测值 -> 就是上述公式中的 f(x)
y_pred = torch.tensor([[0.1, 0.8, 0.1], [0.7, 0.2, 0.1]], requires_grad=True, dtype=torch.float)
# 3. 创建多分类交叉熵损失函数.
criterion = nn.CrossEntropyLoss() # 平均损失, 来源于参数: reduction: str = "mean",
# 4. 计算损失值.
loss = criterion(y_pred, y_true)
print(f'损失值: {loss}')
# 2. 测试
if __name__ == '__main__':
dm01()</code></pre>
<p> </p>
<p>二分类任务的损失函数(BCELoss):</p>
<p> 公式:</p>
<p> Loss = -ylog(预测值) - (1 - y)log(1 - 预测值)</p>
<p> 细节:</p>
<p> 因为公式中没有包含Sigmoid激活函数, 所以使用BCELoss的时候, 还需要手动指定 Sigmoid.</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 演示: 二分类任务的损失函数.
def dm01():
# 1. 设置真实值.
y_true = torch.tensor([0, 1, 0], dtype=torch.float)
# 2. 设置预测值(概率)
y_pred = torch.tensor([0.6901, 0.5423, 0.2639])
# 3. 创建二分类交叉熵损失函数.
criterion = nn.BCELoss() # reduction: str = "mean" -> 均值
# 4. 计算损失值.
loss = criterion(y_pred, y_true)
print(f'损失值: {loss}')
# 2. 测试
if __name__ == '__main__':
dm01()</code></pre>
<p> </p>
<p>回归任务常用损失函数如下:</p>
<p> MAE: Mean Absolute Error, 平均绝对误差.</p>
<p> 公式:</p>
<p> 误差绝对值之和 / 样本总数</p>
<p> 类似于L1正则化, 权重可以降维0, 数据会变得稀疏.</p>
<p> </p>
<p> 弊端:</p>
<p> 在0点不平滑, 可能错过最小值.</p>
<p> </p>
<p> MSE: Mean Squared Error, 均方误差.</p>
<p> 公式:</p>
<p> 误差平方之和 / 样本总数</p>
<p> 弊端:</p>
<p> 如果差值过大, 可能存在梯度爆炸的情况.</p>
<p> </p>
<p> Smooth L1:</p>
<p> 就是基于MAE 和 MSE做的综合, 在 [-1, 1]是 L2(MSE), 其它段时L1.</p>
<p> 这样即解决了L1不平滑的问题(0点不可导, 可能错过最小值)</p>
<p> 又解决了L2(MSE)的 梯度爆炸的问题.</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 演示: MAE 损失函数.
def dm01():
# 1. 定义变量, 记录: 真实值.
y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)
# 2. 定义变量, 记录: 预测值.
y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)
# 3. 创建MAE损失函数对象.
criterion = nn.L1Loss()
# 4. 计算损失.
loss = criterion(y_pred, y_true)
# 5. 输出损失.
print(f'MAE: {loss}')
# 2. 定义函数, 演示: MSE 损失函数.
def dm02():
# 1. 定义变量, 记录: 真实值.
y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)
# 2. 定义变量, 记录: 预测值.
y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)
# 3. 创建MSE损失函数对象.
criterion = nn.MSELoss()
# 4. 计算损失.
loss = criterion(y_pred, y_true)
# 5. 输出损失.
print(f'MSE: {loss}')
# 3. 定义函数, 演示: Smooth L1 损失函数.
def dm03():
# 1. 定义变量, 记录: 真实值.
y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)
# 2. 定义变量, 记录: 预测值.
y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)
# 3. 创建Smooth L1损失函数对象.
criterion = nn.SmoothL1Loss()
# 4. 计算损失.
loss = criterion(y_pred, y_true)
# 5. 输出损失.
print(f'Smooth L1: {loss}')
# 4. 测试
if __name__ == '__main__':
# dm01() # 0.699999988079071
# dm02() # 0.6700000166893005
dm03() # 0.33500000834465027</code></pre> |
1 |
1 |
1 |
2/2/26, 3:48 AM |
2/4/26, 3:33 PM |
View Edit Delete |
| 38 |
导数计算 |
<p><strong>幂函数求导</strong><br />公式:<img src="data:image/png;base64,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" alt="" /></p>
<p>例如 :x<sup>2</sup>; 求导则等于2x<br /><br /></p>
<p><strong>复合函数求导<br /></strong>公式:<img src="data:image/png;base64,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" alt="" /></p>
<p>例如:(3-x)<sup>2</sup>求导</p>
<p>要算要外层乘以内层,</p>
<p>设内层 3-x 等于 u</p>
<p>然后外层u<sup>2</sup>对u求导 、内层u对x求导,并相乘</p>
<p>得出外层2u = 2(3-x) 和 内层(0-1) = -1 相乘</p>
<p>得到2x-6</p> |
1 |
1 |
1 |
2/3/26, 7:36 PM |
2/4/26, 4:48 AM |
View Edit Delete |
| 39 |
Pytorch常用优化器 |
<p>梯度下降相关介绍:</p>
<p> 概述:</p>
<p> 梯度下降是结合 本次损失函数的导数(作为梯度) 基于学习率 来更新权重的.</p>
<p> 公式:</p>
<p> W新 = W旧 - 学习率 * (本次的)梯度</p>
<p> 存在的问题:</p>
<p> 1. 遇到平缓区域, 梯度下降(权重更新)可能会慢.</p>
<p> 2. 可能会遇到 鞍点(梯度为0)</p>
<p> 3. 可能会遇到 局部最小值.</p>
<p> 解决思路:</p>
<p> 从上述的 学习率 或者 梯度入手, 进行优化, 于是有了: 动量法Momentum, 自适应学习率AdaGrad, RMSProp, 综合衡量: Adam</p>
<p> </p>
<p> 动量法Momentum:</p>
<p> 动量法公式:</p>
<p> St = β * St-1 + (1 - β) * Gt</p>
<p> 解释:</p>
<p> St: 本次的指数移动加权平均结果.</p>
<p> β: 调节权重系数, 越大, 数据越平缓, 历史指数移动加权平均 比重越大, 本次梯度权重越小.</p>
<p> St-1: 历史的指数移动加权平均结果.</p>
<p> Gt: 本次计算出的梯度(不考虑历史梯度).</p>
<p> 加入动量法后的 梯度更新公式:</p>
<p> W新 = W旧 - 学习率 * St</p>
<p> </p>
<p> 自适应学习率: AdaGrad(Adaptive Gradient Estimation)</p>
<p> 公式:</p>
<p> 累计平方梯度:</p>
<p> St = St-1 + Gt * Gt</p>
<p> 解释:</p>
<p> St: 累计平方梯度</p>
<p> St-1: 历史累计平方梯度.</p>
<p> Gt: 本次的梯度.</p>
<p> 学习率:</p>
<p> 学习率 = 学习率 / (sqrt(St) + 小常数)</p>
<p> 解释:</p>
<p> 小常数: 1e-10, 目的: 防止分母变为0</p>
<p> 梯度下降公式:</p>
<p> W新 = W旧 - 调整后的学习率 * Gt</p>
<p> 缺点:</p>
<p> 可能会导致学习率过早, 过量的降低, 导致模型后期学习率太小, 较难找到最优解.</p>
<p> </p>
<p> </p>
<p> 自适应学习率: RMSProp(Root Mean Square Propagation) -> 可以看做是 对AdaGrad做的优化, 加入 调和权重系数.</p>
<p> 公式:</p>
<p> 指数加权平均 累计历史平方梯度:</p>
<p> St = β * St-1 + (1 - β) * Gt * Gt</p>
<p> 解释:</p>
<p> St: 累计平方梯度</p>
<p> St-1: 历史累计平方梯度.</p>
<p> Gt: 本次的梯度.</p>
<p> β: 调和权重系数.</p>
<p> 学习率:</p>
<p> 学习率 = 学习率 / (sqrt(St) + 小常数)</p>
<p> 解释:</p>
<p> 小常数: 1e-10, 目的: 防止分母变为0</p>
<p> 梯度下降公式:</p>
<p> W新 = W旧 - 调整后的学习率 * Gt</p>
<p> 优点:</p>
<p> RMSProp通过引入 衰减系数β, 控制历史梯度 对 历史梯度信息获取的多少.</p>
<p> </p>
<p> 自适应矩估计: Adam(Adaptive Moment Estimation)</p>
<p> 思路:</p>
<p> 即优化学习率, 又优化梯度.</p>
<p> 公式:</p>
<p> 一阶矩: 算均值.</p>
<p> Mt = β1 * Mt-1 + (1 - β1) * Gt 充当: 梯度</p>
<p> St = β2 * St-1 + (1 - β2) * Gt * Gt 充当: 学习率</p>
<p> 二阶矩: 梯度的方差.</p>
<p> Mt^ = Mt / (1 - β1 ^ t)</p>
<p> St^ = St / (1 - β2 ^ t)</p>
<p> 权重更新公式:</p>
<p> W新 = W旧 - 学习率 / (sqrt(St^) + 小常数) * Mt^</p>
<p> 大白话翻译:</p>
<p> Adam = RMSProp + Momentum</p>
<p> </p>
<p>总结: 如何选择梯度下降优化方法</p>
<p> 简单任务和较小的模型:</p>
<p> SGD, 动量法</p>
<p> 复杂任务或者有大量数据:</p>
<p> Adam</p>
<p> 需要处理稀疏数据或者文本数据:</p>
<p> AdaGrad, RMSProp</p>
<pre class=""><code class="language-python hljs"># 导包
import torch
import torch.nn as nn
import torch.optim as optim
# 1. 定义函数, 演示: 梯度下降优化方法 -> 动量法(Momentum)
def dm01_momentum():
# 1. 初始化权重参数.
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 2. 定义损失函数
criterion = ((w ** 2) / 2.0)
# 3. 创建优化器(函数对象) -> 基于SGD(随机梯度下降), 加入参数 momentum, 就是 动量法.
# 参1: (待优化的)参数列表, 参2: 学习率, 参3: 动量参数.
optimizer = optim.SGD(params=[w], lr=0.01, momentum=0.9) # 细节: momentum=0(默认), 只考虑: 本次梯度.
# 4. 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
print(f'w: {w}, w.grad: {w.grad}')
# 5.重复上述的步骤, 第2次 更新权重参数.
# 5.1 定义损失函数.
criterion = ((w ** 2) / 2.0)
# 5.2 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
# 5.3 打印结果.
print(f'w: {w}, w.grad: {w.grad}')
# 2. 定义函数, 演示: 梯度下降优化方法 -> 自适应学习率(AdaGrad)
def dm02_adagrad():
# 1. 初始化权重参数.
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 2. 定义损失函数
criterion = ((w ** 2) / 2.0)
# 3. 创建优化器(函数对象)
# 思路1: 基于SGD(随机梯度下降), 加入参数 momentum, 就是 动量法.
# 参1: (待优化的)参数列表, 参2: 学习率, 参3: 动量参数.
# optimizer = optim.SGD(params=[w], lr=0.01, momentum=0.9) # 细节: momentum=0(默认), 只考虑: 本次梯度.
# 思路2: 基于AdaGrad(自适应学习率).
optimizer = optim.Adagrad(params=[w], lr=0.01)
# 4. 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
print(f'w: {w}, w.grad: {w.grad}')
# 5.重复上述的步骤, 第2次 更新权重参数.
# 5.1 定义损失函数.
criterion = ((w ** 2) / 2.0)
# 5.2 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
# 5.3 打印结果.
print(f'w: {w}, w.grad: {w.grad}')
# 3. 定义函数, 演示: 梯度下降优化方法 -> 自适应学习率(RMSProp)
def dm03_rmsprop():
# 1. 初始化权重参数.
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 2. 定义损失函数
criterion = ((w ** 2) / 2.0)
# 3. 创建优化器(函数对象)
# 思路1: 基于SGD(随机梯度下降), 加入参数 momentum, 就是 动量法.
# 参1: (待优化的)参数列表, 参2: 学习率, 参3: 动量参数.
# optimizer = optim.SGD(params=[w], lr=0.01, momentum=0.9) # 细节: momentum=0(默认), 只考虑: 本次梯度.
# 思路2: 基于AdaGrad(自适应学习率).
# optimizer = optim.Adagrad(params=[w], lr=0.01)
# 思路3: 基于RMSProp(自适应学习率).
optimizer = optim.RMSprop(params=[w], lr=0.01, alpha=0.99)
# 4. 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
print(f'w: {w}, w.grad: {w.grad}')
# 5.重复上述的步骤, 第2次 更新权重参数.
# 5.1 定义损失函数.
criterion = ((w ** 2) / 2.0)
# 5.2 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
# 5.3 打印结果.
print(f'w: {w}, w.grad: {w.grad}')
# 4. 定义函数, 演示: 梯度下降优化方法 -> 自适应矩估计(Adam)
def dm04_adam():
# 1. 初始化权重参数.
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 2. 定义损失函数
criterion = ((w ** 2) / 2.0)
# 3. 创建优化器(函数对象)
# 思路1: 基于SGD(随机梯度下降), 加入参数 momentum, 就是 动量法.
# 参1: (待优化的)参数列表, 参2: 学习率, 参3: 动量参数.
# optimizer = optim.SGD(params=[w], lr=0.01, momentum=0.9) # 细节: momentum=0(默认), 只考虑: 本次梯度.
# 思路2: 基于AdaGrad(自适应学习率).
# optimizer = optim.Adagrad(params=[w], lr=0.01)
# 思路3: 基于RMSProp(自适应学习率).
# optimizer = optim.RMSprop(params=[w], lr=0.01, alpha=0.99)
# 思路4: 基于Adam(自适应矩估计).
optimizer = optim.Adam(params=[w], lr=0.01, betas=(0.9, 0.999)) # betas=(梯度用的 衰减系数, 学习率用的 衰减系数)
# 4. 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
print(f'w: {w}, w.grad: {w.grad}')
# 5.重复上述的步骤, 第2次 更新权重参数.
# 5.1 定义损失函数.
criterion = ((w ** 2) / 2.0)
# 5.2 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
# 5.3 打印结果.
print(f'w: {w}, w.grad: {w.grad}')
# 5. 测试
if __name__ == '__main__':
dm01_momentum()
# dm02_adagrad()
# dm03_rmsprop()
# dm04_adam()</code></pre> |
1 |
1 |
1 |
2/4/26, 2:20 PM |
2/4/26, 3:33 PM |
View Edit Delete |
| 40 |
Pytorch手动调整学习率衰减间隔 |
<p>学习率衰减策略介绍:</p>
<p> 目的:</p>
<p> 较之于AdaGrad, RMSProp, Adam方式, 我们可以通过 等间隔, 指定间隔, 指数等方式, 来手动控制学习率的调整.</p>
<p> </p>
<p> 分类:</p>
<p> 等间隔学习率衰减</p>
<p> 指定间隔学习率衰减</p>
<p> 指数学习率衰减</p>
<p> </p>
<p>等间隔学习率衰减:</p>
<p> step_size: 间隔的轮数, 即: 多少轮调整一次学习率.</p>
<p> gamma: 学习率衰减系数, 即: lr新 = lr旧 * gamma</p>
<p> </p>
<p>指定间隔学习率衰减:</p>
<p> milestones = [50, 125, 160] 里边定义的是要调整学习率的 轮数.</p>
<p> gamma: 学习率衰减系数, 即: lr新 = lr旧 * gamma</p>
<p> </p>
<p>指数间隔学习率衰减:</p>
<p> 前期学习率衰减快, 中期慢, 后期更慢, 更符合梯度下降规律.</p>
<p> 公式:</p>
<p> lr新 = lr旧 * gamma ** epoch</p>
<p> </p>
<p>总结:</p>
<p> 等间隔学习率衰减:</p>
<p> 优点:</p>
<p> 直观, 易于调试, 适用于 大批量数据.</p>
<p> 缺点:</p>
<p> 学习率变化较大, 可能跳过最优解.</p>
<p> 应用场景:</p>
<p> 大型数据集, 较为简单的任务.</p>
<p> </p>
<p> 指定间学习率衰减:</p>
<p> 优点:</p>
<p> 易于调试, 稳定训练过程.</p>
<p> 缺点:</p>
<p> 在某些情况下可能衰减过快, 导致优化提前停滞.</p>
<p> 应用场景:</p>
<p> 对训练平稳性要求较高的任务.</p>
<p> 指数学习率衰减:</p>
<p> 优点:</p>
<p> 平滑, 且考虑历史更新, 收敛稳定性较强.</p>
<p> 缺点:</p>
<p> 超参调节较为复杂, 可能需要更多的资源.</p>
<p> 应用场景:</p>
<p> 高精度训练, 避免过快收敛.</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
from torch import optim
import matplotlib.pyplot as plt
# 1. 定义函数, 演示: 等间隔学习率衰减
def dm01():
# 1. 定义变量, 记录初始的 学习率, 训练的轮数, 每轮训练的批次数.
lr, epochs, iteration = 0.1, 200, 10
# 2. 创建数据集. y_true, x, w
# 真实值.
y_true = torch.tensor([0])
# 输入特征
x = torch.tensor([1.0], dtype=torch.float32)
# 权重参数w, 需要自动微分(求导)
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 3. 创建优化器对象, 动量法 -> 加速模型的收敛, 减少震荡.
# 参1: 待优化的参数, 参2: 学习率, 参3: 动量系数
optimizer = optim.SGD([w], lr=lr, momentum=0.9)
# 4. 创建学习率衰减对象.
# 思路1: 创建等间隔学习率衰减对象.
# 参1: 优化器对象, 参2: 间隔的轮数(多少轮调整一次学习率), 参3: 学习率衰减系数.
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5) # [0.1, 0.1, 0.1... 0.05...]
# 5. 创建两个列表, 分别表示: 训练轮数, 每轮训练用的学习率
# epoch_list = [0, 1, 2, 3.... 50, 51, 52...100, 101, 101... 150, 151...199]
# lr_list = [0.1, 0.1, 0.1, 0.05........,0.025........., 0.0125...]
lr_list, epoch_list = [], []
# 6. 循环遍历训练轮数, 进行具体的训练.
for epoch in range(epochs): # epoch: 0 ~ 199
# 7. 获取当前轮数 和 学习率, 并保存到列表中.
epoch_list.append(epoch)
lr_list.append(scheduler.get_last_lr()) # 获取最后的lr(learning rate, 学习率)
# 8. 循环遍历, 每轮每批次进行训练.
for batch in range(iteration):
# 9. 先计算预测值, 然后基于损失函数计算损失.
y_pred = w * x
# 10. 计算损失, 最小二乘法.
loss = (y_pred - y_true) ** 2
# 11. 梯度清零 + 反向传播 + 优化器更新参数.
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 12. 更新学习率.
scheduler.step()
# 13. 打印结果:
print(f'lr_list: {lr_list}') # [0.1, 0.1, 0.1..., 0.05........,0.025........., 0.0125...]
# 14. 可视化.
# x轴: 训练的轮数, y轴: 每轮训练用的学习率
plt.plot(epoch_list, lr_list)
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.show()
# 2. 定义函数, 演示: 指定间隔学习率衰减
def dm02():
# 1. 定义变量, 记录初始的 学习率, 训练的轮数, 每轮训练的批次数.
lr, epochs, iteration = 0.1, 200, 10
# 2. 创建数据集. y_true, x, w
# 真实值.
y_true = torch.tensor([0])
# 输入特征
x = torch.tensor([1.0], dtype=torch.float32)
# 权重参数w, 需要自动微分(求导)
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 3. 创建优化器对象, 动量法 -> 加速模型的收敛, 减少震荡.
# 参1: 待优化的参数, 参2: 学习率, 参3: 动量系数
optimizer = optim.SGD([w], lr=lr, momentum=0.9)
# 4. 创建学习率衰减对象.
# 思路1: 创建等间隔学习率衰减对象.
# 参1: 优化器对象, 参2: 间隔的轮数(多少轮调整一次学习率), 参3: 学习率衰减系数.
# scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5) # [0.1, 0.1, 0.1... 0.05...]
# 思路2: 创建指定间隔学习率衰减对象.
# 定义变量, 记录要修改学习率的轮数.
milestones = [50, 125, 160]
scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=milestones, gamma=0.5)
# 5. 创建两个列表, 分别表示: 训练轮数, 每轮训练用的学习率
# epoch_list = [0, 1, 2, 3.... 50, 51, 52...100, 101, 101... 150, 151...199]
# lr_list = [0.1, 0.1, 0.1, 0.05........,0.025........., 0.0125...]
lr_list, epoch_list = [], []
# 6. 循环遍历训练轮数, 进行具体的训练.
for epoch in range(epochs): # epoch: 0 ~ 199
# 7. 获取当前轮数 和 学习率, 并保存到列表中.
epoch_list.append(epoch)
lr_list.append(scheduler.get_last_lr()) # 获取最后的lr(learning rate, 学习率)
# 8. 循环遍历, 每轮每批次进行训练.
for batch in range(iteration):
# 9. 先计算预测值, 然后基于损失函数计算损失.
y_pred = w * x
# 10. 计算损失, 最小二乘法.
loss = (y_pred - y_true) ** 2
# 11. 梯度清零 + 反向传播 + 优化器更新参数.
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 12. 更新学习率.
scheduler.step()
# 13. 打印结果:
print(f'lr_list: {lr_list}') # [0.1, 0.1, 0.1..., 0.05........,0.025........., 0.0125...]
# 14. 可视化.
# x轴: 训练的轮数, y轴: 每轮训练用的学习率
plt.plot(epoch_list, lr_list)
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.show()
# 3. 定义函数, 演示: 指数学习率衰减
def dm03():
# 1. 定义变量, 记录初始的 学习率, 训练的轮数, 每轮训练的批次数.
lr, epochs, iteration = 0.1, 200, 10
# 2. 创建数据集. y_true, x, w
# 真实值.
y_true = torch.tensor([0])
# 输入特征
x = torch.tensor([1.0], dtype=torch.float32)
# 权重参数w, 需要自动微分(求导)
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 3. 创建优化器对象, 动量法 -> 加速模型的收敛, 减少震荡.
# 参1: 待优化的参数, 参2: 学习率, 参3: 动量系数
optimizer = optim.SGD([w], lr=lr, momentum=0.9)
# 4. 创建学习率衰减对象.
# 思路1: 创建等间隔学习率衰减对象.
# 参1: 优化器对象, 参2: 间隔的轮数(多少轮调整一次学习率), 参3: 学习率衰减系数.
# scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5) # [0.1, 0.1, 0.1... 0.05...]
# 思路2: 创建指定间隔学习率衰减对象.
# 定义变量, 记录要修改学习率的轮数.
# milestones = [50, 125, 160]
# scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=milestones, gamma=0.5)
# 思路3: 创建指数学习率衰减对象.
scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95)
# 5. 创建两个列表, 分别表示: 训练轮数, 每轮训练用的学习率
# epoch_list = [0, 1, 2, 3.... 50, 51, 52...100, 101, 101... 150, 151...199]
# lr_list = [0.1, 0.1, 0.1, 0.05........,0.025........., 0.0125...]
lr_list, epoch_list = [], []
# 6. 循环遍历训练轮数, 进行具体的训练.
for epoch in range(epochs): # epoch: 0 ~ 199
# 7. 获取当前轮数 和 学习率, 并保存到列表中.
epoch_list.append(epoch)
lr_list.append(scheduler.get_last_lr()) # 获取最后的lr(learning rate, 学习率)
# 8. 循环遍历, 每轮每批次进行训练.
for batch in range(iteration):
# 9. 先计算预测值, 然后基于损失函数计算损失.
y_pred = w * x
# 10. 计算损失, 最小二乘法.
loss = (y_pred - y_true) ** 2
# 11. 梯度清零 + 反向传播 + 优化器更新参数.
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 12. 更新学习率.
scheduler.step()
# 13. 打印结果:
print(f'lr_list: {lr_list}') # [0.1, 0.1, 0.1..., 0.05........,0.025........., 0.0125...]
# 14. 可视化.
# x轴: 训练的轮数, y轴: 每轮训练用的学习率
plt.plot(epoch_list, lr_list)
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.show()
# 4. 测试
if __name__ == '__main__':
# dm01()
# dm02()
dm03()</code></pre> |
1 |
1 |
1 |
2/4/26, 3:32 PM |
2/4/26, 3:32 PM |
View Edit Delete |
| 41 |
Pytorch正则化 |
<p>正则化的作用:</p>
<p> 缓解模型的过拟合情况.</p>
<p>正则化的方式:</p>
<p> L1正则化: 权重可以变为0, 相当于: 降维.</p>
<p> L2正则化: 权重可以无限接近0</p>
<p> DropOut: 随机失活, 每批次样本训练时, 随机让一部分神经元死亡, 防止一些特征对结果的影响较大(防止过拟合)</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 演示: 随机失活(DropOut)
def dm01():
# 1. 创建隐藏层输出结果.
t1 = torch.randint(0, 10, size=(1, 4)).float()
print(f't1: {t1}') # t1: tensor([[0., 5., 6., 3.]])
# 2. 进行下一层 加权求和 和 激活函数计算.
# 2.1 创建全连接层(充当线性层)
# 参1: 输入特征维度, 参2: 输出特征维度.
linear1 = nn.Linear(4, 5)
# 2.2 加权求和.
l1 = linear1(t1)
print(f'l1: {l1}')
# 2.3 激活函数.
output = torch.relu(l1)
print(f'output: {output}')
# 3. 对激活值进行随机失活dropout处理 -> 只有训练阶段有, 测试阶段没有.
dropout = nn.Dropout(p=0.5) # 每个神经元都有50%的概率被 kill.
# 具体的 随机失活动作.
d1 = dropout(output)
print(f'd1(随机失活后的数据): {d1}') # 未被失活的进行缩放, 缩放比例为: 1 / (1 - p) = 2
# 2. 测试
if __name__ == '__main__':
dm01()</code></pre>
<p> BN(批量归一化): 先对数据做标准化(会丢失一些信息), 然后再对数据做 缩放(λ, 理解为: w权重) 和 平移(β, 理解为: b偏置), 再找补回一些信息.</p>
<p> BatchNorm1d:主要应用于全连接层或处理一维数据的网络,例如文本处理。它接收形状为 (N, num_features) 的张量作为输入。</p>
<p> BatchNorm2d:主要应用于卷积神经网络,处理二维图像数据或特征图。它接收形状为 (N, C, H, W) 的张量作为输入。</p>
<p> BatchNorm3d:主要用于三维卷积神经网络 (3D CNN),处理三维数据,例如视频或医学图像。它接收形状为 (N, C, D, H, W) 的张量作为输入。</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 处理 二维数据.
def dm01():
# 1. 创建图像样本数据.
# 1张图片, 2个通道, 3行4列(像素点)
input_2d = torch.randn(size=(1, 2, 3, 4))
print(f'input_2d: {input_2d}')
# 2. 创建批量归一化层(BN层)
# 参1: 输入特征数 = 图片的通道数.
# 参2: 噪声值(小常数), 默认为1e-5.
# 参3: 动量值, 用于计算移动平局统计量的 动量值.
# 参4: 表示使用可学习的变换参数(λ, β) 对归一化(标准化)后的数据进行 缩放和平移.
bn2d = nn.BatchNorm2d(num_features=2, eps=1e-5, momentum=0.1, affine=True)
# 3. 对数据进行 批量归一化处理.
output_2d = bn2d(input_2d)
print(f'output_2d: {output_2d}')
# 2. 定义函数, 处理: 一维数据.
def dm02():
# 1. 创建样本数据.
# 2行2列, 2条样本, 每个样本有2个特征
input_1d = torch.randn(size=(2, 2))
print(f'input_1d: {input_1d}')
# 2. 创建线性层.
linear1 = nn.Linear(2, 4)
# 3. 对数据进行 线性变换.
l1 = linear1(input_1d)
print(f'l1: {l1}')
# 4. 创建批量归一化层.
bn1d = nn.BatchNorm1d(num_features=4)
# 5. 对线性处理结果l1 进行 批量归一化处理.
output_1d = bn1d(l1)
print(f'output_1d: {output_1d}')
# 3. 测试
if __name__ == '__main__':
# dm01()
dm02()</code></pre> |
1 |
1 |
1 |
2/4/26, 4:47 PM |
2/4/26, 6:21 PM |
View Edit Delete |
| 42 |
Pytorch实现基础的价格分类模型 |
<p>背景:</p>
<p> 基于手机的20列特征 -> 预测手机的价格区间(4个区间), 可以用机器学习做, 也可以用 深度学习做(推荐)</p>
<p> </p>
<p>ANN案例的实现步骤:</p>
<p> 1. 构建数据集.</p>
<p> 2. 搭建神经网络.</p>
<p> 3. 模型训练.</p>
<p> 4. 模型测试.</p>
<pre class=""><code class="hljs language-python">import torch
import torch.nn as nn
import pandas as pd
from sklearn.model_selection import train_test_split
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
import torch.optim as optim
import numpy as np
import time
from sklearn.preprocessing import StandardScaler
# 构建数据集
def create_dataset():
# 使用pandas读取数据
data = pd.read_csv('./data/手机价格预测.csv')
# 特征值和目标值
x, y = data.iloc[:, :-1], data.iloc[:, -1]
# 类型转换:特征值,目标值
x = x.astype(np.float32)
y = y.astype(np.int64)
# 数据集划分
x_train, x_valid, y_train, y_valid = train_test_split(x, y, train_size=0.8, random_state=88, stratify=y)
# 优化①:数据标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_valid = transfer.transform(x_valid)
# 构建数据集,转换为pytorch的形式
train_dataset = TensorDataset(torch.from_numpy(x_train), torch.tensor(y_train.values))
valid_dataset = TensorDataset(torch.from_numpy(x_valid), torch.tensor(y_valid.values))
# 返回结果
return train_dataset, valid_dataset, x_train.shape[1], len(np.unique(y))
# 构建网络模型
class PhonePriceModel(nn.Module):
def __init__(self, input_dim, output_dim):
super(PhonePriceModel, self).__init__()
# 优化②:增加网络深度
# 1. 第一层: 输入为维度为 20, 输出维度为: 128
self.linear1 = nn.Linear(input_dim, 128)
# 2. 第二层: 输入为维度为 128, 输出维度为: 256
self.linear2 = nn.Linear(128, 256)
# 3. 第三层: 输入为维度为 256, 输出维度为: 512
self.linear3 = nn.Linear(256, 512)
# 4. 第四层: 输入为维度为 512, 输出维度为: 128
self.linear4 = nn.Linear(512, 128)
# 5. 输出层: 输入为维度为 128, 输出维度为: 4
self.linear5 = nn.Linear(128, output_dim)
def forward(self, x):
# 前向传播过程
x = torch.relu(self.linear1(x))
x = torch.relu(self.linear2(x))
x = torch.relu(self.linear3(x))
x = torch.relu(self.linear4(x))
# 后续CrossEntropyLoss损失函数中包含softmax过程, 所以当前步骤不进行softmax操作
output = self.linear5(x)
# 获取数据结果
return output
# 编写训练函数
def train(train_dataset, input_dim, class_num):
# 固定随机数种子
torch.manual_seed(0)
# 初始化数据加载器
dataloader = DataLoader(train_dataset, shuffle=True, batch_size=8)
# 初始化模型
model = PhonePriceModel(input_dim, class_num)
# 损失函数 CrossEntropyLoss = softmax + 损失计算
criterion = nn.CrossEntropyLoss()
# 优化③:使用Adam优化方法, 优化④:学习率变为1e-4
optimizer = optim.Adam(model.parameters(), lr=1e-4)
# 遍历每个轮次的数据
num_epoch = 50
for epoch_idx in range(num_epoch):
# 训练时间
start = time.time()
# 计算损失
total_loss = 0.0
total_num = 0
# 遍历每个batch数据进行处理
for x, y in dataloader:
model.train()
output = model(x)
# 计算损失
loss = criterion(output, y)
# 梯度清零
optimizer.zero_grad()
# 反向传播
loss.backward()
# 参数更新
optimizer.step()
# 损失计算
total_num += len(y)
total_loss += loss.item() * len(y)
# 打印损失变换结果
print('epoch: %4s loss: %.2f, time: %.2fs' %
(epoch_idx + 1, total_loss / total_num, time.time() - start))
# 模型保存
torch.save(model.state_dict(), './model/phone-price-model2.pth')
def evaluate(valid_dataset, input_dim, class_num):
# 加载模型和训练好的网络参数
model = PhonePriceModel(input_dim, class_num)
# load_state_dict:将加载的参数字典应用到模型上
# load:加载用来保存模型参数的文件
model.load_state_dict(torch.load('./model/phone-price-model2.pth'))
# 构建加载器
dataloader = DataLoader(valid_dataset, batch_size=8, shuffle=False)
# 评估测试集
correct = 0
# 遍历测试集中的数据
for x, y in dataloader:
# 将其送入网络中
# model.eval()
output = model(x)
# 获取预测类别结果
y_pred = torch.argmax(output, dim=1)
# 获取预测正确的个数
correct += (y_pred == y).sum()
# 求预测精度
print('Acc: %.5f' % (correct / len(valid_dataset)))
if __name__ == '__main__':
train_dataset, valid_dataset, input_dim, class_num = create_dataset()
train(train_dataset, input_dim, class_num)
evaluate(valid_dataset, input_dim, class_num)</code></pre> |
1 |
1 |
1 |
2/4/26, 6:21 PM |
2/4/26, 6:22 PM |
View Edit Delete |
| 43 |
Pytorch实现卷积神经网络(CNN)案例 |
<p>深度学习项目的步骤</p>
<p> 1. 准备数据集.</p>
<p> 这里我们用的时候 计算机视觉模块 torchvision自带的 CIFAR10数据集, 包含6W张 (32,32,3)的图片, 5W张训练集, 1W张测试集, 10个分类, 每个分类6K张图片.</p>
<p> 需要单独安装一下 torchvision包, 即: pip install torchvision</p>
<p> 2. 搭建(卷积)神经网络</p>
<p> 3. 模型训练.</p>
<p> 4. 模型测试.</p>
<p> </p>
<p>卷积层:</p>
<p> 提取图像的局部特征 -> 特征图(Feature Map), 计算方式: N = (W - F + 2P) // S + 1</p>
<p> 每个卷积核都是1个神经元.</p>
<p> </p>
<p>池化层:</p>
<p> 降维, 有最大池化 和 平均池化.</p>
<p> 池化只在HW上做调整, 通道上不改变.</p>
<p> </p>
<p>案例的优化思路:</p>
<p> 1. 增加卷积核的输出通道数(大白话: 卷积核的数量)</p>
<p> 2. 增加全连接层的参数量.</p>
<p> 3. 调整学习率</p>
<p> 4. 调整优化方法(optimizer...)</p>
<p> 5. 调整激活函数...</p>
<p> 6. ...</p>
<pre class=""><code class="language-python hljs">import torch
import torch.nn as nn
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor
import torch.optim as optim
from torch.utils.data import DataLoader
import time
import matplotlib.pyplot as plt
from torchinfo import summary
import os
# ===== 超参数集中管理(最佳实践)=====
BATCH_SIZE = 128 # 增大提升训练速度
LR = 1e-4
EPOCHS = 50
WEIGHT_DECAY = 1e-5
NUM_WORKERS = 4 # 利用多核CPU加速数据加载
MODEL_PATH = './model/image_model.pth'
# 1、准备数据集
def create_dataset():
# 1。获取训练集
# 参1:数据集路径。 参2:是否训练集,参 3数据预处理 --> 张量数据, 参4?:是否联网下载
train_dataset = CIFAR10(root='./data', train=True, transform=ToTensor(), download=True)
test_dataset = CIFAR10(root='./data', train=False, transform=ToTensor(),download=True)
return train_dataset, test_dataset
# 2、搭建卷积神经网络
class ImageModel(nn.Module):
# 1、初始化父类成员,搭建神经网络
def __init__(self):
# 初始化父类成员
super().__init__()
# 第一个卷积层,输入3通道,输出32通道,卷积核大小3*3,步长1,填充1
self.conv1 = nn.Conv2d(3,32,3,1,1)
self.bn1 = nn.BatchNorm2d(32)
# 第一个池化层
# 窗口大小2*2,步长1,填充0
self.pool1 = nn.MaxPool2d(2,2,0)
# 第2个卷积层 输入32通道,输出128通道,卷积核大小3*3,步长1,填充0
self.conv2 = nn.Conv2d(32,64,3,1,1)
self.bn2 = nn.BatchNorm2d(64)
# 第2个池化层
self.pool2 = nn.MaxPool2d(2,2,0)
# 第一个人隐藏层(全连接层),自动计算卷积输入数量,输出512,
self.fc1 = nn.LazyLinear(512)
self.bn3 = nn.BatchNorm1d(512)
# 第一个人隐藏层(全连接层),512,输出256
self.fc2 = nn.Linear(512,256)
self.bn4= nn.BatchNorm1d(256)
# 第一个人隐藏层(全连接层),256,输出10
self.output = nn.Linear(256,10)
# 添加dropout层
self.dropout = nn.Dropout(0.5)
# 定义前向传播
def forward(self,x):
# 第一层:卷积层(加权求和) + 激励层(激活函数)+池化层(降维)
x = self.pool1(torch.relu(self.bn1(self.conv1(x))))
# 第二层:卷积层(加权求和) + 激励层(激活函数)+池化层(降维)
x = self.pool2(torch.relu(self.bn2(self.conv2(x))))
# 第三层: 全连接层(加权求和)+激励层(激活函数)
# 全连接层只能处理二维数据,所以要将数据进行拉平(8,16,6,6) -> (8,576)
# 参1:样本数(行数),参2是列数(特征数)。-1表示自动计算
# 这里的size(0)是x的总长度,8、因为批次是8,不能用x[0],不然会出现形状为 [16, 6, 6] 的张量
x = x.reshape(x.size(0), -1)
# print(x.shape)
x = torch.relu(self.bn3(self.fc1(x)))
# 添加dropout层
x = self.dropout(x)
# 第四层: 全连接层(加权求和)+激励层(激活函数)
x = torch.relu(self.bn4(self.fc2(x)))
# 添加dropout层
x = self.dropout(x)
# 输出层
return self.output(x) # 后期用多分类交叉熵函数CrossEntropyLoss = Softmax()激活函数+损失计算
# 3、模型训练
def train(train_dataset):
# 1、创建数据加载器
train_dataloader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
# 2、创建模型对象
model = ImageModel().to(device)
# 3、创建损失函数
criterion = nn.CrossEntropyLoss()
# 4、创建优化器
optimizer = optim.Adam(model.parameters(), lr=LR, weight_decay=WEIGHT_DECAY)
# ✅ 优化2: 自动创建模型保存目录
os.makedirs(os.path.dirname(MODEL_PATH), exist_ok=True)
# 5、开始训练
for epoch in range(EPOCHS):
# 总损失
total_loss = 0.0
# 总样本数
total_sample =0.0
# 预测总正确数
total_correct = 0
# 训练开始时间
start_time = time.time()
for i, (x, y) in enumerate(train_dataloader):
# 1、将数据移动到GPU
x = x.to(device)
y = y.to(device)
model.train()
# 2、前向传播
y_pred = model(x)
# 3、计算损失
loss = criterion(y_pred, y)
# 4、梯度清零
optimizer.zero_grad()
# 5、反向传播
loss.backward()
# 6、梯度更新
optimizer.step()
# 统计预测正确的个数
# total_correct += (y_pred.argmax(dim=1) == y).sum().item()
# print('#' * 30)
# print(y_pred)
# print(y)
# print(torch.argmax(y_pred,dim=-1))
# print((torch.argmax(y_pred,dim=-1) ==y))
# print('#' * 30)
# 预测总正确数
total_correct += (torch.argmax(y_pred, dim=-1) == y).sum()
# print(total_correct)
# 统计总损失
# loss.item() 返回单个批次的平均损失 乘以批次数,获取总损失
total_loss += loss.item() * len(y)
# 统计总样本数
total_sample += len(y)
# 打印训练结果
print(f'轮数:{epoch + 1}, 训练总损失:{total_loss / total_sample}, 训练准确率:{total_correct / total_sample}, 训练时间:{time.time() - start_time}')
# 保存模型
torch.save(model.state_dict(), './model/image_model.pth')
# 4、模型测试
def evaluate(test_dataset):
# 1、创建数据加载器
test_dataloader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False)
# 2、创建模型对象
model = ImageModel().to(device)
# 3、加载模型参数
model.load_state_dict(torch.load('./model/image_model.pth'))
# 4、定义变量统计 预测正确的样本数,总样本数
total_correct = 0
total_samples = 0
model.eval()
# 遍历数据加载器,获取到每批次的数量
for x, y in test_dataloader:
# 1、将数据移动到GPU
x = x.to(device)
y = y.to(device)
# 2、前向传播
y_pred = model(x)
# 3、统计预测正确的样本数
total_correct += (torch.argmax(y_pred, dim=-1) == y).sum()
# 4、统计总样本数
total_samples += len(y)
# 打印测试结果
print(f'测试准确率:{total_correct / total_samples}')
if __name__ == '__main__':
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(torch.cuda.get_device_name(0))
train_dataset, test_dataset = create_dataset()
# print(train_dataset,train_dataset.data.shape) #(5000,32,32,3)
# print(test_dataset, test_dataset.data.shape) #(10000,32,32,3)
#
# plt.figure(figsize=(2,2))
# plt.imshow(train_dataset.data[111])
# plt.show()
model = ImageModel().to(device)
# 查看模型参数,参1:模型,参2 (批次,通道,高,宽),参3 设备
# 卷积层参数计算公式 = 输入通道数*卷积核尺寸*卷积核数量+卷积核数量
summary(model,input_size=(BATCH_SIZE, 3,32,32),device=device)
# 模型训练
train(train_dataset)
# 模型测试
evaluate(test_dataset)
</code></pre> |
1 |
1 |
1 |
2/8/26, 9:03 PM |
2/9/26, 6:49 AM |
View Edit Delete |
| 44 |
Ubuntu24.04设置Nginx自动重启 |
<p>1、创建 override 目录</p>
<pre class=""><code class="language-bash hljs">sudo mkdir -p /etc/systemd/system/nginx.service.d</code></pre>
<p> </p>
<p>2、创建自动重启配置</p>
<pre class=""><code class="language-bash hljs">sudo tee /etc/systemd/system/nginx.service.d/restart.conf <<'EOF'
[Service]
# 进程异常退出时自动重启
Restart=on-failure
# 正常退出也重启(可选,更严格)
# Restart=always
# 退出后延迟 5 秒重启
RestartSec=5s
# 重启限制(防止频繁崩溃)
StartLimitInterval=60s
StartLimitBurst=5
# 优雅停止超时时间
TimeoutStopSec=10s
EOF</code></pre>
<p> </p>
<p>3、重载 systemd 配置</p>
<pre class=""><code class="language-bash hljs">sudo systemctl daemon-reload</code></pre>
<p> </p>
<p>4、重启 nginx 使配置生效</p>
<pre class=""><code class="language-bash hljs">sudo systemctl restart nginx</code></pre>
<p> </p>
<p>5、验证配置生效</p>
<pre class=""><code class="language-bash hljs">systemctl show nginx | grep -E "Restart|StartLimit|TimeoutStopSec"</code></pre> |
1 |
34 |
1 |
2/9/26, 7:50 AM |
2/9/26, 9:54 AM |
View Edit Delete |
| 45 |
Nginx设置域名反向代理,防止DNS失效导致Nginx进程意外终止 |
<p>1、设置DNS地址及有效期</p>
<p>2、将域名设置为变量。</p>
<p>3、重写域名</p>
<p>4、去掉proxy_pass后面的反斜杠</p>
<pre class=""><code class="hljs language-bash"> location /api/ {
resolver 223.5.5.5 223.6.6.6 valid=30s;
resolver_timeout 10s;
set $backend "timeless.com";
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://$backend;
proxy_set_header Host $backend;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
</code></pre> |
1 |
42 |
1 |
2/9/26, 10:04 AM |
2/9/26, 10:04 AM |
View Edit Delete |
| 47 |
余弦相似度公式cosθ |
<p>余弦相似度 = 看两个东西“朝向”是否一致,不管它们“长短”如何。</p>
<p><strong>公式:两个向量的点积 除以 两个向量模长的乘积</strong></p>
<p><img src="data:image/png;base64,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" alt="" /></p>
<p> </p>
<p><strong>情况1:完全相同方向 → 相似度 = 1</strong></p>
<p><img src="data:image/png;base64,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" alt="" /></p>
<p>分子:点积1×2 + 1×2 = 2 + 2 =4</p>
<p>分母:长度乘积:√(1²+1²) × √(2²+2²) = 1.41 × 2.83≈4</p>
<p>相似度:4 ÷ 4=1.0</p>
<p> </p>
<p><strong>情况2:垂直(90°)→ 相似度 = 0</strong></p>
<p><img src="data:image/png;base64,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" alt="" /></p>
<p>分子:点积0×2 + 2×0 = 0 + 0 =0</p>
<p>分母:长度乘积:√(0²+2²) × √(2²+0²) = 2 × 2 = 4</p>
<p>相似度:0 ÷ 4 = 0</p>
<p> </p>
<p><strong>情况3:完全相反 → 相似度 = -1</strong></p>
<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPwAAAC+CAIAAACeWfVXAAAQAElEQVR4AexdX0gc2Zo/3AenJ2g7arQzQrpzr6Hp3jFBJGTYEALGB6EJ+DAvvsgIgllkXeJDgouXDVluWDEPHdZd2Q4EhDysL/sQkAYfHCFIlpEgkvSs0qSX6Q6YUaMmrSQ9woX7nVNV/UdPVXf96/rTX6iUVafqfN93fudXp746fb5z/tDREcQNEagpBP5A8B8iUGMIIOlrrMKxuIQg6ZEFNYcAkr7mqhwLjKTXxAHM5GQEkPROrj20XRMCSHpNsGEmJyOApHdy7aHtmhBA0muCDTM5GQEkvZNrz2m228ReJL1NKgLNqB4CSPrqYY2abIKAnUgfHp68E7EJLmiGixFQIH1kNBqbejAcqlLpI6MjVxsC/aO9VdKHamoWARnS996binbur2WrhUvnwIN+kk7R7dajgXC11KKemkSAS/rI6I29ufHpdT2I0MfmXk9ewonTfLpw0BvpeDsz+wZOErNPNjv65J0cuAU3REAfAlzSx2fvP93UJ5csJTKkIyz5Kj2XOkg6sSwnc2n64bOEeHHj6cPHcfEY/yACJiDAJb0heuI/rWX9l4Q2OxIOZNcXkcqGAItC9CJgHunJ5qvNw0An9XB6O/3p5fkNvbZifkTAEARMJD3Z+DmVpR4O+DaZN9jMG1JfKMQABMwkPUnMv0j5bzy61rT605IBtqIIzQhgxmIEuKSHDsTYVDQ21O0l3qtDenrr4XPW6yVvf9b7WVxsMh4jAvoQ4JI+MX//9sR40aarMyebeiX1zCjbujQ9gf02yhDhVSMQ4JLeCMFMRs+dfvyEZUjgzkYImEX6njvUQeprWp3DxttG1Y2mUATMIv3yY+Yd6fKLqH34HxEwHIGKSW+4ZhSICFiEgFmkv3bt7y0qEapFBMogYBbpy6jFy4iAdQgg6a3DHjVbhICdSN97bwojpyziQU2ptRPp3Qg8lsmGCMiQ3hO4cPl6kG3nGm1oNpqECGhHgEv6M83+1mxyJfl6JZk+8AauNHu0K8CciIDdEOCS/vN+8tV+jpn6aTdLPHVfsWPcIQKuQIBLeleUDAuBCMggUIb09f6gN/du/5NMbkxGBExBwFyhSqSv811p/+ZgK5k+NtcGlI4IVBUBWdID4y/4yIfkL0dVtQeVIQKmI8AnvcR46XPWdDNQASJQPQS4pG9r9kEnpedsUOyqDwYDddUzCTUhAuYiwCX9zm/QQ1+8oVtvbi2g9KoiwCV9VS0wSRmKRQTkEEDSyyGD6a5FwE6kx9kQXEszexXMTqS3FzJojWsRMIv0L1/+r2sxw4I5HAGzSO9wWGrW/JooOJK+JqoZC1mMgJ1Ij+GCxTWDx6YhYCfSm1ZIFIwIFCPAJ329XxqAcPm69nDB8PBklE7uNxWN4ZqBxaDjsbUI8El/lGGxgq9Xksl3Ho3hgp0DA6HUEza530LKj2sGWlvPqL0IAT7pCzfkvghhg4WUckfS9cT8/bvikjtLiQzxNrdLV/AvImApAuVI39jqze0eaSW+pUVD5YgAHwE50p9pFsYVB5qy23ojp+gs9VlcgYdfAZhafQTkSP95X5gC5PXase/6Bd8ZzZaFBh/1BVKLOGe3ZgQxo9EIyJE+r+fz0adc3Vf1+XNVB8D4oW6y/mRadtlkVeLwZkTACATKkp5GUWU/7WjQJTFe+pzVIKKGsmBRq4cAl/SSQ0+n9QuS9MpvWqYAidzs9hLi7RoRu+qnHgyHqlcu1IQIyCLAJX3eoV9JvtbGeNAXny1enxCO0a0HVHCzAQJc0tvALjQBETANASS9adCiYLsiYCfSY7igXVliX7s0WWYn0msqAGZCBNQigKRXixje73gEkPSOr0IsgFoEkPRqEcP7HY+AnUiP4YKOp5MzCmAn0luDGGqtOQQUSe8J0DUGdU1ZHBmNxnAAQs3Ryt4FViD9mWb/+dzHA+32g7sS7dxfy2qXgDkRARMQkCV9ne/vzpJ3Olabioze2Jsbn143wWgUiQjoQUCG9J5Au498yOiJmYrP4ggzPTWDeU1DgE/6+rbzZPv/xKVkTdONgh2MgJNN55G+8bt2z7ut7c9OLhfajgjIIsAhfX1jE/Gcp/02l68HA+LxuUZZEXgBEXAWAhzSF2Z6er2STB+Q3LtftYeSOAsNtLYmEOCQ3qBydw48oIGCQ91e4r06hL31BsGKYvQjUI70n35JalxaMDF/n83pNy7tsTNHf3WhBCMQKEd6I3TIyMBkRMAaBJD01uCOWi1EwE6kx3BBC4lQS6rtRPpawh3LaiECZpH+3Pk/WVgqVI0IKCBgFukVVOIlXQhgZt0IIOl1Q4gCnIaAnUjfe2/qTsRpAKK9zkPATqR3HnposSMR4JO+zncleNmIBQYdiQka7XIE+KSHQh9vryVf01mLYa9pqm6QgRsiYBcEiu2QJX3xTXiMCLgJASS9m2oTy1IRArKkr/N1i269v60iSXgTIuAQBPikP95+Ba4829Y+eIJB5L1DqhPNrAQBPumLctLVBYtO8RARcDwC5UhP5wLxaFtd0PHYnCgAnroFAS7pi1YXDLZmk5rXWnMLSFgOdyHAJf3n/aTYQ598/Qpnv3FXjWNpCJf0iAsi4GYEkPRurl0sGxcBO5EewwW5VeTwRBuabyfS2xAeNMmNCCDp3VirWCZFBJD0ivDgRTcigKR3Y61imRQRQNIrwoMX3YiAE0jvRtyxTBYioED6tnNSxCBOTm9hDaFqwxGQIb0ncOFykKTFwQgYLmg47ijQQgT4pK9vO59LV3ucWWjwkUNXnO25E5uK3usRqjE8PBmNTQ52Cme4tyECXNK31X+TO/Z8J0ZOXf6u3oaGV9Ek4PRor5K+5ccz69mOPjppT+fAwFWyNvPwWUIpA16zFAEe6T1fe4jn7Fe7LHJqZetjU7uuRcMtLZ8RyoHT+zdiihNRJebvP88EegYGI11k9X/swXgjiu5OGTzS05IebGV26F9CjnbeHXvq64QTM/bMH5iKxgoL9URj9/8lCimntv86lQJ+xX/8JQr7k9u/8RIf8hJ5MmNTf/n3ovSxLi8hgX5F7ys+u7Db1d26Pv900wyUUKZxCPBIn/uSI1/XeYxToixp4+lDtkTP3FqWZFfn2PGDfx2fYAel+38oPRUW9vnHP3PuvP3PvMRJXiJP5u2JP/9TUfrMepaQ9PMJhRWE4NG9RRaB9yOSc69carxqHQI80pOdo4+es23iJAjwUVv3cffIOhMt19xzZ6z5xe2Jx3F5SwRXPr68NL2YFpx7+XvxitUIcElPjjJsEgTWT99OkknJ1bHaWmv0Lz++PbukoLpz4MFY3pVfXlw9BEeIftQqZMFLViLAJz0hRRGD1WL85rO7Sv6DlSgp64av2NsFywVvTem1oCwNr5qOgBzpmWLcIQJuRABJ78ZaxTIpIoCkV4QHL7oRASS9G2sVy6SIAJJeER686EYEkPTG1ypKtDkCSHqbVxCaZzwCSHrjMUWJNkcASW/zCkLzjEeAR3oaNlVYWjB4+XrQ9KHF8Eu+NExS8w/4YRq9oTgAWAE+AwwIDT6aisaUR97LWiAYzwaBapQgKxovnESAR/pc+ldpXcHk65Wtj4TkvhyfzGjkeWjwx463M2xU4/NMoH9SfdhRCAg3QFJpjVb13BnrOniuwwD6zPxANjMa9XcODIRST9ig0YWU/9ajgbBGQU7OVj3beaQv0U6jqD7s7JSkGX2y+eyuFGoU30iThha/Og3h4R9alifuP91Wl026Ozx8LZBdXxQGUcZ/Wss2XPw+JF2s5C88tM0vbj989r6Sm3n3JObv353fYFeWEhnibW5nx7gzB4EypK/z+b0fM3afon7j6UM9A7zaWxqym+sC53rvsViWlm/VwA0PreIwTDWy8F7zEVAmfVuzj5jdzJeUsfdeX6HRLbli+ongVd8ii+PPM6TVZ5GD0XOn359d/UlpJLPpSLhegRLpaTOf2z3KGQsCdX/hg0/YRosDroF2tzoyC9KLXkZtD516QPzqnVTv/fOleq8OjbS8pHFV08vhb5vI7rbQ8PPvNis1NPioL5BaVIjPMktzbclVID00857sdtroT1jwX9kXG2VYUXAGMH6EziNQ1k9YflzILn0J6Kuzrb1Dkl1/Mr0siKHezp5m91yQoWEPjB/qJgUzNIjALJUhIEt61sy/2/9UmRidd0mM10lijVZs/JzKersGhtnHa+fAjY7Dtz9XObhbYnyZt5zGAmK2UgRkSO8JtPvMaOZLlUtnPX1XGwhp6B4TfJ6pqNo+u8go6+HuC7A5C+BYXWc/vHxm1snVIcgYHYPOU9XPXu89Znk/9Dr5b1HXq8Rtk4op/zdys9tLiLdrhOaloh4IT6B8DryiAwEZ0rOu+qrN5lfssbDOcrUNXnyWOUssL3N+VHfmAO9ZxnHoeVQ/T9PSdEE1s6Ssk1ZaZafsR7e+FCBjz2RIb6wSlIYI2AkBJL2dagNtqQoCSPqqwGxrJTVnHJK+5qocC4ykRw7UHAJI+pqrciwwkh45UHMIIOlrrsqxwMaQ3rU4ij+1wg+lan8kVguJ+KMy/Byr8tdctYpscH+YxbjR37+1BppxCqECQDnSt+WXFgzW+PI74pT55X8kDg1WGC5YqJ7JwihR4UfZGToRPqdG3ZeUWjz103WoWgBySX+mOVhYWpAuv+MX56p3H/YGlYiOl64sXBDu7G9aY7GRT1ZJ95j72/WKIAZYYlUDkEv6+jpP7vh30djj3w0eUC/KLf0jPOXwcldc4qY0j9IZBbGUT9C+muWihAZ/rDRcsDfS5U29FBal2nj6Mk38lyJK5dB5reCeGbM+Ss+dEwsnnsZZi8VVBpBLerYSSZAtKigMt/y0o6UoFecJDT6iQXrC/d6rQ4UxhoCpGqaCsyjmTWwfkKb2Kq1rWXm4YKi9laQTwsB9KDUdFtr0LRvSLBTe0D0w/laHJLGjL7/oJ0sC7ZMF54olye6gvRCfmfd7WdURzLJiCxeqDCCX9OQos5JMk3Y6+UdrNmn2grKdXRe9BQDgyBvqChMCDI6ONb8o70xDDnHbePrwRcsQG5kM1cMS4bFhX0tK8VBQqfCpWrSJTw4TYMYO6BiNDV3cnHuyeuhVF49buTk9l/KMFzJ1hIvi1IBnL1vGKnuvxmef7F1js5tsbu0KsqQm39/sze5vCWkn93APfXWzD1Z2oKb9Oims9FwfgHzS1/uvB31HdCKQ9JezwesXfGdKdZp/1nVvaoQOsheGpzPIgJRie1OqvpSytG2jA9NvntltaPGT8PfNBykiNPlZFg9FnyUQRTfJ/xE+IsWhxXSQsNLIXvoUSfawx6nUmvJngf6pG3t0PTnQUuUorYvCuH9adigCfc/Ae7X0DSDZX1LMfF1Mhv56SF9NkTBJHQC89O58aKVQEYU60j1inErn/NcNII/0nsDZb3IfMixQ8NMvyfRBne+P9RzlRiUl1t9mS2RlN9f/e3oCWkFCMgtFXByXIvpK7i6l7EKKv0eExQAABkRJREFU0Ni/27Mv9qB6eq6EyJv4fsv3IaDXwXsaDwVvA9ZvMLeWlfxpobZEKgAbFNu/wsh7eDxUjpsnrKUsRMFSb0ewqqRExpwsvwEoikWlNmIl4/4X0wDV6hwf1ZJi5uvi4X9uHHhbvu3tbNqLb5DOHnh/Ck0JAQz7ydrqYZFCM1p6QwDkkZ7a7an7iv6B//WNTSR3ZHSkLAgubPCqBQqK59BFCE0gnFB2zuzfUPNOhFacNqIFj8jXsruxlNgmoZuXWg/3iuZiCg//0O3NvBHnujkZgyIYADbo39iLuDDvGp3WJr/8IA2YkmzQr+mUhKXpCdoECOnQRVjSZIQGH13bm5moqKSRURY1n3/Cfe0k9Srxfq813NfSID60tOmZfSXoEvfGtPQmAMgjfS79a/rAG7hOJ/S7fL3d8+7XJGv1xbKY8gd4Dw0n3UqqAdqbAoPLK4bnJJ994/2B92oXScBX4/KbXX/Ae7AlhkRBfU+N0BnF8rVYXrLyHULFRHnhgpTlhFCXQBAB5KCzuNH3SbSfLBSFxgvXjd0D79lrbeJUcw6AVxwVCTbnH5jMfraj6+Le+gbZfLXZFOgoaUo0G19dAHmkB9PBq3m9khQ28xkPCk3YoKqkxV9Z3YsUF6ZzEgNSCw6oLgOYfPrEigwrpjKwhBCxORSUMMPYnaJJQrIz9tAMSUspQhNTiK5k3wAj8BkG3UTqP3VUAUj0AihDemdUgCYrS/DNN2CaRJXLRF8p0TE6S6bqmN1yom13nT0M7EmGh9+oh9kkAGuP9GrpQvs34BtXzaeFpAJcCGDAREWMhw9B0DLWVdp5K0ly31/6QgAfT+pA4xfQJACR9Hy4xdTCa0HNp4WYWdUfva9sVcosvpn5RbQ5GC/2A3UapQJAJL1OrDG78xCwnvTnzv+pcthU3Vy5WLyzphCwnvRWwI06axoBJH1NV39tFh5JX5v1XtOlRtKrr37x58PYlNmDMdWbhjkqQUCO9IVwQQuGWFZiuK57WKd4CWVZijgItvAzLftxBLrPYcsnRkZvta7TRdHoRMc3iwbr6rIIM1cRAS7pzzQHg57tNTYMIZnzdZ9rrKJFZqui7XTn/lq2SA/8hE6HwQg9x4tpaUAYHbCwK4Ry0kThIaHjCoUFqujg0KrFqRRZa92hWzTzSN/4x7Oegw/bn1kZd/a3c95G18TIRkbpMMzpdVY2aecvjoQoRJ/c6Dhciy+zm5YXVw+F0BY6jo3FuBAa+5IfxMbuwp0zEOCRHiwvGkt8nPtCPF/XQaK9N3BFJsvHv8Vn88MwC8WJb6S9XSPMgSkMOaZPQuqVMDAzMkqHUgkrXcZnF3bZ6gl0UE1Fg0zCw5PCW6KgEY+sRIBH+k+7Wc/5ZtGlaTsXaLLSwIp0g38SG2pZrnis7EmhdOT3AukDn/7kkGMqeYqNAV5MS0G3+bEJFQ2qIQR+dZeCGE8qxnMrEOCRnuz8VhhP33qUPiC5L6YGkegrOHyDsnFagf4pYK20KY9kOqGRxvhQt+f2BGvFpTcGNP9jzS9o6NbsUqeviahxZsAq+PyVNimIUZVVJ4zEU6MQ4JKekMJ4+l+OPV8f/35klD4T5MRnx2foHEnp58KXqLCvyPEQrBFWDJ9/ugmn0IovpBq6Iz2EjoM/XJuR5FBvRy4CGvKd2sAq+rQIxrAIpiz0+UjSTt2OCVVEQIb0kgV1visXGne3xI9aKVX7X5Ny0sHcc3s9UgutQYvgr9OMdBIBGvdJO2caun8cCNPE0GCPPyt02tBTdf/Bp6evEbPHaaozqpbv5pL+THNQjBW88FUm6ZDIqc1ndyvw6QUfPTbU7SXCQHn4xASfeyGVn3ahr2l1jn3sgsC5NcK+WWNDFzeFRC1cAflMoJa8mMcEBLik/7yflGIFMzsmKLVQJH0niC6HEOYj0BG8GuEU9kIKsxF4L95clMiu4M7BCHBJ7+DyoOmIQFkEkPRlIcIb3IYAkt4JNYo2GooAkt5QOFGYExAwi/S/vfv/Cotf+Z0gUNXNcD9uiMBpBMwi/WlNmIII2AQBJL1NKgLNqB4CSPrqYY2aqoyAnDokvRwymO5aBJD0rq1aLJgcAkh6OWQw3bUIIOldW7VYMDkEkPRyyGC6axFA0itWLV50IwJ/AwAA//+u5UeFAAAABklEQVQDABx4vFTSOc74AAAAAElFTkSuQmCC" alt="" /></p>
<p>分子:1×(-1) + 0×0 = -1 + 0 = -1</p>
<p>分母:长度乘积:√(1²+0²) × √((-1)²+0²) = 1 × 1 = 1</p>
<p>相似度:-1 ÷ 1 = -1.0</p> |
1 |
1 |
1 |
2/13/26, 8:52 PM |
2/17/26, 9:02 PM |
View Edit Delete |
| 48 |
Zero-shot学习(Zero-shot Learning) |
<p>Zero-shot是指学习在训练阶段不存在与测试阶段完全相同的类别,但是模型可以使用训练过的知识来推广到测试集中的新类别上。</p>
<p>这种能力被称为“零样本”学习,因为模型在训练时从未见过测试集中的新类别,在模型训练和提示词优化中均有体现。</p>
<p> </p>
<p style="language: zh-CN; margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-align: left; direction: ltr; unicode-bidi: embed; mso-line-break-override: none; word-break: normal; punctuation-wrap: hanging;"><strong>在模型训练中:</strong></p>
<ul>
<li style="text-align: left; direction: ltr; unicode-bidi: embed; word-break: normal;">已知马(四脚兽)、虎(有条纹)、熊猫(黑白色)的特征,但未训练过斑马的数据(不认识)</li>
<li style="text-align: left; direction: ltr; unicode-bidi: embed; word-break: normal;">告知模型:斑马是四脚兽、有黑白色的条纹</li>
<li style="text-align: left; direction: ltr; unicode-bidi: embed; word-break: normal;">模型可以在已知数据中进行推理,从而识别斑马。</li>
</ul>
<p> </p>
<p><strong>在提示词优化中:</strong></p>
<ul>
<li>Zero-shot思想用于基于已训练的能力,不提供任何示例,仅通过语言去描述任务的要求、目标和约束,让模型直接生成结果。</li>
</ul>
<p>简单来说就是“用语言定义任务,解放(信任)模型的预训练知识”</p>
<p> </p>
<p>比如:</p>
<p>请判断””包围的用户评论中的情感倾向,输出 正面 或 负面。</p>
<p>”这款代餐鸡胸肉饱腹感很强,吃起来也不柴,很推荐!”</p>
<p> </p>
<p> </p> |
1 |
60 |
1 |
2/17/26, 4:29 PM |
2/17/26, 4:37 PM |
View Edit Delete |
| 49 |
Few-shot学习(Few-shot Learning) |
<p>Few-shot学习是指少样本学习,当模型在学习了一定类别的大量数据后,对于新的类别,只需要少量的样本就能快速学习,对应的有one-shot learning,单样本学习,也算样本少到为一的情况下的一种few-shot learning。</p>
<p> </p>
<p><strong>在模型训练中(相似度判断方法):</strong></p>
<ul>
<li>基于少量企鹅样本并结合相识度判断,推论未知图片内含“企鹅”</li>
</ul>
<p> </p>
<p><strong>在提示词优化中:</strong></p>
<ul>
<li>Few-shot主要用于基于少量示例,让模型参考示例回答。</li>
<li> </li>
</ul>
<p>简单来说就是“用示例定义任务,在模型的预训练知识的基础上,提升模型回答的对齐精度(比如参考示例的格式)”</p>
<p> </p>
<p>比如:</p>
<p>请抽取产品名称和核心卖点2个字段,格式为Json,我提供2个示例。</p>
<p><em>示例1:MacBookPro高效节能,性能强大,适合牛马工作使用</em></p>
<p><em>输出:{“产品名称”: “MacBookPro”, “产品卖点”: “高效节能,性能强大”}</em></p>
<p><em>示例2:联想笔记本拥有RTX4060独立显卡,畅玩游戏,丝滑流畅</em></p>
<p><em>输出:{“产品名称”: “联想笔记本”, “产品卖点”: “畅玩游戏,丝滑流畅”}</em></p>
<p>请处理:华为MatepadPro,高清大屏,长效续航,你的好帮手。</p>
<p> </p>
<p><em>{“产品名称”: “华为MatepadPro”, “产品卖点”: “高清大屏,长效续航”}<br /><br /></em></p>
<p><em> </em></p> |
1 |
60 |
1 |
2/17/26, 4:33 PM |
2/19/26, 5:59 AM |
View Edit Delete |
| 50 |
OpenAI实现提示词案例:文本分类 |
<div style="background-color: #0f111a; color: #c3cee3;">
<pre style="font-family: 'Source Code Pro',monospace; font-size: 12.0pt;"><span style="color: #c792ea; font-style: italic;">from </span>openai <span style="color: #c792ea; font-style: italic;">import </span>OpenAI<br /><span style="color: #c792ea; font-style: italic;">import </span>os<br /><span style="color: #c792ea; font-style: italic;">from </span>dotenv <span style="color: #c792ea; font-style: italic;">import </span>load_dotenv<br /><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">加载</span><span style="color: #717cb4; font-style: italic;"> .env </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">文件<br /></span><span style="color: #82aaff;">load_dotenv</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># 1</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">、获取</span><span style="color: #717cb4; font-style: italic;">client</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">对象,</span><span style="color: #717cb4; font-style: italic;">OpenAi</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">类对象<br /></span>client <span style="color: #89ddff;">= </span><span style="color: #82aaff;">OpenAI</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">api_key</span><span style="color: #89ddff;">=</span>os<span style="color: #89ddff;">.</span><span style="color: #82aaff;">getenv</span><span style="color: #89ddff;">(</span><span style="color: #c3e88d;">"DASHSCOPE_API_KEY"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">base_url</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"https://dashscope.aliyuncs.com/compatible-mode/v1"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span>examples_data <span style="color: #89ddff;">= { </span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">示例数据<br /></span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;"> </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">新闻报道</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">今日,股市经历了一轮震荡,受到宏观经济数据和全球贸易紧张局势的影响。投资者密切关注美联储可能的政策调整,以适应市场的不确定性。</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">财务报告</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">本公司年度财务报告显示,去年公司实现了稳步增长的盈利,同时资产负债表呈现强劲的状况。经济环境的稳定和管理层的有效战略执行为公司的健康发展奠定了基础。</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司公告</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">本公司高兴地宣布成功完成最新一轮并购交易,收购了一家在人工智能领域领先的公司。这一战略举措将有助于扩大我们的业务领域,提高市场竞争力</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">分析师报告</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">最新的行业分析报告指出,科技公司的创新将成为未来增长的主要推动力。云计算、人工智能和数字化转型被认为是引领行业发展的关键因素,投资者应关注这些趋势</span><span style="color: #c3e88d;">'<br /></span><span style="color: #89ddff;">}<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">分类列表<br /></span>examples_types <span style="color: #89ddff;">= [</span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">新闻报道</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">财务报告</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司公告</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">分析师报告</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span>messages <span style="color: #89ddff;">= [<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"system"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">你是金融专家,将文本分类为</span><span style="color: #c3e88d;">['</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">新闻报道</span><span style="color: #c3e88d;">', '</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">财务报道</span><span style="color: #c3e88d;">', '</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司公告</span><span style="color: #c3e88d;">', '</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">分析师报告</span><span style="color: #c3e88d;">']</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">,不清楚的分类为</span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">不清楚类别</span><span style="color: #c3e88d;">' </span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">下面有示例:</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">},<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span><span style="color: #c792ea; font-style: italic;">for </span>key<span style="color: #89ddff;">, </span>value <span style="color: #c792ea; font-style: italic;">in </span>examples_data<span style="color: #89ddff;">.</span><span style="color: #82aaff;">items</span><span style="color: #89ddff;">():<br /></span><span style="color: #89ddff;"> </span>messages<span style="color: #89ddff;">.</span><span style="color: #82aaff;">append</span><span style="color: #89ddff;">({</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"user"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span>value<span style="color: #89ddff;">})<br /></span><span style="color: #89ddff;"> </span>messages<span style="color: #89ddff;">.</span><span style="color: #82aaff;">append</span><span style="color: #89ddff;">({</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"assistant"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span>key<span style="color: #89ddff;">})<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">提问数据<br /></span>questions <span style="color: #89ddff;">= [<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">今日,央行发布公告宣布降低利率,以刺激经济增长。这一降息举措将影响贷款利率,并在未来几个季度内对金融市场产生影响。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"ABC</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司今日发布公告称,已成功完成对</span><span style="color: #c3e88d;">XYZ</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司股权的收购交易。本次交易是</span><span style="color: #c3e88d;">ABC</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司在扩大业务范围、加强市场竞争力方面的重要举措。据悉,此次收购将进一步巩固</span><span style="color: #c3e88d;">ABC</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司在行业中的地位,并为未来业务发展提供更广阔的发展空间。详情请见公司官方网站公告栏</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司资产负债表显示,公司偿债能力强劲,现金流充足,为未来投资和扩张提供了坚实的财务基础。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">最新的分析报告指出,可再生能源行业预计将在未来几年经历持续增长,投资者应该关注这一领域的投资机会</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">小明喜欢小新哟</span><span style="color: #c3e88d;">"<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">向模型提问<br /></span><span style="color: #c792ea; font-style: italic;">for </span>q <span style="color: #c792ea; font-style: italic;">in </span>questions<span style="color: #89ddff;">:<br /></span><span style="color: #89ddff;"> </span>response <span style="color: #89ddff;">= </span>client<span style="color: #89ddff;">.</span>chat<span style="color: #89ddff;">.</span>completions<span style="color: #89ddff;">.</span><span style="color: #82aaff;">create</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">model</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"qwen3.5-plus"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">messages</span><span style="color: #89ddff;">=</span>messages <span style="color: #89ddff;">+ [{</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"user"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">f"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">按照示例,回答这段文本的分类类别:</span><span style="color: #89ddff;">{</span>q<span style="color: #89ddff;">}</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">}]<br /></span><span style="color: #89ddff;"> )<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"> </span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>response<span style="color: #89ddff;">.</span>choices<span style="color: #89ddff;">[</span><span style="color: #f78c6c;">0</span><span style="color: #89ddff;">].</span>message<span style="color: #89ddff;">.</span>content<span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span></pre>
</div> |
1 |
60 |
1 |
2/17/26, 7:00 PM |
2/19/26, 6:48 AM |
View Edit Delete |
| 51 |
OpenAI实现提示词案例:文本抽取 |
<div style="background-color: #0f111a; color: #c3cee3;">
<pre style="font-family: 'Source Code Pro',monospace; font-size: 12.0pt;"><span style="color: #c792ea; font-style: italic;">from </span>openai <span style="color: #c792ea; font-style: italic;">import </span>OpenAI<br /><span style="color: #c792ea; font-style: italic;">import </span>os<br /><span style="color: #c792ea; font-style: italic;">from </span>dotenv <span style="color: #c792ea; font-style: italic;">import </span>load_dotenv<br /><span style="color: #c792ea; font-style: italic;">import </span>json<br /><br /><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">加载</span><span style="color: #717cb4; font-style: italic;"> .env </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">文件<br /></span><span style="color: #82aaff;">load_dotenv</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># 1</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">、获取</span><span style="color: #717cb4; font-style: italic;">client</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">对象,</span><span style="color: #717cb4; font-style: italic;">OpenAi</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">类对象<br /></span>client <span style="color: #89ddff;">= </span><span style="color: #82aaff;">OpenAI</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">api_key</span><span style="color: #89ddff;">=</span>os<span style="color: #89ddff;">.</span><span style="color: #82aaff;">getenv</span><span style="color: #89ddff;">(</span><span style="color: #c3e88d;">"DASHSCOPE_API_KEY"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">base_url</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"https://dashscope.aliyuncs.com/compatible-mode/v1"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span>examples_data <span style="color: #89ddff;">= [ </span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">示例数据<br /></span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;"> </span><span style="color: #89ddff;">{<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"2023-01-10</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">,股市震荡。股票强大科技</span><span style="color: #c3e88d;">A</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">股今日开盘价</span><span style="color: #c3e88d;">100</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,一度飙升至</span><span style="color: #c3e88d;">105</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,随后回落至</span><span style="color: #c3e88d;">98</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,最终以</span><span style="color: #c3e88d;">102</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币收盘,成交量达到</span><span style="color: #c3e88d;">520000</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"answers"</span><span style="color: #89ddff;">: {<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">日期</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"2023-01-10"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">股票名称</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">强大科技</span><span style="color: #c3e88d;">A</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">股</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">开盘价</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"100</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">收盘价</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"102</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">成交量</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"520000"<br /></span><span style="color: #c3e88d;"> </span><span style="color: #89ddff;">}<br /></span><span style="color: #89ddff;"> },<br /></span><span style="color: #89ddff;"> {<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"2024-05-16</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">,股市利好。股票英伟达美股今日开盘价</span><span style="color: #c3e88d;">105</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">美元,一度飙升至</span><span style="color: #c3e88d;">109</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">美元,随后回落至</span><span style="color: #c3e88d;">100</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">美元,最终以</span><span style="color: #c3e88d;">116</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">美元收盘,成交量达到</span><span style="color: #c3e88d;">3560000</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"answers"</span><span style="color: #89ddff;">: {<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">日期</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"2024-05-16"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">股票名称</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">英伟达美股</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">开盘价</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"105</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">美元</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">收盘价</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"116</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">美元</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">成交量</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"3560000"<br /></span><span style="color: #c3e88d;"> </span><span style="color: #89ddff;">}<br /></span><span style="color: #89ddff;"> }<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span>fields <span style="color: #89ddff;">= [</span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">日期</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">股票名称</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">开盘价</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">收盘价</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">成交量</span><span style="color: #c3e88d;">'</span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span>messages <span style="color: #89ddff;">= [<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"system"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">f"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">你帮我完成信息抽取,我给你句子,你抽取</span><span style="color: #89ddff;">{</span>fields<span style="color: #89ddff;">}</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">信息,按</span><span style="color: #c3e88d;">JSON</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">字符串输出,如果某些信息不存在,用</span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">原文未提及</span><span style="color: #c3e88d;">'</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">表示,请参考如下示例:</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">}<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span><span style="color: #c792ea; font-style: italic;">for </span>example <span style="color: #c792ea; font-style: italic;">in </span>examples_data<span style="color: #89ddff;">:<br /></span><span style="color: #89ddff;"> </span>messages<span style="color: #89ddff;">.</span><span style="color: #82aaff;">append</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"user"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span>example<span style="color: #89ddff;">[</span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">]}<br /></span><span style="color: #89ddff;"> )<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"> </span>messages<span style="color: #89ddff;">.</span><span style="color: #82aaff;">append</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"assistant"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span>json<span style="color: #89ddff;">.</span><span style="color: #82aaff;">dumps</span><span style="color: #89ddff;">(</span>example<span style="color: #89ddff;">[</span><span style="color: #c3e88d;">"answers"</span><span style="color: #89ddff;">], </span><span style="color: #f78c6c;">ensure_ascii</span><span style="color: #89ddff;">=</span><span style="color: #c792ea; font-style: italic;">False</span><span style="color: #89ddff;">)}<br /></span><span style="color: #89ddff;"> )<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">提问数据<br /></span>questions <span style="color: #89ddff;">= [<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"2025-06-16</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">,股市利好。股票</span><span style="color: #c3e88d;">Timeless </span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">上证</span><span style="color: #c3e88d;">A</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">股今日开盘价</span><span style="color: #c3e88d;">66</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,一度飙升至</span><span style="color: #c3e88d;">70</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,随后回落至</span><span style="color: #c3e88d;">65</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,最终以</span><span style="color: #c3e88d;">68</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币收盘,成交量达到</span><span style="color: #c3e88d;">123000</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"2025-06-06</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">,股市利好。股票</span><span style="color: #c3e88d;">Leon </span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">深证</span><span style="color: #c3e88d;">A</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">股今日开盘价</span><span style="color: #c3e88d;">200</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,一度飙升至</span><span style="color: #c3e88d;">211</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,随后回落至</span><span style="color: #c3e88d;">201</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币,最终以</span><span style="color: #c3e88d;">206</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">人民币收盘。</span><span style="color: #c3e88d;">"<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">向模型提问<br /></span><span style="color: #c792ea; font-style: italic;">for </span>q <span style="color: #c792ea; font-style: italic;">in </span>questions<span style="color: #89ddff;">:<br /></span><span style="color: #89ddff;"> </span>response <span style="color: #89ddff;">= </span>client<span style="color: #89ddff;">.</span>chat<span style="color: #89ddff;">.</span>completions<span style="color: #89ddff;">.</span><span style="color: #82aaff;">create</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">model</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"qwen3.5-plus"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">messages</span><span style="color: #89ddff;">=</span>messages <span style="color: #89ddff;">+ [{</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"user"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">f"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">按照上述的示例,现在抽取这个句子的信息:</span><span style="color: #89ddff;">{</span>q<span style="color: #89ddff;">}</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">}]<br /></span><span style="color: #89ddff;"> )<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"> </span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>response<span style="color: #89ddff;">.</span>choices<span style="color: #89ddff;">[</span><span style="color: #f78c6c;">0</span><span style="color: #89ddff;">].</span>message<span style="color: #89ddff;">.</span>content<span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span></pre>
</div> |
1 |
60 |
1 |
2/17/26, 7:46 PM |
2/19/26, 6:48 AM |
View Edit Delete |
| 52 |
OpenAI实现提示词案例:文本判断 |
<div style="background-color: #0f111a; color: #c3cee3;">
<pre style="font-family: 'Source Code Pro',monospace; font-size: 12.0pt;"><span style="color: #c792ea; font-style: italic;">from </span>openai <span style="color: #c792ea; font-style: italic;">import </span>OpenAI<br /><span style="color: #c792ea; font-style: italic;">import </span>os<br /><span style="color: #c792ea; font-style: italic;">from </span>dotenv <span style="color: #c792ea; font-style: italic;">import </span>load_dotenv<br /><span style="color: #c792ea; font-style: italic;">import </span>json<br /><br /><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">加载</span><span style="color: #717cb4; font-style: italic;"> .env </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">文件<br /></span><span style="color: #82aaff;">load_dotenv</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># 1</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">、获取</span><span style="color: #717cb4; font-style: italic;">client</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">对象,</span><span style="color: #717cb4; font-style: italic;">OpenAi</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">类对象<br /></span>client <span style="color: #89ddff;">= </span><span style="color: #82aaff;">OpenAI</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">api_key</span><span style="color: #89ddff;">=</span>os<span style="color: #89ddff;">.</span><span style="color: #82aaff;">getenv</span><span style="color: #89ddff;">(</span><span style="color: #c3e88d;">"DASHSCOPE_API_KEY"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">base_url</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"https://dashscope.aliyuncs.com/compatible-mode/v1"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span>examples_data <span style="color: #89ddff;">= {<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">是</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: [<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司</span><span style="color: #c3e88d;">ABC</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">发布了季度财报,显示盈利增长。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">财报披露,公司</span><span style="color: #c3e88d;">ABC</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">利润上升。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">公司</span><span style="color: #c3e88d;">ITCAST</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">发布了年度财报,显示盈利大幅度增长。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">财报披露,公司</span><span style="color: #c3e88d;">ITCAST</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">更赚钱了。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"> ],<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">不是</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">: [<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">黄金价格下跌,投资者抛售。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">外汇市场交易额创下新高。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">央行降息,刺激经济增长。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">新能源技术的创新。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"> ]<br /></span><span style="color: #89ddff;">}<br /></span><span style="color: #89ddff;"><br /></span>messages <span style="color: #89ddff;">= [<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"system"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">f"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">你帮我完成文本匹配,我给你</span><span style="color: #c3e88d;">2</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">个句子,被</span><span style="color: #c3e88d;">[]</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">包围,你判断它们是否匹配,回答是或不是,请参考如下示例:</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">},<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span><span style="color: #c792ea; font-style: italic;">for </span>key<span style="color: #89ddff;">, </span>value <span style="color: #c792ea; font-style: italic;">in </span>examples_data<span style="color: #89ddff;">.</span><span style="color: #82aaff;">items</span><span style="color: #89ddff;">():<br /></span><span style="color: #89ddff;"> </span><span style="color: #c792ea; font-style: italic;">for </span>t <span style="color: #c792ea; font-style: italic;">in </span>value<span style="color: #89ddff;">:<br /></span><span style="color: #89ddff;"> </span>messages<span style="color: #89ddff;">.</span><span style="color: #82aaff;">append</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"user"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">f"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">句子</span><span style="color: #c3e88d;">1</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">:</span><span style="color: #c3e88d;">[</span><span style="color: #89ddff;">{</span>t<span style="color: #89ddff;">[</span><span style="color: #f78c6c;">0</span><span style="color: #89ddff;">]}</span><span style="color: #c3e88d;">]</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">,句子</span><span style="color: #c3e88d;">2</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">:</span><span style="color: #c3e88d;">[</span><span style="color: #89ddff;">{</span>t<span style="color: #89ddff;">[</span><span style="color: #f78c6c;">1</span><span style="color: #89ddff;">]}</span><span style="color: #c3e88d;">]"</span><span style="color: #89ddff;">}<br /></span><span style="color: #89ddff;"> )<br /></span><span style="color: #89ddff;"> </span>messages<span style="color: #89ddff;">.</span><span style="color: #82aaff;">append</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"assistant"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span>key<span style="color: #89ddff;">}<br /></span><span style="color: #89ddff;"> )<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">提问数据<br /></span>questions <span style="color: #89ddff;">= [<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">利率上升,影响房地产市场。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">高利率对房地产有一定的冲击。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">油价大幅度下跌,能源公司面临挑战。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">未来智能城市的建设趋势越加明显。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">股票市场今日大涨,投资者乐观。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">持续上涨的市场让投资者感到满意。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">向模型提问<br /></span><span style="color: #c792ea; font-style: italic;">for </span>q <span style="color: #c792ea; font-style: italic;">in </span>questions<span style="color: #89ddff;">:<br /></span><span style="color: #89ddff;"> </span>response <span style="color: #89ddff;">= </span>client<span style="color: #89ddff;">.</span>chat<span style="color: #89ddff;">.</span>completions<span style="color: #89ddff;">.</span><span style="color: #82aaff;">create</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">model</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"qwen3.5-plus"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">messages</span><span style="color: #89ddff;">=</span>messages <span style="color: #89ddff;">+ [{</span><span style="color: #c3e88d;">"role"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"user"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"content"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">f"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">句子</span><span style="color: #c3e88d;">1</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">:</span><span style="color: #c3e88d;">[</span><span style="color: #89ddff;">{</span>q<span style="color: #89ddff;">[</span><span style="color: #f78c6c;">0</span><span style="color: #89ddff;">]}</span><span style="color: #c3e88d;">]</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">,句子</span><span style="color: #c3e88d;">2</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">:</span><span style="color: #c3e88d;">[</span><span style="color: #89ddff;">{</span>q<span style="color: #89ddff;">[</span><span style="color: #f78c6c;">1</span><span style="color: #89ddff;">]}</span><span style="color: #c3e88d;">]"</span><span style="color: #89ddff;">}]<br /></span><span style="color: #89ddff;"> )<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"> </span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>response<span style="color: #89ddff;">.</span>choices<span style="color: #89ddff;">[</span><span style="color: #f78c6c;">0</span><span style="color: #89ddff;">].</span>message<span style="color: #89ddff;">.</span>content<span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span></pre>
</div> |
1 |
60 |
1 |
2/17/26, 8:29 PM |
2/19/26, 6:48 AM |
View Edit Delete |
| 53 |
Langchain实现FewShot提示词模板 |
<div style="background-color: #0f111a; color: #c3cee3;">
<pre style="font-family: 'Source Code Pro',monospace; font-size: 12.0pt;"><span style="color: #c792ea; font-style: italic;">from </span>langchain_core<span style="color: #89ddff;">.</span>prompts <span style="color: #c792ea; font-style: italic;">import </span>PromptTemplate<span style="color: #89ddff;">, </span>FewShotPromptTemplate<br /><span style="color: #c792ea; font-style: italic;">from </span>langchain_community<span style="color: #89ddff;">.</span>llms<span style="color: #89ddff;">.</span>tongyi <span style="color: #c792ea; font-style: italic;">import </span>Tongyi<br /><span style="color: #c792ea; font-style: italic;">import </span>os<br /><span style="color: #c792ea; font-style: italic;">from </span>dotenv <span style="color: #c792ea; font-style: italic;">import </span>load_dotenv<br /><span style="color: #82aaff;">load_dotenv</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;">#</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">示例的模板<br /></span>example_template <span style="color: #89ddff;">= </span>PromptTemplate<span style="color: #89ddff;">.</span><span style="color: #82aaff;">from_template</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">单词:</span><span style="color: #c3e88d;">{word}</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">,反义词:</span><span style="color: #c3e88d;">{antonym}"<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;">#</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">示例的数据动态注入<br /></span>example_data <span style="color: #89ddff;">= [<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"word"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">大</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"antonym"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">小</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">},<br /></span><span style="color: #89ddff;"> {</span><span style="color: #c3e88d;">"word"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">上</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"antonym"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">下</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">},<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span>few_shot_template <span style="color: #89ddff;">= </span><span style="color: #82aaff;">FewShotPromptTemplate</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">提示词数据模板<br /></span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;"> </span><span style="color: #f78c6c;">example_prompt </span><span style="color: #89ddff;">= </span>example_template<span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">提示词的数据<br /></span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;"> </span><span style="color: #f78c6c;">examples </span><span style="color: #89ddff;">= </span>example_data<span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">示例之前的提示词<br /></span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;"> </span><span style="color: #f78c6c;">prefix </span><span style="color: #89ddff;">= </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">告知我单词的反义词,我提供如下的示例:</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">示例之后的提示词<br /></span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;"> </span><span style="color: #f78c6c;">suffix </span><span style="color: #89ddff;">= </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">基于前面的示例告诉我,</span><span style="color: #c3e88d;">{input_word}</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">的反义词是?</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">提示词的输入变量<br /></span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;"> </span><span style="color: #f78c6c;">input_variables </span><span style="color: #89ddff;">=[</span><span style="color: #c3e88d;">"input_word"</span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span>prompt_text <span style="color: #89ddff;">= </span>few_shot_template<span style="color: #89ddff;">.</span><span style="color: #82aaff;">format</span><span style="color: #89ddff;">(</span><span style="color: #f78c6c;">input_word</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">左</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">)<br /></span><span style="color: #717cb4; font-style: italic;"># print(prompt_text)<br /></span><span style="color: #717cb4; font-style: italic;"><br /></span>model <span style="color: #89ddff;">= </span><span style="color: #82aaff;">Tongyi</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">model</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"qwen-max"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>model<span style="color: #89ddff;">.</span><span style="color: #82aaff;">invoke</span><span style="color: #89ddff;">(</span><span style="color: #f78c6c;">input </span><span style="color: #89ddff;">= </span>prompt_text<span style="color: #89ddff;">))</span></pre>
</div> |
1 |
61 |
1 |
2/19/26, 6:30 AM |
2/19/26, 6:42 AM |
View Edit Delete |
| 54 |
Langchain调用通义千问的模型 |
<p>展示调用常用的3种模型</p>
<p>大语言模型、聊天模型、嵌入(向量)模型</p>
<p>1、大语言模型</p>
<div style="background-color: #0f111a; color: #c3cee3;">
<div>
<pre style="font-family: 'Source Code Pro',monospace; font-size: 12.0pt;"><span style="color: #c792ea; font-style: italic;">from </span>langchain_core<span style="color: #89ddff;">.</span>prompts <span style="color: #c792ea; font-style: italic;">import </span>PromptTemplate<br /><span style="color: #c792ea; font-style: italic;">from </span>langchain_community<span style="color: #89ddff;">.</span>llms<span style="color: #89ddff;">.</span>tongyi <span style="color: #c792ea; font-style: italic;">import </span>Tongyi<br /><span style="color: #c792ea; font-style: italic;">import </span>os<br /><span style="color: #c792ea; font-style: italic;">from </span>dotenv <span style="color: #c792ea; font-style: italic;">import </span>load_dotenv<br /><span style="color: #82aaff;">load_dotenv</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span>prompt_template <span style="color: #89ddff;">= </span>PromptTemplate<span style="color: #89ddff;">.</span><span style="color: #82aaff;">from_template</span><span style="color: #89ddff;">(</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">我朋友姓</span><span style="color: #c3e88d;">{lastname},</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">生了个孩子,性别</span><span style="color: #c3e88d;">{gender},</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">你帮他起个名字</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span>prompt_text <span style="color: #89ddff;">= </span>prompt_template<span style="color: #89ddff;">.</span><span style="color: #82aaff;">format</span><span style="color: #89ddff;">(</span><span style="color: #f78c6c;">lastname </span><span style="color: #89ddff;">= </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">张</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #f78c6c;">gender </span><span style="color: #89ddff;">= </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">女</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">)<br /></span>model <span style="color: #89ddff;">= </span><span style="color: #82aaff;">Tongyi</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #717cb4; font-style: italic;"># api_key=os.getenv("DASHSCOPE_API_KEY"),<br /></span><span style="color: #717cb4; font-style: italic;"> </span><span style="color: #f78c6c;">model</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"qwen-max"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">一次性返回结果<br /></span><span style="color: #717cb4; font-style: italic;"># res = model.invoke(input="</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">你是谁呀能做什么?</span><span style="color: #717cb4; font-style: italic;">")<br /></span><span style="color: #717cb4; font-style: italic;"><br /></span><span style="color: #717cb4; font-style: italic;"># langchain</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">一次性返回结果方式输出<br /></span><span style="color: #717cb4; font-style: italic;"># chain = prompt_template | model<br /></span><span style="color: #717cb4; font-style: italic;"># print(chain.invoke({"lastname": "</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">张</span><span style="color: #717cb4; font-style: italic;">", "gender": "</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">女</span><span style="color: #717cb4; font-style: italic;">"}))<br /></span><span style="color: #717cb4; font-style: italic;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">流式输出<br /></span><span style="color: #717cb4; font-style: italic;"># for res in model.stream(input=prompt_text):<br /></span><span style="color: #717cb4; font-style: italic;"># for chunk in res:<br /></span><span style="color: #717cb4; font-style: italic;"># print(chunk, end="",flush=True)<br /></span><span style="color: #717cb4; font-style: italic;"><br /></span><span style="color: #717cb4; font-style: italic;"># langchain </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">流式返回结果方式输出<br /></span>chain <span style="color: #89ddff;">= </span>prompt_template <span style="color: #89ddff;">| </span>model<br /><span style="color: #c792ea; font-style: italic;">for </span>res <span style="color: #c792ea; font-style: italic;">in </span>chain<span style="color: #89ddff;">.</span><span style="color: #82aaff;">stream</span><span style="color: #89ddff;">({</span><span style="color: #c3e88d;">"lastname"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">张</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"gender"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">女</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">}):<br /></span><span style="color: #89ddff;"> </span><span style="color: #c792ea; font-style: italic;">for </span>chunk <span style="color: #c792ea; font-style: italic;">in </span>res<span style="color: #89ddff;">:<br /></span><span style="color: #89ddff;"> </span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>chunk<span style="color: #89ddff;">, </span><span style="color: #f78c6c;">end</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">""</span><span style="color: #89ddff;">,</span><span style="color: #f78c6c;">flush</span><span style="color: #89ddff;">=</span><span style="color: #c792ea; font-style: italic;">True</span><span style="color: #89ddff;">)</span></pre>
</div>
</div>
<p> </p>
<p>2、聊天模型</p>
<div style="background-color: #0f111a; color: #c3cee3;">
<div>
<pre style="font-family: 'Source Code Pro',monospace; font-size: 12.0pt;"><span style="color: #c792ea; font-style: italic;">from </span>langchain_community<span style="color: #89ddff;">.</span>chat_models<span style="color: #89ddff;">.</span>tongyi <span style="color: #c792ea; font-style: italic;">import </span>ChatTongyi<br /><span style="color: #c792ea; font-style: italic;">from </span>langchain_core<span style="color: #89ddff;">.</span>messages <span style="color: #c792ea; font-style: italic;">import </span>HumanMessage<span style="color: #89ddff;">,</span>SystemMessage<span style="color: #89ddff;">,</span>AIMessage<br /><br /><span style="color: #c792ea; font-style: italic;">import </span>os<br /><span style="color: #c792ea; font-style: italic;">from </span>dotenv <span style="color: #c792ea; font-style: italic;">import </span>load_dotenv<br /><span style="color: #82aaff;">load_dotenv</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span>model <span style="color: #89ddff;">= </span><span style="color: #82aaff;">ChatTongyi</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #717cb4; font-style: italic;"># api_key=os.getenv("DASHSCOPE_API_KEY"),<br /></span><span style="color: #717cb4; font-style: italic;"> </span><span style="color: #f78c6c;">model</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"qwen3-max"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;">#</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">准备消息列表<br /></span><span style="color: #717cb4; font-style: italic;"># messages = [<br /></span><span style="color: #717cb4; font-style: italic;"># SystemMessage(content="</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">你是一个边塞诗人。</span><span style="color: #717cb4; font-style: italic;">"),<br /></span><span style="color: #717cb4; font-style: italic;"># HumanMessage(content="</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">写一首唐诗</span><span style="color: #717cb4; font-style: italic;">"),<br /></span><span style="color: #717cb4; font-style: italic;"># AIMessage(content="</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">《杜侍御送贡物戏》 铜柱朱崖道路难,伏波横海旧登坛。越人自贡珊瑚树,汉使何劳獬豸冠。疲马山中愁日晚,孤舟江上畏春寒。由来此货称难得,多恐君王不忍看。</span><span style="color: #717cb4; font-style: italic;">"),<br /></span><span style="color: #717cb4; font-style: italic;"># HumanMessage(content="</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">请继续按照上面的格式写诗</span><span style="color: #717cb4; font-style: italic;">"),<br /></span><span style="color: #717cb4; font-style: italic;"># ]<br /></span><span style="color: #717cb4; font-style: italic;"><br /></span><span style="color: #717cb4; font-style: italic;">#</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">简写方式,可避免导包,可在呢内容用</span><span style="color: #717cb4; font-style: italic;">{</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">变量</span><span style="color: #717cb4; font-style: italic;">}</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">占位<br /></span>messages <span style="color: #89ddff;">= [(<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"system"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">你是一个边塞诗人。</span><span style="color: #c3e88d;">"<br /></span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"human"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">写一首唐诗</span><span style="color: #c3e88d;">"<br /></span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"ai"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">《杜侍御送贡物戏》 铜柱朱崖道路难,伏波横海旧登坛。越人自贡珊瑚树,汉使何劳獬豸冠。疲马山中愁日晚,孤舟江上畏春寒。由来此货称难得,多恐君王不忍看。</span><span style="color: #c3e88d;">"<br /></span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"human"</span><span style="color: #89ddff;">,<br /></span><span style="color: #89ddff;"> </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">请继续按照上面的格式写诗</span><span style="color: #c3e88d;">"<br /></span><span style="color: #89ddff;">)]<br /></span><span style="color: #89ddff;"><br /></span>res <span style="color: #89ddff;">= </span>model<span style="color: #89ddff;">.</span><span style="color: #82aaff;">stream</span><span style="color: #89ddff;">(</span><span style="color: #f78c6c;">input</span><span style="color: #89ddff;">=</span>messages<span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">流式输出<br /></span><span style="color: #c792ea; font-style: italic;">for </span>chunk <span style="color: #c792ea; font-style: italic;">in </span>res<span style="color: #89ddff;">:<br /></span><span style="color: #89ddff;"> </span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>chunk<span style="color: #89ddff;">.</span>content<span style="color: #89ddff;">, </span><span style="color: #f78c6c;">end</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">""</span><span style="color: #89ddff;">,</span><span style="color: #f78c6c;">flush</span><span style="color: #89ddff;">=</span><span style="color: #c792ea; font-style: italic;">True</span><span style="color: #89ddff;">)</span></pre>
</div>
</div>
<p> </p>
<p>3、嵌入模型</p>
<div style="background-color: #0f111a; color: #c3cee3;">
<pre style="font-family: 'Source Code Pro',monospace; font-size: 12.0pt;"><span style="color: #c792ea; font-style: italic;">from </span>langchain_community<span style="color: #89ddff;">.</span>embeddings <span style="color: #c792ea; font-style: italic;">import </span>DashScopeEmbeddings<br /><br /><span style="color: #c792ea; font-style: italic;">import </span>os<br /><span style="color: #c792ea; font-style: italic;">from </span>dotenv <span style="color: #c792ea; font-style: italic;">import </span>load_dotenv<br /><span style="color: #82aaff;">load_dotenv</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">创建模型对象 不传</span><span style="color: #717cb4; font-style: italic;">model</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">默认用的是</span><span style="color: #717cb4; font-style: italic;"> text-embeddings-v1<br /></span>model <span style="color: #89ddff;">= </span><span style="color: #82aaff;">DashScopeEmbeddings</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>model<span style="color: #89ddff;">.</span><span style="color: #82aaff;">embed_query</span><span style="color: #89ddff;">(</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">我喜欢你</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">))<br /></span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>model<span style="color: #89ddff;">.</span><span style="color: #82aaff;">embed_documents</span><span style="color: #89ddff;">([</span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">我喜欢你</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">你喜欢我</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">]))</span></pre>
</div>
<p> </p> |
1 |
61 |
1 |
2/19/26, 6:38 AM |
2/19/26, 12:07 PM |
View Edit Delete |
| 55 |
Langchain的ChatPromptTemplate结合chain的基本案例 |
<div style="background-color: #0f111a; color: #c3cee3;">
<div>
<pre style="font-family: 'Source Code Pro',monospace; font-size: 12.0pt;"><span style="color: #c792ea; font-style: italic;">from </span>langchain_core<span style="color: #89ddff;">.</span>output_parsers <span style="color: #c792ea; font-style: italic;">import </span>StrOutputParser<span style="color: #89ddff;">, </span>JsonOutputParser<br /><span style="color: #c792ea; font-style: italic;">from </span>langchain_core<span style="color: #89ddff;">.</span>prompts <span style="color: #c792ea; font-style: italic;">import </span>ChatPromptTemplate<span style="color: #89ddff;">, </span>MessagesPlaceholder<br /><span style="color: #c792ea; font-style: italic;">from </span>langchain_community<span style="color: #89ddff;">.</span>chat_models<span style="color: #89ddff;">.</span>tongyi <span style="color: #c792ea; font-style: italic;">import </span>ChatTongyi<br /><br /><span style="color: #c792ea; font-style: italic;">from </span>dotenv <span style="color: #c792ea; font-style: italic;">import </span>load_dotenv<br /><span style="color: #c792ea; font-style: italic;">from </span>langchain_core<span style="color: #89ddff;">.</span>runnables <span style="color: #c792ea; font-style: italic;">import </span>RunnableLambda<br /><br /><span style="color: #82aaff;">load_dotenv</span><span style="color: #89ddff;">()<br /></span><span style="color: #89ddff;"><br /></span>history_data <span style="color: #89ddff;">= [<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"human"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">你来写一首诗?</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"ai"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">归园田居(其三) 种豆南山下,草盛豆苗稀。晨兴理荒秽,带月荷锄归。道狭草木长,夕露沾我衣。衣沾不足惜,但使愿无违。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"human"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">好诗,再来一首</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"ai"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">饮酒(其五) 结庐在人境,而无车马喧。问君何能尔,心远地自偏。采菊东篱下,悠然见南山。山气日夕佳,飞鸟相与还。此中有真意,欲辨已忘言。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;">]<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># first_prompt_template = ChatPromptTemplate.from_messages([<br /></span><span style="color: #717cb4; font-style: italic;"># ("system", "</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">你是一个世外高人,不予世俗同流合污,以作诗表达心中所想</span><span style="color: #717cb4; font-style: italic;">,</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">并封装成</span><span style="color: #717cb4; font-style: italic;">JSON</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">格式返回给我。要求</span><span style="color: #717cb4; font-style: italic;">key</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">是</span><span style="color: #717cb4; font-style: italic;">poetry</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">,</span><span style="color: #717cb4; font-style: italic;">value</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">是你作的诗</span><span style="color: #717cb4; font-style: italic;">"),<br /></span><span style="color: #717cb4; font-style: italic;"># MessagesPlaceholder(variable_name="chat_history"),<br /></span><span style="color: #717cb4; font-style: italic;"># ("human", "{input}"),<br /></span><span style="color: #717cb4; font-style: italic;"># ])<br /></span><span style="color: #717cb4; font-style: italic;"><br /></span>first_prompt_template <span style="color: #89ddff;">= </span>ChatPromptTemplate<span style="color: #89ddff;">.</span><span style="color: #82aaff;">from_messages</span><span style="color: #89ddff;">([<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"system"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">你是一个世外高人,不予世俗同流合污,以作诗表达心中所感。</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> </span><span style="color: #82aaff;">MessagesPlaceholder</span><span style="color: #89ddff;">(</span><span style="color: #f78c6c;">variable_name</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">"chat_history"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"human"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"{input}"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;">])<br /></span><span style="color: #89ddff;"><br /></span>second_prompt_template <span style="color: #89ddff;">= </span>ChatPromptTemplate<span style="color: #89ddff;">.</span><span style="color: #82aaff;">from_messages</span><span style="color: #89ddff;">([<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"ai"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">上一首诗是:</span><span style="color: #c3e88d;">{poetry}"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;"> (</span><span style="color: #c3e88d;">"human"</span><span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">帮我解释一下诗名和每一句诗的意思</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">),<br /></span><span style="color: #89ddff;">])<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">自定义函数<br /></span>myfun <span style="color: #89ddff;">= </span><span style="color: #82aaff;">RunnableLambda</span><span style="color: #89ddff;">(</span><span style="color: #c792ea; font-style: italic;">lambda </span>ai_msg<span style="color: #89ddff;">:{</span><span style="color: #c3e88d;">"poetry" </span><span style="color: #89ddff;">: </span>ai_msg<span style="color: #89ddff;">.</span>content<span style="color: #89ddff;">}) </span><span style="color: #717cb4; font-style: italic;">#type: ignore<br /></span><span style="color: #717cb4; font-style: italic;"><br /></span>model <span style="color: #89ddff;">= </span><span style="color: #82aaff;">ChatTongyi</span><span style="color: #89ddff;">(<br /></span><span style="color: #89ddff;"> </span><span style="color: #f78c6c;">model </span><span style="color: #89ddff;">= </span><span style="color: #c3e88d;">"qwen3-max"<br /></span><span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span>str_parser <span style="color: #89ddff;">= </span><span style="color: #82aaff;">StrOutputParser</span><span style="color: #89ddff;">()<br /></span>json_parser <span style="color: #89ddff;">= </span><span style="color: #82aaff;">JsonOutputParser</span><span style="color: #89ddff;">()<br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">前一个输出等于下一个输入,必须是</span><span style="color: #717cb4; font-style: italic;">Runnable</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">接口的子类,自定义函数入链需要遵守这个规则<br /></span>chain <span style="color: #89ddff;">= (</span>first_prompt_template <span style="color: #89ddff;">| </span>model<br /> <span style="color: #717cb4; font-style: italic;"># json_parser<br /></span><span style="color: #717cb4; font-style: italic;"> </span><span style="color: #89ddff;">| </span>myfun<br /> <span style="color: #89ddff;">| </span>second_prompt_template <span style="color: #89ddff;">| </span>model <span style="color: #89ddff;">| </span>str_parser<span style="color: #89ddff;">)<br /></span><span style="color: #89ddff;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">直接输出<br /></span><span style="color: #717cb4; font-style: italic;"># print(chain.invoke({"chat_history":history_data, "input": "</span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">再来一首诗</span><span style="color: #717cb4; font-style: italic;">"}).content)<br /></span><span style="color: #717cb4; font-style: italic;"><br /></span><span style="color: #717cb4; font-style: italic;"># </span><span style="color: #717cb4; font-style: italic; font-family: 'Courier New',monospace;">流式输出<br /></span><span style="color: #c792ea; font-style: italic;">for </span>chunk <span style="color: #c792ea; font-style: italic;">in </span>chain<span style="color: #89ddff;">.</span><span style="color: #82aaff;">stream</span><span style="color: #89ddff;">({</span><span style="color: #c3e88d;">"chat_history"</span><span style="color: #89ddff;">:</span>history_data<span style="color: #89ddff;">, </span><span style="color: #c3e88d;">"input"</span><span style="color: #89ddff;">: </span><span style="color: #c3e88d;">"</span><span style="color: #c3e88d; font-family: 'Courier New',monospace;">再来一首诗</span><span style="color: #c3e88d;">"</span><span style="color: #89ddff;">}):<br /></span><span style="color: #89ddff;"> </span><span style="color: #82aaff; font-style: italic;">print</span><span style="color: #89ddff;">(</span>chunk<span style="color: #89ddff;">, </span><span style="color: #f78c6c;">end</span><span style="color: #89ddff;">=</span><span style="color: #c3e88d;">""</span><span style="color: #89ddff;">, </span><span style="color: #f78c6c;">flush</span><span style="color: #89ddff;">=</span><span style="color: #c792ea; font-style: italic;">True</span><span style="color: #89ddff;">)</span></pre>
</div>
</div> |
1 |
61 |
1 |
2/19/26, 7:43 AM |
2/19/26, 3:32 PM |
View Edit Delete |
| 56 |
Ubuntu24.04安装redis并设置初始密码和允许远程登录 |
<p>1、安装redis</p>
<pre class=""><code class="hljs language-undefined">sudo apt install redis-server</code></pre>
<p> </p>
<p>2、查看redis版本</p>
<pre class=""><code class="hljs language-css">redis-server --version</code></pre>
<p> </p>
<p>3、编辑配置文件,用于设置密码</p>
<pre class=""><code class="hljs language-bash">sudo vim /etc/redis/redis.conf</code></pre>
<p> </p>
<p>4、找到# requirepass foobared 这一行,去掉井号空格,让r定格写,把foobared替换成你的密码</p>
<pre class=""><code class="hljs language-undefined">requirepass timeless_password</code></pre>
<p>5、找到bind 127.0.0.1 -::-1 改为</p>
<pre class=""><code class="hljs language-bash">bind 0.0.0.0 ::</code></pre>
<p> </p>
<p>6、重启redis服务</p>
<pre class=""><code class="hljs language-undefined">sudo systemctl restart redis-server</code></pre> |
1 |
34 |
1 |
2/21/26, 2:08 PM |
2/24/26, 4:20 PM |
View Edit Delete |
| 57 |
Ubuntu24.04安装Milvus |
<p>1、创建目录并下载docker的yml文件</p>
<pre class=""><code class="language-bash hljs">sudo mkdir /Milvus && cd /Milvus
wget https://github.com/milvus-io/milvus/releases/download/v2.6.11/milvus-standalone-docker-compose.yml -O docker-compose.yml</code></pre>
<p> </p>
<p>2、根据服务器的实际情况修改yml文件</p>
<pre class=""><code class="language-yaml hljs">services:
etcd:
container_name: milvus-etcd
image: quay.io/coreos/etcd:v3.5.25
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
- ETCD_SNAPSHOT_COUNT=50000
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd
command: etcd -advertise-client-urls=http://etcd:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
healthcheck:
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 30s
timeout: 20s
retries: 3
minio:
container_name: milvus-minio
image: minio/minio:RELEASE.2024-12-18T13-15-44Z
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
ports:
- "9001:9001"
- "9000:9000"
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data
command: minio server /minio_data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
mem_limit: 1g
cpus: 0.5
standalone:
container_name: milvus-standalone
image: milvusdb/milvus:v2.6.11
command: ["milvus", "run", "standalone"]
security_opt:
- seccomp:unconfined
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
MQ_TYPE: woodpecker
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
interval: 30s
start_period: 90s
timeout: 20s
retries: 3
ports:
- "19530:19530"
- "9091:9091"
depends_on:
- "etcd"
- "minio"
mem_limit: 2g # 4G内存需严格限制2GB,留2G给系统
cpus: 1.5 # 双核服务器需严格限制1.5核(留0.5核给系统)
networks:
default:
name: milvus
</code></pre>
<p> </p>
<p>3、启动docker</p>
<pre class=""><code class="hljs language-undefined">docker compse up -d</code></pre>
<p> </p>
<p>4、Python脚本测试</p>
<pre class=""><code class="hljs language-python">from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection
# 连接到 Milvus 服务(默认端口 19530)
connections.connect("default", host="localhost", port="19530")
# 创建集合(类似建表)
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=128)
]
schema = CollectionSchema(fields, "demo collection")
collection = Collection("demo_collection", schema)
# 插入数据
import random
vectors = [[random.random() for _ in range(128)] for _ in range(10)]
collection.insert([vectors])
# 创建索引
index_params = {"index_type": "IVF_FLAT", "metric_type": "L2", "params": {"nlist": 128}}
collection.create_index("embedding", index_params)
# 搜索
collection.load()
query_vector = [[random.random() for _ in range(128)]]
results = collection.search(query_vector, "embedding", {"metric_type": "L2"}, limit=3)
print(results)</code></pre>
<p> </p>
<p>5、Restful API 测试</p>
<pre class=""><code class="hljs language-sql">curl -X GET "http://localhost:19531/collections"</code></pre>
<p> </p>
<p>6、测试官方没提供cli工具,有第三方的工具mivlus -cli,但是不推荐</p>
<pre class=""><code class="hljs language-css">pip install milvus-cli
milvus_cli
# 然后在交互界面中 connect --host localhost --port 19530</code></pre> |
1 |
34 |
1 |
2/24/26, 4:25 PM |
2/24/26, 5:36 PM |
View Edit Delete |
| 58 |
Ubuntu24.04安装Tesseract OCR |
<p>1、安装</p>
<pre class=""><code class="hljs language-bash">sudo apt update
sudo apt install -y tesseract-ocr
sudo apt install -y tesseract-ocr-chi-sim # 中文简体
sudo apt install -y tesseract-ocr-eng # 英文</code></pre>
<p> </p>
<p>2、验证安装</p>
<pre class=""><code class="language-bash hljs">tesseract --version</code></pre>
<p> </p>
<p>3、测试中文识别</p>
<pre class=""><code class="hljs language-bash">echo "测试中文" > test.txt
tesseract test.txt stdout -l chi_sim</code></pre>
<p> </p> |
1 |
34 |
1 |
2/24/26, 4:28 PM |
2/24/26, 4:29 PM |
View Edit Delete |
| 59 |
Windows 11 安装WSL |
<p>1、管理员权限打开PowerShell</p>
<p>2、安装 Windows 子系统 for Linux (WSL) 功能,但不自动安装任何具体的 Linux 发行版。</p>
<pre class=""><code class="hljs language-css">wsl --install --no-distribution</code></pre>
<p> </p>
<p>3、查看在线可安装系统(有时候网络不好会报错)</p>
<pre class=""><code class="hljs language-css">wsl --list --online</code></pre>
<p> </p>
<p>4、安装其中某一个系统,根据提示输入用户名和密码</p>
<pre class=""><code class="hljs language-css">wsl --install -d Ubuntu-24.04</code></pre>
<p><br />5、Ubuntu24.04镜像</p>
<pre class=""><code class="hljs language-cpp">sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo vim /etc/apt/sources.list
deb https://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse</code></pre>
<p> </p>
<p> </p> |
1 |
68 |
1 |
2/27/26, 4:50 PM |
3/2/26, 3:02 PM |
View Edit Delete |
| 60 |
Windows 11 安装NVM |
<p>https://github.com/coreybutler/nvm-windows/releases</p>
<p>0、powershell 一般权限不够需要以管理员运行powershell并执行下面语句开放更高权限,但建议还是cmd最直接</p>
<pre class=""><code class="hljs language-sql">Set-ExecutionPolicy RemoteSigned -Scope CurrentUser </code></pre>
<p> </p>
<p>1、安装NVM并查看版本</p>
<p>点击EXE文件安装,安装完新建cmd输入下面命令测试看版本,</p>
<pre class=""><code class="hljs language-undefined">nvm version</code></pre>
<p>2、添加镜像</p>
<pre class=""><code class="hljs language-ruby">nvm node_mirror https://npmmirror.com/mirrors/node/
nvm npm_mirror https://npmmirror.com/mirrors/npm/</code></pre>
<p> </p>
<p>3、安装特定版本node</p>
<pre class=""><code class="hljs language-undefined">nvm install 22.14.0</code></pre>
<p> </p>
<p>4、使用特定版本node</p>
<pre class=""><code class="language-perl hljs">nvm use 22.14.0</code></pre>
<p> </p>
<p>5、查看版本是否生效</p>
<pre class=""><code class="hljs language-undefined">node -v
npm -v</code></pre>
<p> </p> |
1 |
68 |
1 |
2/27/26, 8:12 PM |
2/27/26, 8:18 PM |
View Edit Delete |
| 61 |
Git 基本命令 |
<p>1、设置签名</p>
<pre class=""><code class="hljs language-lua">git config --global user.name Timeless</code></pre>
<p> </p>
<p>2、设置邮箱,邮箱尽量和github保持一致</p>
<pre class=""><code class="language-bash hljs">git config --global user.email xxxxx@xxxx.com</code></pre>
<p> </p>
<p>3、查看git配置信息</p>
<pre class=""><code class="language-bash hljs">git config --list</code></pre>
<p> </p>
<p>4、初始化本地库</p>
<pre class=""><code class="language-bash hljs">git init</code></pre>
<p> </p>
<p>5、状态,显示分支以及待提交文件等状态</p>
<pre class=""><code class="language-cpp hljs">git status
git status -s //简略显示</code></pre>
<p> </p>
<p>6、添加到暂存区</p>
<pre class=""><code class="language-bash hljs">git add xxx.xx
git add .</code></pre>
<p> </p>
<p>7、查看暂存区文件</p>
<pre class=""><code class="hljs language-bash">git ls files</code></pre>
<p> </p>
<p>8、从暂存区里面删除某文件</p>
<pre class=""><code class="language-bash hljs">git rm --cached xxx.xx</code></pre>
<p> </p>
<p>9、从暂存区提交到git(本地)库</p>
<pre class=""><code class="hljs language-sql">git commit -m "first commit" xxx.xx</code></pre>
<p> </p>
<p>10、查看精简历史日志</p>
<pre class=""><code class="hljs language-css">git reflog
git reflog --online</code></pre>
<p> </p>
<p>11、查看详细日志</p>
<pre class=""><code class="hljs language-lua">git log
git log --online</code></pre>
<p> </p>
<p>12、切换版本</p>
<pre class=""><code class="language-bash hljs">git reset --hard xxxxx(xxxxx为git reflog中查出来的版本号)</code></pre>
<p> </p>
<p>13、从暂存区恢复到本地</p>
<pre class=""><code class="language-bash hljs">git restore page/login/index.css</code></pre>
<p><br />14、版本回退</p>
<pre class=""><code class="hljs language-perl">git reset --soft 版本号(其他文件未跟踪)
git reset --hard 版本号
git reset --mixed 版本号(与git reset等价)</code></pre>
<p> </p>
<p>15、忽略文件</p>
<pre class=""><code class="language-bash hljs">.gitignore
node_modules
dist
.vscode
*.pem
*.log</code></pre>
<p> </p>
<p>16、创建分支</p>
<pre class=""><code class="language-bash hljs">git branch 分支名</code></pre>
<p> </p>
<p>17、切换分支</p>
<pre class=""><code class="hljs language-undefined">git checkout 分支名</code></pre>
<p> </p>
<p>18、//查看当前git有哪些分支</p>
<pre class=""><code class="language-bash hljs">git branch</code></pre>
<p> </p>
<p>19、分支的合并与删除</p>
<pre class=""><code class="language-bash hljs"># 1、切回到要合入的分支上:
git checkout master
# 2、合并其他分支过来:
git merge slaver1
# 3、删除合并后的分支指针:
git branch -d slaver1</code></pre>
<p> </p>
<p>20、<span class="qk-md-strong" style="-webkit-font-smoothing: antialiased; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgba(59,130,246,.5); --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-shadow: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-shadow-colored: 0 0 transparent; box-sizing: border-box; border: 0px solid; font-weight: 600; opacity: 1; color: #060a26; font-family: 'PingFang SC', 'Helvetica Neue', -apple-system, BlinkMacSystemFont, STHeiti, 'Microsoft Yahei', Simsun, Tahoma, 'Apple Color Emoji', 'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', sans-serif; font-size: 14px; background-color: #ffffff; animation: auto ease 0s 1 normal none running none !important;"><span class="qk-md-text complete" style="-webkit-font-smoothing: antialiased; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgba(59,130,246,.5); --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-shadow: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-shadow-colored: 0 0 transparent; box-sizing: border-box; border: 0px solid; opacity: 1; animation: auto ease 0s 1 normal none running none !important;" data-spm-anchor-id="5176.28103460.0.i11.96a075516xBJU4">管理</span></span><span class="qk-md-text complete" style="-webkit-font-smoothing: antialiased; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgba(59,130,246,.5); --tw-ring-offset-shadow: 0 0 transparent; --tw-ring-shadow: 0 0 transparent; --tw-shadow: 0 0 transparent; --tw-shadow-colored: 0 0 transparent; box-sizing: border-box; border: 0px solid; color: #060a26; margin-bottom: 0px; opacity: 1; font-family: 'PingFang SC', 'Helvetica Neue', -apple-system, BlinkMacSystemFont, STHeiti, 'Microsoft Yahei', Simsun, Tahoma, 'Apple Color Emoji', 'Segoe UI', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', sans-serif; font-size: 14px; background-color: #ffffff; animation: auto ease 0s 1 normal none running none !important;">远程地址</span></p>
<pre class=""><code class="language-bash hljs"># 1、添加远程仓库地址(通常别名为 origin):
git remote add origin <远程仓库URL>
# 2、验证是否添加成功:
git remote -v
# 3、(可选) 如果地址填错了,先删除再重新添加:
git remote remove origin
git remote add origin <正确的远程仓库URL></code></pre>
<p> </p>
<p>21、从零开始获取项目(克隆)</p>
<pre class=""><code class="hljs language-bash"># 1、克隆远程仓库到本地当前目录:
git clone <远程仓库URL>
# 2、(进阶) 只克隆指定的分支(节省时间):
git clone -b <分支名> <远程仓库URL></code></pre>
<p> </p>
<p>22、日常同步代码(拉取)</p>
<pre class=""><code class="hljs language-bash"># 1、拉取远程最新代码并自动合并到当前分支:
git pull origin <远程分支名>
# 2、(推荐) 拉取并变基(保持提交历史是一条直线,更整洁):
git pull --rebase origin <远程分支名>
# 3、(分步做法) 先抓取但不合并,查看情况后再手动合并:
git fetch origin
git merge origin/<远程分支名></code></pre>
<p> </p>
<p>23、提交代码到远程(推送)</p>
<pre class=""><code class="language-bash hljs"># 1、首次推送(建立本地分支与远程分支的追踪关系):
git push -u origin <本地分支名>
# 2、后续推送(因为建立了追踪,可以直接简写):
git push
# 3、强制推送(危险:覆盖远程历史,仅在 reset 回退后使用):
git push -f origin <本地分支名></code></pre> |
1 |
52 |
1 |
2/27/26, 8:38 PM |
2/27/26, 8:38 PM |
View Edit Delete |
| 62 |
Windows 11 下使Python3.12 支持 Pytorch GPU版 |
<p>1、下载并安装Visual Studio</p>
<pre class=""><code class="hljs language-bash">https://visualstudio.microsoft.com/</code></pre>
<p><br />2、下载CUDA并安装</p>
<pre class=""><code class="hljs language-bash">https://developer.nvidia.com/cuda-downloads</code></pre>
<p> </p>
<p>3、给Python创建一个虚拟环境</p>
<pre class=""><code class="language-bash hljs">python -m venv PyTorchEnv
cd PyTorchEnv\Scripts
# 如果是Powershell
#如果遇到安全问题,输入以下命令按Y
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
#然后再执行下面语句 进入虚拟环境
.\Activate.ps1
# 如果是cmd,直接执行activate即可
activate</code></pre>
<p><br /><br />4、在虚拟环境下,下载安装Pytorch,这样可以避免和主Python依赖冲突</p>
<pre class=""><code class="hljs language-perl">https://pytorch.org/
# 自己在网页上挑选自己适合的版本
pip3 install torch torchvision --index-url https://download.pytorch.org/whl/cu130</code></pre>
<p> </p>
<p>5、查看是否安装成功</p>
<pre class=""><code class="hljs language-undefined">pip list</code></pre>
<pre class=""><code class="hljs language-undefined">torch 2.10.0+cu130
torchvision 0.25.0+cu130</code></pre>
<p><br />6、设置pip镜像</p>
<pre class=""><code class="language-csharp hljs">pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip config set install.trusted-host mirrors.aliyun.com</code></pre>
<p> </p>
<p>7、退出虚拟环境</p>
<pre class=""><code class="hljs language-undefined">deactivate</code></pre> |
1 |
68 |
1 |
2/27/26, 10:02 PM |
3/2/26, 3:08 PM |
View Edit Delete |
| 63 |
TensorFlow利用LSTM训练MQL5的数据 |
<p>1、Tensorflow在windows上2.10版本过后就不支持GPU训练了</p>
<p>2、Python关于MT5的库也只支持windows。</p>
<p>3、综上所述,本篇笔记推荐的环境是win10的系统、4090以下的显卡。但很明显这样终将被淘汰。目前已经转PyTorch。但MT5对PyTorch转的onnx模型的GPU运行支持度还不够完美,期待MT5更新。</p>
<pre class=""><code class="language-python hljs"># python libraries
import MetaTrader5 as mt5
import tensorflow as tf
import numpy as np
import pandas as pd
import tf2onnx
# input parameters
inp_model_name = "model.eurusd.H1.120_old.onnx"
inp_history_size = 120
if not mt5.initialize():
print("initialize() failed, error code =", mt5.last_error())
quit()
# we will save generated onnx-file near our script to use as resource
from sys import argv
data_path = argv[0]
last_index = data_path.rfind("\\") + 1
data_path = data_path[0:last_index]
print("data path to save onnx model", data_path)
# set start and end dates for history data
from datetime import timedelta, datetime
# end_date = datetime.now()
end_date = datetime(2023, 1, 1, 0)
start_date = end_date - timedelta(days=inp_history_size)
# print start and end dates
print("data start date =", start_date)
print("data end date =", end_date)
# get rates
eurusd_rates = mt5.copy_rates_range("EURUSD", mt5.TIMEFRAME_H1, start_date, end_date)
# create dataframe
df = pd.DataFrame(eurusd_rates)
# get close prices only
data = df.filter(['close']).values
# scale data
from sklearn.preprocessing import MinMaxScaler
# MinMaxScaler:一个用于数据归一化的工具,将数据的值缩放到指定的范围,这里是[0, 1]。
# fit_transform():将scaler适配到数据并对其进行变换。
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(data)
# training_size:定义训练集的大小,占总数据的80%。
# 将数据分为训练集(train_data_initial)和测试集(test_data_initial)。
# training size is 80% of the data
training_size = int(len(scaled_data) * 0.80)
print("Training_size:", training_size)
train_data_initial = scaled_data[0:training_size, :]
test_data_initial = scaled_data[training_size:, :1]
# split_sequence():将时间序列数据分割成输入(X)和输出(y)序列。n_steps是输入序列的长度,输出是下一个时间点的预测值。
# 例如,输入的时间步长为n_steps,输出为时间步长后的下一个值。
def split_sequence(sequence, n_steps):
X, y = list(), list()
for i in range(len(sequence)):
# find the end of this pattern
end_ix = i + n_steps
# check if we are beyond the sequence
if end_ix > len(sequence) - 1:
break
# gather input and output parts of the pattern
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return np.array(X), np.array(y)
# 拆分训练集和测试集数据
# 将训练集和测试集数据传入 split_sequence 函数,将数据转换为时间序列输入输出对。
time_step = inp_history_size
x_train, y_train = split_sequence(train_data_initial, time_step)
x_test, y_test = split_sequence(test_data_initial, time_step)
# 调整数据形状以适应LSTM
# LSTM模型要求输入的数据形状为 [样本数, 时间步长, 特征数],这里每个数据点只有一个特征(即收盘价),因此将输入数据的形状调整为 (样本数, 时间步长, 1)。
x_train = x_train.reshape(x_train.shape[0], x_train.shape[1], 1)
x_test = x_test.reshape(x_test.shape[0], x_test.shape[1], 1)
# define model
from keras.models import Sequential
from keras.layers import Dense, Activation, Conv1D, MaxPooling1D, Dropout, Flatten, LSTM
from keras.metrics import RootMeanSquaredError as rmse
# Sequential:初始化一个线性堆叠的模型。
# Conv1D:一维卷积层,用于提取时间序列中的局部特征。
# MaxPooling1D:最大池化层,用于减少数据的维度。
# LSTM:长短期记忆层,擅长处理时间序列数据。
# Dropout:丢弃层,防止过拟合。
# Dense:全连接层,用于输出预测值。
# compile:编译模型,指定优化器、损失函数和评估指标(均方误差和RMSE)。
model = Sequential()
model.add(Conv1D(filters=256, kernel_size=2, activation='relu', padding='same', input_shape=(inp_history_size, 1)))
model.add(MaxPooling1D(pool_size=2))
model.add(LSTM(100, return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(100, return_sequences=False))
model.add(Dropout(0.3))
model.add(Dense(units=1, activation='sigmoid'))
model.compile(optimizer='adam', loss='mse', metrics=[rmse()])
# model.fit():训练模型,使用训练数据训练300个周期,并在每个周期后使用验证数据进行验证。
# epochs=300:训练300个周期。
# batch_size=32:每次梯度更新时使用32个样本。
# verbose=2:显示每个周期的训练进度。
history = model.fit(x_train, y_train, epochs=300, validation_data=(x_test, y_test), batch_size=32, verbose=2)
# 评估模型在训练集和测试集上的表现
# 使用训练集和测试集对模型进行评估,输出损失值和根均方误差(RMSE)
train_loss, train_rmse = model.evaluate(x_train, y_train, batch_size=32)
print(f"train_loss={train_loss:.3f}")
print(f"train_rmse={train_rmse:.3f}")
test_loss, test_rmse = model.evaluate(x_test, y_test, batch_size=32)
print(f"test_loss={test_loss:.3f}")
print(f"test_rmse={test_rmse:.3f}")
# save model to ONNX
output_path = data_path + inp_model_name
onnx_model = tf2onnx.convert.from_keras(model, output_path=output_path)
print(f"saved model to {output_path}")
# finish
mt5.shutdown()
</code></pre> |
1 |
2 |
1 |
3/6/26, 7:44 PM |
3/6/26, 7:44 PM |
View Edit Delete |
| 64 |
MQL5运行TensorFlow训练出来的模型 |
<p>1、本篇笔记也是在MQL5网上看到大佬的笔记作的修改<br />2、利用Tensorflow训练,MQL5运行。<br />3、模型训练的方式,已经在另一篇文章记录</p>
<pre class=""><code class="language-cpp hljs">//+------------------------------------------------------------------+
//| TimelessAI.mq5 |
//| Copyright 2023, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, Timeless"
#property link "https://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
input double InpLots = 1.0; // Lots amount to open position
input bool InpUseStops = true; // Use stops in trading
input int InpTakeProfit = 500; // TakeProfit level
input int InpStopLoss = 500; // StopLoss level
#resource "model.eurusd.H1.120.onnx" as uchar ExtModel[]
//SAMPLE_SIZE: 定义每次预测使用的历史数据的大小(120个时间点)。
#define SAMPLE_SIZE 120
//ExtHandle: 保存ONNX模型的句柄。
//ExtPredictedClass: 保存模型预测的结果(价格上升、持平或下降)。
//ExtNextBar、ExtNextDay: 用于管理图表的下一根K线和日期。
//ExtMin、ExtMax: 保存价格的最小值和最大值,用于归一化。
//ExtTrade: 用于交易操作的CTrade对象。
long ExtHandle = INVALID_HANDLE;
int ExtPredictedClass = -1;
datetime ExtNextBar = 0;
datetime ExtNextDay = 0;
float ExtMin = 0.0;
float ExtMax = 0.0;
CTrade ExtTrade;
//--- price movement prediction
#define PRICE_UP 0
#define PRICE_SAME 1
#define PRICE_DOWN 2
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
//---
if(_Symbol != "EURUSD" || _Period != PERIOD_H1) {
Print("model must work with EURUSD,H1");
return(INIT_FAILED);
}
//--- 加载ONNX模型并获取句柄ExtHandle
ExtHandle = OnnxCreateFromBuffer(ExtModel, ONNX_DEFAULT);
if(ExtHandle == INVALID_HANDLE) {
Print("OnnxCreateFromBuffer error ", GetLastError());
return(INIT_FAILED);
}
// 由于并非输入张量中定义的所有大小,我们必须显式设置它们
// 第一个索引-批量大小,第二个索引-系列大小,第三个索引-序列号(仅关闭)
// 设置ONNX模型的输入和输出维度。输入维度为{1, SAMPLE_SIZE, 1},
// 表示批量大小为1,输入时间序列长度为120,特征数为1(收盘价)。
const long input_shape[] = {1, SAMPLE_SIZE, 1};
if(!OnnxSetInputShape(ExtHandle, ONNX_DEFAULT, input_shape)) {
Print("OnnxSetInputShape error ", GetLastError());
return(INIT_FAILED);
}
//---由于并非输出张量中定义的所有大小,我们必须显式设置它们
//---第一个索引-批大小,必须与输入张量的批大小匹配
//---第二个指数-预测价格的数量(我们只预测收盘价)
//输出维度为{1, 1},表示模型输出1个预测值。
const long output_shape[] = {1, 1};
if(!OnnxSetOutputShape(ExtHandle, 0, output_shape)) {
Print("OnnxSetOutputShape error ", GetLastError());
return(INIT_FAILED);
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
// 返回当前服务器的时间(以秒为单位),
//ExtNextDay 是存储下一个新的一天的时间戳(通常基于午夜)。
//这行代码判断当前时间是否超过或等于下一天的时间点。
if(TimeCurrent() >= ExtNextDay) {
GetMinMax();
//--- set next day time
ExtNextDay = TimeCurrent();
ExtNextDay -= ExtNextDay % PeriodSeconds(PERIOD_D1);
ExtNextDay += PeriodSeconds(PERIOD_D1);
}
//--- check new bar
if(TimeCurrent() < ExtNextBar)
return;
//如果当前时间已经超过了 ExtNextBar,则更新 ExtNextBar 为下一个 K 线的时间:
//PeriodSeconds() 获取当前图表周期的秒数(例如,PeriodSeconds() 如果是 M1 则返回 60 秒,M5 则返回 300 秒等)。
//通过对当前时间取模并加上周期秒数,调整 ExtNextBar 为下一个完整的 K 线开始时间。
ExtNextBar = TimeCurrent();
ExtNextBar -= ExtNextBar % PeriodSeconds();
ExtNextBar += PeriodSeconds();
float close = (float)iClose(_Symbol, _Period, 0);
// 如果 ExtMin(当天最低价)大于当前的收盘价 close,则更新 ExtMin 为当前的 close。这行代码在每次 OnTick 被调用时检查并更新当天的最低价
if(ExtMin > close)
ExtMin = close;
if(ExtMax < close)
ExtMax = close;
//--- predict next price
PredictPrice();
//--- check trading according to prediction
if(ExtPredictedClass >= 0)
if(PositionSelect(_Symbol))
CheckForClose();
else
CheckForOpen();
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Get minimal and maximal Close for last 120 days |
//+------------------------------------------------------------------+
//该函数获取过去120天(SAMPLE_SIZE)的日线收盘价,并计算其中的最小值和最大值,用于后续的归一化处理。
void GetMinMax(void) {
//这里定义了一个名为 close 的变量,类型为 vectorf。
//vectorf 是 MQL5 中的一个数据结构,用来存储浮动的数据序列,在这里用于存储一段时间内的收盘价数据。
//vectorf 是一个一维数组,通常用于存储单一类型的数值数据,如收盘价、开盘价等。
//MqlRates 是一个结构体,表示单根K线的数据,包含了开盘价、最高价、最低价、收盘价等多个字段。
vectorf close;
//获取最120根K线的收盘价
close.CopyRates(_Symbol, PERIOD_D1, COPY_RATES_CLOSE, 0, SAMPLE_SIZE);
//将过去120根K线的收盘价的最低价放在ExtMin里
ExtMin = close.Min();
//将过去120根K线的收盘价的最高价放在ExtMax里
ExtMax = close.Max();
}
//+------------------------------------------------------------------+
//| Predict next price |
//+------------------------------------------------------------------+
//该函数用于获取预测的价格方向:
// 首先从图表获取过去120个时间点的收盘价,并进行归一化处理(使用最小值和最大值)。
// 然后将归一化的价格数据输入到ONNX模型中,运行推理得到预测值。
// 根据预测值与当前收盘价的差异,确定预测的价格趋势:
// PRICE_SAME:表示预测价格与当前价格相同。
// PRICE_UP:表示预测价格上涨。
// PRICE_DOWN:表示预测价格下跌。
void PredictPrice(void) {
//这行代码定义了一个静态的 vectorf 类型变量 output_data,大小为 1。vectorf 用于存储浮动类型的数值数据,
//这里用来存储预测的结果。
static vectorf output_data(1); // vector to get result
//这行定义了另一个静态的 vectorf 类型变量 x_norm,大小为 SAMPLE_SIZE。
//它用于存储经过归一化处理的价格数据。
static vectorf x_norm(SAMPLE_SIZE); // vector for prices normalize
//检查是否可以进行归一化。如果 ExtMin (最小值)大于或等于 ExtMax (最大值),则无法归一化。
//在这种情况下,ExtPredictedClass 被设置为 -1(表示错误状态),并且函数直接返回,不进行进一步操作。
if(ExtMin >= ExtMax) {
ExtPredictedClass = -1;
return;
}
//使用 CopyRates 函数从图表请求历史数据。具体参数:
//_Symbol 表示当前交易品种(例如 EURUSD)。
//_Period 表示时间周期(例如 D1)。
//COPY_RATES_CLOSE 表示只复制收盘价数据。
//1 表示从最近的时间点开始请求数据。
//SAMPLE_SIZE 表示请求的数据条数。
//如果请求失败,ExtPredictedClass 被设置为 -1,表示发生错误,然后函数返回。
if(!x_norm.CopyRates(_Symbol, _Period, COPY_RATES_CLOSE, 1, SAMPLE_SIZE)) {
ExtPredictedClass = -1;
return;
}
//---
//该行获取最后一根 K 线的收盘价。因为数据被存储在 x_norm 中,x_norm[SAMPLE_SIZE - 1] 表示数组中的最后一个元素,即最近的收盘价。
float last_close = x_norm[SAMPLE_SIZE - 1];
//这两行代码将价格数据进行归一化处理:
//x_norm -= ExtMin;:将数据中的每个元素减去最小值 ExtMin,以确保数据从 0 开始。
//x_norm /= (ExtMax - ExtMin);:然后将数据除以 (ExtMax - ExtMin),使数据范围变为 0 到 1。这样就完成了归一化。
x_norm -= ExtMin;
x_norm /= (ExtMax - ExtMin);
//OnnxRun 是一个函数,用于通过 ONNX 模型进行推理。具体参数:
//ExtHandle 是 ONNX 模型的句柄。
//ONNX_NO_CONVERSION 表示不进行数据类型转换。
//x_norm 是归一化后的价格数据,作为输入传入。
//output_data 用于存储推理的输出结果。
//如果推理失败,ExtPredictedClass 被设置为 -1,表示错误状态,函数直接返回。
if(!OnnxRun(ExtHandle, ONNX_NO_CONVERSION, x_norm, output_data)) {
ExtPredictedClass = -1;
return;
}
//这行代码将预测的输出值从 0 到 1 的范围反归一化到实际价格范围。
// output_data[0] 是 ONNX 模型输出的归一化预测结果。
// (ExtMax - ExtMin) 将归一化结果还原为实际的价格范围。
// + ExtMin 是为了将结果偏移回到正确的价格区间。
float predicted = output_data[0] * (ExtMax - ExtMin) + ExtMin;
//计算预测的价格(predicted)与最后的收盘价(last_close)之间的差异delta。
//如果差异为负,表示预测价格低于当前收盘价;如果差异为正,表示预测价格高于当前收盘价。
float delta = last_close - predicted;
//如果 delta 的绝对值非常小(即价格变化几乎为 0),那么预测的价格与当前收盘价几乎相同。
//此时,ExtPredictedClass 被设置为 PRICE_SAME,表示价格保持不变。
if(fabs(delta) <= 0.003)
ExtPredictedClass = PRICE_SAME;
else {
if(delta < 0)
ExtPredictedClass = PRICE_UP;
else
ExtPredictedClass = PRICE_DOWN;
}
}
//+------------------------------------------------------------------+
//| Check for open position conditions |
//+------------------------------------------------------------------+
//根据预测的价格趋势(上涨或下跌),判断建仓信号:
//如果预测价格上涨(PRICE_UP),则选择买入。
//如果预测价格下跌(PRICE_DOWN),则选择卖出。
//根据输入参数设置止损和止盈,并在允许交易的情况下建仓。
void CheckForOpen(void) {
//定义一个变量 signal,类型为 ENUM_ORDER_TYPE,用于表示订单类型(买单或卖单)。初始化为 WRONG_VALUE,表示没有有效的信号。
ENUM_ORDER_TYPE signal = WRONG_VALUE;
//--- check signals
if(ExtPredictedClass == PRICE_DOWN)
signal = ORDER_TYPE_SELL; // sell condition
else {
if(ExtPredictedClass == PRICE_UP)
signal = ORDER_TYPE_BUY; // buy condition
}
//检查 signal 是否有效(即不等于 WRONG_VALUE),并且检查终端是否允许交易(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) 返回是否可以进行交易)。
if(signal != WRONG_VALUE && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) {
double price, sl = 0, tp = 0;
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
if(signal == ORDER_TYPE_SELL) {
price = bid;
// 如果启用了止损止盈(InpUseStops),则根据当前卖价 (bid) 和止损、止盈的参数进行计算:
// sl = NormalizeDouble(bid + InpStopLoss * _Point, _Digits);:计算止损价格(卖价加上止损距离),并将其规范化为适合当前交易品种的价格精度。
// tp = NormalizeDouble(ask - InpTakeProfit * _Point, _Digits);:计算止盈价格(买价减去止盈距离),并规范化为适合的精度。
if(InpUseStops) {
sl = NormalizeDouble(bid + InpStopLoss * _Point, _Digits);
tp = NormalizeDouble(ask - InpTakeProfit * _Point, _Digits);
}
} else {
price = ask;
if(InpUseStops) {
sl = NormalizeDouble(ask - InpStopLoss * _Point, _Digits);
tp = NormalizeDouble(bid + InpTakeProfit * _Point, _Digits);
}
}
ExtTrade.PositionOpen(_Symbol, signal, InpLots, price, sl, tp);
}
}
//+------------------------------------------------------------------+
//| 平仓条件判断 |
//| 如果设置了止损和止盈,函数会直接返回。 |
//| 如果没有设置止损和止盈,检查当前持仓的类型: |
//| 如果是买入仓位且预测价格下跌,则平仓并反向开仓。 |
//| 如果是卖出仓位且预测价格上涨,则平仓并反向开仓。 |
//+------------------------------------------------------------------+
void CheckForClose(void) {
//这行代码检查是否启用了止损(InpUseStops)。
//如果启用了止损,函数将直接返回,不会继续执行其他的平仓操作。这意味着止损机制优先于其他信号。
if(InpUseStops)
return;
//定义一个布尔变量 bsignal,初始化为 false。这个变量用来表示是否存在需要平仓的信号。
bool bsignal = false;
//使用 PositionGetInteger(POSITION_TYPE) 获取当前持仓的类型,返回值存储在 type 变量中:
// POSITION_TYPE_BUY 表示当前持仓为买单。
// POSITION_TYPE_SELL 表示当前持仓为卖单。
long type = PositionGetInteger(POSITION_TYPE);
//如果当前持仓为买单 (POSITION_TYPE_BUY),并且 ExtPredictedClass 为 PRICE_DOWN(即预测价格将下跌),则将 bsignal 设置为 true,表示需要平仓。
if(type == POSITION_TYPE_BUY && ExtPredictedClass == PRICE_DOWN)
bsignal = true;
//如果当前持仓为卖单 (POSITION_TYPE_SELL),并且 ExtPredictedClass 为 PRICE_UP(即预测价格将上涨),则将 bsignal 设置为 true,表示需要平仓
if(type == POSITION_TYPE_SELL && ExtPredictedClass == PRICE_UP)
bsignal = true;
//如果 bsignal 为 true(即需要平仓)并且终端允许交易(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) 返回 true),则执行平仓操作。
if(bsignal && TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) {
//调用 ExtTrade.PositionClose 函数平掉当前持仓,_Symbol 表示当前的交易品种,3 表示平仓的魔术数字,通常用于标识特定的订单。
ExtTrade.PositionClose(_Symbol, 3);
//--- open opposite
CheckForOpen();
}
}
//+------------------------------------------------------------------+
</code></pre> |
1 |
50 |
1 |
3/6/26, 7:47 PM |
3/6/26, 7:47 PM |
View Edit Delete |
| 65 |
MQL5 自己的编写的常用函数 |
<p>自己以前写的代码,用来判断一些常用的事件包括</p>
<p>1、检查是否有新的K线出现</p>
<p>2、限制小数位数(部分品种历史数据中有超过图表正常值)</p>
<p>3、检测保证金是否充足</p>
<p>4、是否达到订单上限</p>
<p>5、下单</p>
<p>6、追踪止损</p>
<p>7、是否在允许的交易时间范围</p>
<p>8、单边总共有多少亏损订单(这个一般马丁用,实际情况几乎不用)</p>
<pre class=""><code class="language-cpp hljs">//+------------------------------------------------------------------+
//| 检查是否有新K线 |
//+------------------------------------------------------------------+
bool IsNewBar(string symbol, ENUM_TIMEFRAMES timeframe) {
// 获取当前时间周期的最新K线时间
datetime currentBarTime = iTime(symbol, timeframe, 0);
// 如果当前K线时间与上次记录的不同,说明有新K线生成
if (currentBarTime > lastBarTimes) {
lastBarTimes = currentBarTime; // 更新最后K线时间
return true; // 返回新K线标志
}
return false; // 没有新K线
}
//+------------------------------------------------------------------+
//| 限制小数位数 |
//+------------------------------------------------------------------+
double RoundToNDecimalPlaces(double value, int decimalPlaces) {
double factor = MathPow(10, decimalPlaces);
value = MathRound(value * factor) / factor;
return value;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 检测保证金是否充足 |
//+------------------------------------------------------------------+
bool CheckMoneyForTrade(string symb, double lots, ENUM_ORDER_TYPE type) {
//--- Getting the opening price
MqlTick mqltick;
SymbolInfoTick(symb, mqltick);
double price = mqltick.ask;
if(type == ORDER_TYPE_SELL)
price = mqltick.bid;
//--- values of the required and free margin
double margin, free_margin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
//--- call of the checking function
if(!OrderCalcMargin(type, symb, lots, price, margin)) {
//--- something went wrong, report and return false
Print("Error in ", __FUNCTION__, " code=", GetLastError());
return(false);
}
//--- if there are insufficient funds to perform the operation\
if(margin > free_margin) {
//--- report the error and return false
Print("Not enough money for ", EnumToString(type), " ", lots, " ", symb, " Error code=", GetLastError());
return(false);
}
//--- checking successful
return(true);
}
//+------------------------------------------------------------------+
//| 是否达到订单上限 |
//+------------------------------------------------------------------+
bool IsLimitOrder(string symbol,string type,string comment) {
CTrade trade;
int totalPositions = PositionsTotal();
int count = 0;
for(int i = 0; i < totalPositions; i++) {
ulong ticket = PositionGetTicket(i);
// 如果成功选择持仓订单
if(PositionSelectByTicket(ticket)) {
string order_symbol = PositionGetString(POSITION_SYMBOL);
string order_comment = PositionGetString(POSITION_COMMENT);
// 获取订单类型
ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
string order_type = (positionType == POSITION_TYPE_BUY) ? "Buy" : "Sell";
if(symbol == order_symbol && type == order_type && comment == order_comment) {
count++;
}
}
}
if(count >= iOrderLimit) {
return false;
}
return true;
}
//+------------------------------------------------------------------+
////+------------------------------------------------------------------+
////| 单边共有多少损单 |
////+------------------------------------------------------------------+
//int FindNearestLossCount(string symbol,ENUM_TIMEFRAMES timeframe, string order_type) {
// HistorySelect(TimeLocal() - 2 * 24 * 3600, TimeCurrent());
// int total = HistoryDealsTotal();
// int count = 0;
// bool is_break = false;
// //Print(total+"订单总数");
// for(int i=total-1; i>=0; i--) {
//
// ulong in_order_ticket = HistoryDealGetTicket(i);
// ENUM_DEAL_ENTRY in_order_entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(in_order_ticket, DEAL_ENTRY);
// //入方向订单(开仓)
// if(in_order_entry == DEAL_ENTRY_IN) {
// ulong in_order_positionId = HistoryDealGetInteger(in_order_ticket, DEAL_POSITION_ID);
// string in_order_symbol = HistoryDealGetString(in_order_ticket, DEAL_SYMBOL);
// int digits = SymbolInfoInteger(in_order_symbol, SYMBOL_DIGITS);
// string in_order_type = (HistoryDealGetInteger(in_order_ticket, DEAL_TYPE) == DEAL_TYPE_BUY) ? "Buy" : "Sell";
// double in_order_commission = RoundToNDecimalPlaces(HistoryDealGetDouble(in_order_ticket, DEAL_COMMISSION),digits);
// string in_order_comment = HistoryDealGetString(in_order_ticket, DEAL_COMMENT);
// double in_order_swap = RoundToNDecimalPlaces(HistoryDealGetDouble(in_order_ticket, DEAL_SWAP),digits);
//
//
// string result[];
// string sep = "_";
// ushort u_sep;
// u_sep = StringGetCharacter(sep, 0);
// int k = StringSplit(in_order_comment, u_sep, result);
// if(ArraySize(result)>0) {
// for(int j=total-1; j>=0; j--) {
// ulong out_order_ticket = HistoryDealGetTicket(j);
// ENUM_DEAL_ENTRY out_order_entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(out_order_ticket, DEAL_ENTRY);
// if(out_order_entry == DEAL_ENTRY_OUT || out_order_entry == DEAL_ENTRY_OUT_BY) {
// ulong out_order_positionId = HistoryDealGetInteger(out_order_ticket, DEAL_POSITION_ID);
// double out_order_commission = RoundToNDecimalPlaces(HistoryDealGetDouble(out_order_ticket, DEAL_COMMISSION),digits);
// //出方向订单(平仓)
// if(out_order_positionId == in_order_positionId && result[0] == "LeonSpikeGoldEA" && result[1] == timeframe && order_type == in_order_type && symbol == in_order_symbol) {
// double order_profit = RoundToNDecimalPlaces(HistoryDealGetDouble(out_order_ticket, DEAL_PROFIT),digits);
// if((order_profit+in_order_commission+out_order_commission+in_order_swap) < 0) {
// count++;
// } else {
// is_break =true;
// break;
//
// }
// }
// }
// }
// }
//
//
// }
// if(is_break == true) {
// break;
// }
// }
// //Print(count+"count");
// return count;
//
//}
////+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 下单 |
//+------------------------------------------------------------------+
void SendOrders(int magic, string symbol, double lots, ENUM_SYMBOL_INFO_DOUBLE type, double sl, double tp, string comment,ulong slippage) {
CTrade trade;
trade.SetExpertMagicNumber(magic);
trade.SetDeviationInPoints(slippage);
int digits = SymbolInfoInteger(symbol, SYMBOL_DIGITS);
double price = RoundToNDecimalPlaces(SymbolInfoDouble(symbol, type),digits);
if(type == SYMBOL_BID) {
int ticket = trade.Sell(lots, symbol, price, sl, tp, comment);
if(ticket < 0) {
PrintFormat("Sell order failed. Error code: %d", GetLastError());
}
} else if (type == SYMBOL_ASK) {
int ticket = trade.Buy(lots, symbol, price, sl, tp, comment);
if(ticket < 0) {
PrintFormat("Buy order failed. Error code: %d", GetLastError());
}
}
}
//+------------------------------------------------------------------+
//| 追踪止损 |
//+------------------------------------------------------------------+
void TrailingStop() {
CTrade trade;
int totalPositions = PositionsTotal();
for(int i = 0; i < totalPositions; i++) {
ulong ticket = PositionGetTicket(i);
// 如果成功选择持仓订单
if(PositionSelectByTicket(ticket)) {
// 获取持仓订单的详细信息
string symbol = PositionGetString(POSITION_SYMBOL);
string comment = PositionGetString(POSITION_COMMENT);
double magic = PositionGetInteger(POSITION_MAGIC);
double sl = PositionGetDouble(POSITION_SL);
double tp = PositionGetDouble(POSITION_TP);
double open = PositionGetDouble(POSITION_PRICE_OPEN);
double current = PositionGetDouble(POSITION_PRICE_CURRENT);
// 获取订单类型
ENUM_POSITION_TYPE positionType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
string orderType = (positionType == POSITION_TYPE_BUY) ? "Buy" : "Sell";
string result[];
string sep = "_";
ushort u_sep;
u_sep = StringGetCharacter(sep, 0);
int k = StringSplit(comment, u_sep, result);
int digits = SymbolInfoInteger(symbol, SYMBOL_DIGITS);
if(StringLen(comment) != 0 && result[0] == "LeonSpikeGoldEA") {
if(orderType == "Sell" ) {
if((open - current) > iTrailingStopPrice) {
double new_sl = open - ((open - current) * iPriceDifferentPercent / 100);
new_sl = RoundToNDecimalPlaces(new_sl, digits);
if(new_sl < sl) {
if (!trade.PositionModify(ticket, new_sl, tp)) {
//PrintFormat("追踪损设置失败 订单 %d. 错误代码: %d", ticket, GetLastError());
} else {
//PrintFormat("%d 单的追踪止损设置为 %f", ticket, new_sl);
}
}
}
} else if(orderType == "Buy") {
if((current - open) > iTrailingStopPrice) {
double new_sl = open + ((current - open) * iPriceDifferentPercent / 100);
new_sl = RoundToNDecimalPlaces(new_sl, digits);
if(new_sl > sl) {
if (!trade.PositionModify(ticket, new_sl, tp)) {
//PrintFormat("追踪损设置失败 订单 %d. Error code: %d", ticket, GetLastError());
} else {
//PrintFormat("%d 订单的追踪止损设置为 %f", ticket, new_sl);
}
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| 是不否在允许交易的时间 |
//+------------------------------------------------------------------+
bool IsAllowPeriod() {
MqlDateTime dt;
TimeCurrent(dt);
if(dt.day_of_week == 5 &&dt.hour > iFriday_day_stop_trading) {
return false;
} else if(dt.day_of_week == 1 && dt.hour < iMonday_day_stop_trading) {
return false;
} else {
if(dt.hour== 0 && dt.min<=30) {
return iBlock_0000_0030;
} else if(dt.hour== 0 && dt.min>30) {
return iBlock_0030_0100;
} else if(dt.hour == 1 && dt.min<=30) {
return iBlock_0100_0130;
} else if(dt.hour == 1 && dt.min>30) {
return iBlock_0130_0200;
} else if(dt.hour == 2 && dt.min<=30) {
return iBlock_0200_0230;
} else if(dt.hour == 2 && dt.min>30) {
return iBlock_0230_0300;
} else if(dt.hour == 3 && dt.min<=30) {
return iBlock_0300_0330;
} else if(dt.hour == 3 && dt.min>30) {
return iBlock_0330_0400;
} else if(dt.hour == 4 && dt.min<=30) {
return iBlock_0400_0430;
} else if(dt.hour == 4 && dt.min>30) {
return iBlock_0430_0500;
} else if(dt.hour == 5 && dt.min<=30) {
return iBlock_0500_0530;
} else if(dt.hour == 5 && dt.min>30) {
return iBlock_0530_0600;
} else if(dt.hour == 6 && dt.min<=30) {
return iBlock_0600_0630;
} else if(dt.hour == 6 && dt.min>30) {
return iBlock_0630_0700;
} else if(dt.hour == 7 && dt.min<=30) {
return iBlock_0700_0730;
} else if(dt.hour == 7 && dt.min>30) {
return iBlock_0730_0800;
} else if(dt.hour == 8 && dt.min<=30) {
return iBlock_0800_0830;
} else if(dt.hour == 8 && dt.min>30) {
return iBlock_0830_0900;
} else if(dt.hour == 9 && dt.min<=30) {
return iBlock_0900_0930;
} else if(dt.hour == 9 && dt.min>30) {
return iBlock_0930_1000;
} else if(dt.hour == 10 && dt.min<=30) {
return iBlock_1000_1030;
} else if(dt.hour == 10 && dt.min>30) {
return iBlock_1030_1100;
} else if(dt.hour == 11 && dt.min<=30) {
return iBlock_1100_1130;
} else if(dt.hour == 11 && dt.min>30) {
return iBlock_1130_1200;
} else if(dt.hour == 12 && dt.min<=30) {
return iBlock_1200_1230;
} else if(dt.hour == 12 && dt.min>30) {
return iBlock_1230_1300;
} else if(dt.hour == 13 && dt.min<=30) {
return iBlock_1300_1330;
} else if(dt.hour == 13 && dt.min>30) {
return iBlock_1330_1400;
} else if(dt.hour == 14 && dt.min<=30) {
return iBlock_1400_1430;
} else if(dt.hour == 14 && dt.min>30) {
return iBlock_1430_1500;
} else if(dt.hour == 15 && dt.min<=30) {
return iBlock_1500_1530;
} else if(dt.hour == 15 && dt.min>30) {
return iBlock_1530_1600;
} else if(dt.hour == 16 && dt.min<=30) {
return iBlock_1600_1630;
} else if(dt.hour == 16 && dt.min>30) {
return iBlock_1630_1700;
} else if(dt.hour == 17 && dt.min<=30) {
return iBlock_1700_1730;
} else if(dt.hour == 17 && dt.min>30) {
return iBlock_1730_1800;
} else if(dt.hour == 18 && dt.min<=30) {
return iBlock_1800_1830;
} else if(dt.hour == 18 && dt.min>30) {
return iBlock_1830_1900;
} else if(dt.hour == 19 && dt.min<=30) {
return iBlock_1900_1930;
} else if(dt.hour == 19 && dt.min>30) {
return iBlock_1930_2000;
} else if(dt.hour == 20 && dt.min<=30) {
return iBlock_2000_2030;
} else if(dt.hour == 20 && dt.min>30) {
return iBlock_2030_2100;
} else if(dt.hour == 21 && dt.min<=30) {
return iBlock_2100_2130;
} else if(dt.hour == 21 && dt.min>30) {
return iBlock_2130_2200;
} else if(dt.hour == 22 && dt.min<=30) {
return iBlock_2200_2230;
} else if(dt.hour == 22 && dt.min>30) {
return iBlock_2230_2300;
} else if(dt.hour == 23 && dt.min<=30) {
return iBlock_2300_2330;
} else if(dt.hour == 23 && dt.min>30) {
return iBlock_2330_2400;
}
}
return true;
}
//+------------------------------------------------------------------+</code></pre> |
1 |
50 |
1 |
3/6/26, 8:00 PM |
3/6/26, 8:00 PM |
View Edit Delete |
| 66 |
websocket后端基础示例FastAPI案例 |
<div style="color: #d1d3db; background-color: #1a1b1d; font-family: 'JetBrains Mono', Consolas, 'Courier New', monospace; font-size: 13px; line-height: 22px; white-space: pre;">
<div><span style="color: #b38cff;">from</span> <span style="color: #81cfe0;">fastapi</span> <span style="color: #b38cff;">import</span> <span style="color: #81cfe0;">FastAPI</span>, <span style="color: #81cfe0;">WebSocket</span>, <span style="color: #81cfe0;">WebSocketDisconnect</span></div>
<div><span style="color: #b38cff;">from</span> <span style="color: #81cfe0;">fastapi</span>.<span style="color: #81cfe0;">middleware</span>.<span style="color: #81cfe0;">cors</span> <span style="color: #b38cff;">import</span> <span style="color: #81cfe0;">CORSMiddleware</span></div>
<div><span style="color: #b38cff;">import</span> <span style="color: #81cfe0;">uvicorn</span></div>
<br />
<div><span style="color: #737780;"># 创建 FastAPI 实例</span></div>
<div><span style="color: #ded47e;">app</span> <span style="color: #d5d8e0;">=</span> <span style="color: #81cfe0;">FastAPI</span>()</div>
<br />
<div><span style="color: #737780;"># 配置 CORS (跨域资源共享)</span></div>
<div><span style="color: #737780;"># 允许所有来源访问,实际生产环境中应更严格地配置</span></div>
<div><span style="color: #ded47e;">app</span>.<span style="color: #f29d79;">add_middleware</span>(</div>
<div> <span style="color: #81cfe0;">CORSMiddleware</span>,</div>
<div> <span style="color: #ded47e;">allow_origins</span><span style="color: #d5d8e0;">=</span>[<span style="color: #82d99f;">"*"</span>], <span style="color: #737780;"># 允许所有来源</span></div>
<div> <span style="color: #ded47e;">allow_credentials</span><span style="color: #d5d8e0;">=</span><span style="color: #80bbff;">True</span>,</div>
<div> <span style="color: #ded47e;">allow_methods</span><span style="color: #d5d8e0;">=</span>[<span style="color: #82d99f;">"*"</span>], <span style="color: #737780;"># 允许所有 HTTP 方法</span></div>
<div> <span style="color: #ded47e;">allow_headers</span><span style="color: #d5d8e0;">=</span>[<span style="color: #82d99f;">"*"</span>], <span style="color: #737780;"># 允许所有 HTTP 头</span></div>
<div>)</div>
<br />
<div><span style="color: #737780;"># 连接管理器类</span></div>
<div><span style="color: #737780;"># 用于管理活跃的 WebSocket 连接,实现消息广播</span></div>
<div><span style="color: #b38cff;">class</span> <span style="color: #81cfe0;">ConnectionManager</span>:</div>
<div> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">__init__</span>(<span style="color: #ded47e;">self</span>):</div>
<div> <span style="color: #737780;"># 存储活跃的 WebSocket 连接列表</span></div>
<div> <span style="color: #ded47e;">self</span>.<span style="color: #e0e3ee;">active_connections</span>: <span style="color: #81cfe0;">list</span>[<span style="color: #81cfe0;">WebSocket</span>] <span style="color: #d5d8e0;">=</span> []</div>
<br />
<div> <span style="color: #b38cff;">async</span> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">connect</span>(<span style="color: #ded47e;">self</span>, <span style="color: #ded47e;">websocket</span>: <span style="color: #81cfe0;">WebSocket</span>):</div>
<div> <span style="color: #82d99f;">"""接受连接并将其添加到活跃连接列表"""</span></div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">websocket</span>.<span style="color: #f29d79;">accept</span>()</div>
<div> <span style="color: #ded47e;">self</span>.<span style="color: #e0e3ee;">active_connections</span>.<span style="color: #f29d79;">append</span>(<span style="color: #ded47e;">websocket</span>)</div>
<br />
<div> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">disconnect</span>(<span style="color: #ded47e;">self</span>, <span style="color: #ded47e;">websocket</span>: <span style="color: #81cfe0;">WebSocket</span>):</div>
<div> <span style="color: #82d99f;">"""断开连接时从列表中移除"""</span></div>
<div> <span style="color: #ded47e;">self</span>.<span style="color: #e0e3ee;">active_connections</span>.<span style="color: #f29d79;">remove</span>(<span style="color: #ded47e;">websocket</span>)</div>
<br />
<div> <span style="color: #b38cff;">async</span> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">broadcast</span>(<span style="color: #ded47e;">self</span>, <span style="color: #ded47e;">message</span>: <span style="color: #81cfe0;">str</span>):</div>
<div> <span style="color: #82d99f;">"""向所有活跃连接发送消息"""</span></div>
<div> <span style="color: #b38cff;">for</span> <span style="color: #ded47e;">connection</span> <span style="color: #b38cff;">in</span> <span style="color: #ded47e;">self</span>.<span style="color: #e0e3ee;">active_connections</span>:</div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">connection</span>.<span style="color: #f29d79;">send_text</span>(<span style="color: #ded47e;">message</span>)</div>
<br />
<div><span style="color: #737780;"># 实例化连接管理器</span></div>
<div><span style="color: #ded47e;">manager</span> <span style="color: #d5d8e0;">=</span> <span style="color: #81cfe0;">ConnectionManager</span>()</div>
<br />
<div><span style="color: #737780;"># WebSocket 路由 endpoint</span></div>
<div><span style="color: #737780;"># 路径参数 client_id 用于标识客户端</span></div>
<div><span style="color: #f29d79;">@</span><span style="color: #ded47e;">app</span><span style="color: #f29d79;">.</span><span style="color: #f29d79;">websocket</span>(<span style="color: #82d99f;">"/ws/</span><span style="color: #80bbff;">{client_id}</span><span style="color: #82d99f;">"</span>)</div>
<div><span style="color: #b38cff;">async</span> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">websocket_endpoint</span>(<span style="color: #ded47e;">websocket</span>: <span style="color: #81cfe0;">WebSocket</span>, <span style="color: #ded47e;">client_id</span>: <span style="color: #81cfe0;">int</span>):</div>
<div> <span style="color: #737780;"># 1. 建立连接</span></div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">manager</span>.<span style="color: #f29d79;">connect</span>(<span style="color: #ded47e;">websocket</span>)</div>
<div> <span style="color: #b38cff;">try</span>:</div>
<div> <span style="color: #737780;"># 2. 循环接收消息</span></div>
<div> <span style="color: #b38cff;">while</span> <span style="color: #80bbff;">True</span>:</div>
<div> <span style="color: #737780;"># 等待客户端发送文本消息</span></div>
<div> <span style="color: #ded47e;">data</span> <span style="color: #d5d8e0;">=</span> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">websocket</span>.<span style="color: #f29d79;">receive_text</span>()</div>
<div> <span style="color: #737780;"># 3. 广播消息给所有用户</span></div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">manager</span>.<span style="color: #f29d79;">broadcast</span>(<span style="color: #b38cff;">f</span><span style="color: #82d99f;">"Client #</span><span style="color: #80bbff;">{</span><span style="color: #ded47e;">client_id</span><span style="color: #80bbff;">}</span><span style="color: #82d99f;"> says: </span><span style="color: #80bbff;">{</span><span style="color: #ded47e;">data</span><span style="color: #80bbff;">}</span><span style="color: #82d99f;">"</span>)</div>
<div> <span style="color: #b38cff;">except</span> <span style="color: #81cfe0;">WebSocketDisconnect</span>:</div>
<div> <span style="color: #737780;"># 4. 处理断开连接</span></div>
<div> <span style="color: #ded47e;">manager</span>.<span style="color: #f29d79;">disconnect</span>(<span style="color: #ded47e;">websocket</span>)</div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">manager</span>.<span style="color: #f29d79;">broadcast</span>(<span style="color: #b38cff;">f</span><span style="color: #82d99f;">"Client #</span><span style="color: #80bbff;">{</span><span style="color: #ded47e;">client_id</span><span style="color: #80bbff;">}</span><span style="color: #82d99f;"> left the chat"</span>)</div>
<br />
<div><span style="color: #b38cff;">if</span> <span style="color: #ded47e;">__name__</span> <span style="color: #d5d8e0;">==</span> <span style="color: #82d99f;">"__main__"</span>:</div>
<div> <span style="color: #737780;"># 启动 uvicorn 服务器</span></div>
<div> <span style="color: #737780;"># host="0.0.0.0" 允许外部访问</span></div>
<div> <span style="color: #737780;"># port=8000 服务端口</span></div>
<div> <span style="color: #81cfe0;">uvicorn</span>.<span style="color: #f29d79;">run</span>(<span style="color: #ded47e;">app</span>, <span style="color: #ded47e;">host</span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;">"0.0.0.0"</span>, <span style="color: #ded47e;">port</span><span style="color: #d5d8e0;">=</span><span style="color: #f48cca;">8000</span>)</div>
</div> |
1 |
69 |
1 |
3/7/26, 7:39 PM |
3/7/26, 7:39 PM |
View Edit Delete |
| 67 |
websocket前端基础示例vue3案例 |
<div style="color: #d1d3db; background-color: #1a1b1d; font-family: 'JetBrains Mono', Consolas, 'Courier New', monospace; font-size: 13px; line-height: 22px; white-space: pre;">
<div><span style="color: #d5d8e0;"><!</span><span style="color: #f2858c;">DOCTYPE</span> <span style="color: #ded47e;">html</span><span style="color: #d5d8e0;">></span></div>
<div><span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">html</span> <span style="color: #ded47e;">lang</span>=<span style="color: #82d99f;">"en"</span><span style="color: #d5d8e0;">></span></div>
<div><span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">head</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">meta</span> <span style="color: #ded47e;">charset</span>=<span style="color: #82d99f;">"UTF-8"</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">title</span><span style="color: #d5d8e0;">></span>FastAPI + Vue 3 WebSocket<span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">title</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #737780;"><!-- 引入 Vue 3 CDN --></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">script</span><span style="color: #82d99f;"> </span><span style="color: #ded47e;">src</span><span style="color: #82d99f;">="https://unpkg.com/vue@3/dist/vue.global.js"</span><span style="color: #d5d8e0;">></</span><span style="color: #f2858c;">script</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">style</span><span style="color: #d5d8e0;">></span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #ded47e;">body</span><span style="color: #82d99f;"> { </span><span style="color: #d5d8e0;">font-family</span><span style="color: #82d99f;">: sans-serif; </span><span style="color: #d5d8e0;">padding</span><span style="color: #82d99f;">: </span><span style="color: #f48cca;">20px</span><span style="color: #82d99f;">; }</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #ded47e;">.chat-box</span><span style="color: #82d99f;"> { </span><span style="color: #d5d8e0;">border</span><span style="color: #82d99f;">: </span><span style="color: #f48cca;">1px</span><span style="color: #82d99f;"> solid #ccc; </span><span style="color: #d5d8e0;">padding</span><span style="color: #82d99f;">: </span><span style="color: #f48cca;">10px</span><span style="color: #82d99f;">; </span><span style="color: #d5d8e0;">height</span><span style="color: #82d99f;">: </span><span style="color: #f48cca;">300px</span><span style="color: #82d99f;">; </span><span style="color: #d5d8e0;">overflow-y</span><span style="color: #82d99f;">: scroll; </span><span style="color: #d5d8e0;">margin-bottom</span><span style="color: #82d99f;">: </span><span style="color: #f48cca;">10px</span><span style="color: #82d99f;">; }</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #ded47e;">.message</span><span style="color: #82d99f;"> { </span><span style="color: #d5d8e0;">margin</span><span style="color: #82d99f;">: </span><span style="color: #f48cca;">5px</span><span style="color: #82d99f;"> </span><span style="color: #f48cca;">0</span><span style="color: #82d99f;">; }</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">style</span><span style="color: #d5d8e0;">></span></div>
<div><span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">head</span><span style="color: #d5d8e0;">></span></div>
<div><span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">body</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">div</span> <span style="color: #ded47e;">id</span>=<span style="color: #82d99f;">"app"</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">h1</span><span style="color: #d5d8e0;">></span>WebSocket Chat (FastAPI)<span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">h1</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #737780;"><!-- 消息显示区域 --></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">div</span> <span style="color: #ded47e;">class</span>=<span style="color: #82d99f;">"chat-box"</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">div</span> <span style="color: #b38cff;">v-for</span>="(<span style="color: #ded47e;">msg</span>, <span style="color: #ded47e;">index</span>) <span style="color: #b38cff;">in</span> <span style="color: #ded47e;">messages</span>" :<span style="color: #ded47e;">key</span>="<span style="color: #ded47e;">index</span>" <span style="color: #ded47e;">class</span>=<span style="color: #82d99f;">"message"</span><span style="color: #d5d8e0;">></span>{{ <span style="color: #ded47e;">msg</span> }}<span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">div</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">div</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #737780;"><!-- 输入框:绑定 messageInput,回车键触发 sendMessage --></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">input</span> <span style="color: #ded47e;">v-model</span>="<span style="color: #ded47e;">messageInput</span>" @<span style="color: #ded47e;">keyup</span>.<span style="color: #ded47e;">enter</span>="<span style="color: #ded47e;">sendMessage</span>" <span style="color: #ded47e;">placeholder</span>=<span style="color: #82d99f;">"Type a message..."</span> <span style="color: #d5d8e0;">/></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">button</span> @<span style="color: #ded47e;">click</span>="<span style="color: #ded47e;">sendMessage</span>"<span style="color: #d5d8e0;">></span>Send<span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">button</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">p</span><span style="color: #d5d8e0;">></span>Status: {{ <span style="color: #ded47e;">status</span> }}<span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">p</span><span style="color: #d5d8e0;">></span></div>
<div> <span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">div</span><span style="color: #d5d8e0;">></span></div>
<br />
<div> <span style="color: #d5d8e0;"><</span><span style="color: #f2858c;">script</span><span style="color: #d5d8e0;">></span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">const</span><span style="color: #82d99f;"> { </span><span style="color: #80bbff;">createApp</span><span style="color: #82d99f;">, </span><span style="color: #80bbff;">ref</span><span style="color: #82d99f;">, </span><span style="color: #80bbff;">onMounted</span><span style="color: #82d99f;">, </span><span style="color: #80bbff;">onUnmounted</span><span style="color: #82d99f;"> } </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #ded47e;">Vue</span><span style="color: #82d99f;">;</span></div>
<br />
<div><span style="color: #82d99f;"> </span><span style="color: #f29d79;">createApp</span><span style="color: #82d99f;">({</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #f29d79;">setup</span><span style="color: #82d99f;">() {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 响应式状态定义</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">const</span><span style="color: #82d99f;"> </span><span style="color: #80bbff;">messages</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #f29d79;">ref</span><span style="color: #82d99f;">([]); </span><span style="color: #737780;">// 存储聊天记录</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">const</span><span style="color: #82d99f;"> </span><span style="color: #80bbff;">messageInput</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #f29d79;">ref</span><span style="color: #82d99f;">(</span><span style="color: #82d99f;">''</span><span style="color: #82d99f;">); </span><span style="color: #737780;">// 输入框内容</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">const</span><span style="color: #82d99f;"> </span><span style="color: #80bbff;">status</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #f29d79;">ref</span><span style="color: #82d99f;">(</span><span style="color: #82d99f;">'Disconnected'</span><span style="color: #82d99f;">); </span><span style="color: #737780;">// 连接状态</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">let</span><span style="color: #82d99f;"> </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #80bbff;">null</span><span style="color: #82d99f;">; </span><span style="color: #737780;">// WebSocket 实例</span></div>
<div><span style="color: #82d99f;"> </span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 生成一个随机的客户端 ID 用于演示</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">const</span><span style="color: #82d99f;"> </span><span style="color: #80bbff;">clientId</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #81cfe0;">Date</span><span style="color: #82d99f;">.</span><span style="color: #f29d79;">now</span><span style="color: #82d99f;">();</span></div>
<br />
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 连接 WebSocket 函数</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">const</span><span style="color: #82d99f;"> </span><span style="color: #f29d79;">connect</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> () </span><span style="color: #b38cff;">=></span><span style="color: #82d99f;"> {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 创建 WebSocket 连接,指向 FastAPI 后端</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #b38cff;">new</span><span style="color: #82d99f;"> </span><span style="color: #81cfe0;">WebSocket</span><span style="color: #82d99f;">(</span><span style="color: #82d99f;">`ws://localhost:8005/ws/</span><span style="color: #f2858c;">${</span><span style="color: #80bbff;">clientId</span><span style="color: #f2858c;">}</span><span style="color: #82d99f;">`</span><span style="color: #82d99f;">);</span></div>
<div><span style="color: #82d99f;"> </span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 连接打开事件</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;">.</span><span style="color: #f29d79;">onopen</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> () </span><span style="color: #b38cff;">=></span><span style="color: #82d99f;"> {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #80bbff;">status</span><span style="color: #82d99f;">.</span><span style="color: #e0e3ee;">value</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #82d99f;">'Connected'</span><span style="color: #82d99f;">;</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #80bbff;">messages</span><span style="color: #82d99f;">.</span><span style="color: #ded47e;">value</span><span style="color: #82d99f;">.</span><span style="color: #f29d79;">push</span><span style="color: #82d99f;">(</span><span style="color: #82d99f;">'System: Connected to server'</span><span style="color: #82d99f;">);</span></div>
<div><span style="color: #82d99f;"> };</span></div>
<br />
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 收到消息事件</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;">.</span><span style="color: #f29d79;">onmessage</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> (</span><span style="color: #ded47e;">event</span><span style="color: #82d99f;">) </span><span style="color: #b38cff;">=></span><span style="color: #82d99f;"> {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 将收到的消息添加到列表</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #80bbff;">messages</span><span style="color: #82d99f;">.</span><span style="color: #ded47e;">value</span><span style="color: #82d99f;">.</span><span style="color: #f29d79;">push</span><span style="color: #82d99f;">(</span><span style="color: #ded47e;">event</span><span style="color: #82d99f;">.</span><span style="color: #ded47e;">data</span><span style="color: #82d99f;">);</span></div>
<div><span style="color: #82d99f;"> };</span></div>
<br />
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 连接关闭事件</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;">.</span><span style="color: #f29d79;">onclose</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> () </span><span style="color: #b38cff;">=></span><span style="color: #82d99f;"> {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #80bbff;">status</span><span style="color: #82d99f;">.</span><span style="color: #e0e3ee;">value</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #82d99f;">'Disconnected'</span><span style="color: #82d99f;">;</span></div>
<div><span style="color: #82d99f;"> };</span></div>
<div><span style="color: #82d99f;"> };</span></div>
<br />
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 发送消息函数</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">const</span><span style="color: #82d99f;"> </span><span style="color: #f29d79;">sendMessage</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> () </span><span style="color: #b38cff;">=></span><span style="color: #82d99f;"> {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">if</span><span style="color: #82d99f;"> (</span><span style="color: #80bbff;">messageInput</span><span style="color: #82d99f;">.</span><span style="color: #e0e3ee;">value</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">&&</span><span style="color: #82d99f;"> </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">&&</span><span style="color: #82d99f;"> </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;">.</span><span style="color: #e0e3ee;">readyState</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">===</span><span style="color: #82d99f;"> </span><span style="color: #81cfe0;">WebSocket</span><span style="color: #82d99f;">.</span><span style="color: #ded47e;">OPEN</span><span style="color: #82d99f;">) {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 发送消息到服务器</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;">.</span><span style="color: #f29d79;">send</span><span style="color: #82d99f;">(</span><span style="color: #80bbff;">messageInput</span><span style="color: #82d99f;">.</span><span style="color: #e0e3ee;">value</span><span style="color: #82d99f;">);</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 清空输入框</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #80bbff;">messageInput</span><span style="color: #82d99f;">.</span><span style="color: #e0e3ee;">value</span><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;"> </span><span style="color: #82d99f;">''</span><span style="color: #82d99f;">;</span></div>
<div><span style="color: #82d99f;"> }</span></div>
<div><span style="color: #82d99f;"> };</span></div>
<br />
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 组件挂载时自动连接</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #f29d79;">onMounted</span><span style="color: #82d99f;">(() </span><span style="color: #b38cff;">=></span><span style="color: #82d99f;"> {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #f29d79;">connect</span><span style="color: #82d99f;">();</span></div>
<div><span style="color: #82d99f;"> });</span></div>
<br />
<div><span style="color: #82d99f;"> </span><span style="color: #737780;">// 组件卸载时关闭连接,防止资源泄漏</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #f29d79;">onUnmounted</span><span style="color: #82d99f;">(() </span><span style="color: #b38cff;">=></span><span style="color: #82d99f;"> {</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">if</span><span style="color: #82d99f;"> (</span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;">) </span><span style="color: #ded47e;">ws</span><span style="color: #82d99f;">.</span><span style="color: #f29d79;">close</span><span style="color: #82d99f;">();</span></div>
<div><span style="color: #82d99f;"> });</span></div>
<br />
<div><span style="color: #82d99f;"> </span><span style="color: #b38cff;">return</span><span style="color: #82d99f;"> { </span><span style="color: #e0e3ee;">messages</span><span style="color: #82d99f;">, </span><span style="color: #e0e3ee;">messageInput</span><span style="color: #82d99f;">, </span><span style="color: #f29d79;">sendMessage</span><span style="color: #82d99f;">, </span><span style="color: #e0e3ee;">status</span><span style="color: #82d99f;"> };</span></div>
<div><span style="color: #82d99f;"> }</span></div>
<div><span style="color: #82d99f;"> }).</span><span style="color: #f29d79;">mount</span><span style="color: #82d99f;">(</span><span style="color: #82d99f;">'#app'</span><span style="color: #82d99f;">);</span></div>
<div><span style="color: #82d99f;"> </span><span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">script</span><span style="color: #d5d8e0;">></span></div>
<div><span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">body</span><span style="color: #d5d8e0;">></span></div>
<div><span style="color: #d5d8e0;"></</span><span style="color: #f2858c;">html</span><span style="color: #d5d8e0;">></span></div>
</div> |
1 |
20 |
1 |
3/7/26, 7:41 PM |
3/7/26, 7:41 PM |
View Edit Delete |
| 68 |
Ubuntu24.04安装TinyProxy实现内网穿透 |
<p>1、安装TinyProxy</p>
<pre class=""><code class="language-bash hljs">sudo apt install tinyproxy</code></pre>
<p> </p>
<p>2、编辑配置文件TinyProxy</p>
<pre class=""><code class="hljs language-bash">sudo vim /etc/tinyproxy/tinyproxy.conf</code></pre>
<p> </p>
<p>3、更改项</p>
<pre class=""><code class="language-bash hljs"># 找到Allow,增加内网服务器IP
Allow 192.168.1.145
# 出于安全考虑一般不用默认 端口 找到 Port 8888,修改为其他端口
Port 8989</code></pre>
<p> </p>
<p>4、重启TinyProxy</p>
<pre class=""><code class="language-bash hljs">sudo systemctl restart tinyproxy</code></pre> |
1 |
34 |
1 |
3/10/26, 7:45 PM |
3/11/26, 3:04 PM |
View Edit Delete |
| 69 |
Ubuntu 后台运行程序,并将日志输出到特定文件。 |
<p>nohup:忽略挂断信号(即使终端关闭,进程仍运行)</p>
<p>> nohup.log:将标准输出重定向到 nohup.log</p>
<p>2>&1:将错误输出也重定向到日志文件</p>
<p>&:放入后台运行</p>
<pre class=""><code class="hljs language-bash">nohup java -jar your-app.jar > nohup.log 2>&1 &</code></pre> |
1 |
34 |
1 |
3/15/26, 2:29 PM |
3/15/26, 2:31 PM |
View Edit Delete |
| 70 |
ElasticSearch数据迁移 |
<p>1、创建文件备份路径</p>
<pre class=""><code class="language-bash hljs"> mkdir -p /backup/elasticsearch
#给权限
sudo chown -R elasticsearch:elasticsearch /mnt/elasticsearch/backups
sudo chmod -R 750 /mnt/elasticsearch/backups</code></pre>
<p> </p>
<p>2、编辑配置文件</p>
<pre class=""><code class="language-bash hljs"># Ubuntu24.04
sudo vim /etc/elasticsearch/elasticsearch.yml
# Windows11
D:\Elasticsearch\config\elasticsearch.yml</code></pre>
<p> </p>
<p>3、在elasticsearch.yml 文件末尾添加仓库路径:</p>
<pre class=""><code class="language-less hljs">path.repo: ["/backup/elasticsearch"]</code></pre>
<p> </p>
<p>4、重启es</p>
<pre class=""><code class="hljs language-undefined">sudo systemctl restart elasticsearch</code></pre>
<p> </p>
<p>5、重置es用户密码(如果忘记),如果记得则略过该步骤</p>
<pre class=""><code class="hljs language-bash">sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic</code></pre>
<p> </p>
<p>6、 创建快照仓库,这里用curl获取,如果有工具也可以直接用apifox或者postman获取</p>
<pre class=""><code class="language-bash hljs">curl -u elastic -X PUT "http://localhost:9200/_snapshot/my_repo" -H 'Content-Type: application/json' -d'
{
"type": "fs",
"settings": {
"location": "/backup/elasticsearch",
"compress": true
}
}
'</code></pre>
<p> </p>
<p>7、创建快照(导出数据,例如叫 snapshot_ubuntu)</p>
<pre class=""><code class="language-bash hljs">curl -u elastic -X PUT "http://localhost:9200/_snapshot/my_repo/snapshot_ubuntu?wait_for_completion=true"</code></pre>
<p> </p>
<p>8、打包快照文件(准备拷贝到 Windows)</p>
<pre class=""><code class="hljs language-bash"># 进入 backup 目录
cd /backup
# 打包整个 elasticsearch 目录
sudo tar -czvf es_snapshot.tar.gz elasticsearch
# 查看
ls -lh es_snapshot.tar.gz</code></pre>
<p> </p>
<p>9、将打包好的文件复制到windows上</p>
<pre class=""><code class="language-ruby hljs"># 用sz直接下载
sz es_snapshot.tar.gz
# 或者scp传输
scp your_user@ubuntu_ip:/backup/es_snapshot.tar.gz D:\Backup\Elasticsearch</code></pre>
<p> </p>
<p>10、 在windows上设置备份文件的存放路径</p>
<pre class=""><code class="language-bash hljs"># 这是windowspower shell的操作命令,其实和mkdir没区别。简单粗暴点就直接手动鼠标右键新建文件夹
New-Item -Path "D:\Backup\Elasticsearch" -ItemType Directory -Force</code></pre>
<p> </p>
<p>11、解压快照文件</p>
<pre class=""><code class="language-bash hljs"># 解压到 D:\Backup\Elasticsearch,简单粗暴点就直接winrar解压,都上了windows了也没必要都用命令行了
tar -xzf D:\Backup\Elasticsearch\es_snapshot.tar.gz -C D:\Backup\Elasticsearch\</code></pre>
<p> </p>
<p>12、修改windows上ES的yml配置文件</p>
<pre class=""><code class="hljs language-lua">C:\ProgramData\Elastic\Elasticsearch\config\elasticsearch.yml</code></pre>
<p> </p>
<p>13、同样最后添加仓库路径,要用/不能用windows的\,会报错无法启动</p>
<pre class=""><code class="language-less hljs">path.repo: ["D:/Backup/Elasticsearch"]</code></pre>
<p> </p>
<p>12、重启ES</p>
<pre class=""><code class="language-bash hljs">#这个也一样,手动吧elasticsearch.bat启动的命令行对话框关掉再也行
Restart-Service elasticsearch</code></pre>
<p> </p>
<p>13、重置windows上es的密码</p>
<pre class=""><code class="hljs language-bash">cd "C:\Program Files\Elastic\Elasticsearch\9.3.1\bin"
.\elasticsearch-reset-password.bat -u elastic</code></pre>
<p> </p>
<p>14、注册相同的快照仓库</p>
<pre class=""><code class="language-bash hljs">curl -u elastic -X PUT "http://localhost:9200/_snapshot/my_repo" -H "Content-Type: application/json" -d "{`"type`":`"fs`",`"settings`":{`"location`":`"D:\Backup\Elasticsearch`",`"compress`":true}}"</code></pre>
<p> </p>
<p>15、恢复快照</p>
<pre class=""><code class="hljs language-bash">curl -u elastic -X POST "http://localhost:9200/_snapshot/my_repo/snapshot_ubuntu/_restore?wait_for_completion=true"</code></pre>
<p> </p> |
1 |
30 |
1 |
3/15/26, 5:35 PM |
3/15/26, 8:01 PM |
View Edit Delete |
| 71 |
RAG数据清洗三大关键点 |
<p>1、文本切分:500-100字符/chunk,设10%-20%重叠防信息割裂。</p>
<p>2、PDF解析:要做结构感知,用LayoutLM画出边缘线再提取文字或者用GPT-4V/Llama Pass把PDF转成文字再提取文字,核心就是让机器看清楚文档结构,避开基础库乱码</p>
<p>3、存储格式:坚持Markdown,主流的大模型利用了github上大量的md文件加入了训练,对此格式敏感,理解度高。对后续的检索和生成的准确性会大幅度提升</p>
<p>三者环环相扣,从文本切分的语意完整 到 PDF结构准确性 再到 数据存储的格式适配性。把这三个基础环境做扎实RAG的效果就会有很大提升</p> |
1 |
60 |
1 |
3/19/26, 3:06 AM |
3/19/26, 3:06 AM |
View Edit Delete |
| 72 |
LangChain内置中间件 |
<p>节点式钩子</p>
<p>1、before_agent: agent执行前拦截</p>
<p>2、after_agent:agent执行后拦截</p>
<p>3、before_model:model执行前拦截</p>
<p>4、after_model:model执行后拦截</p>
<p> </p>
<p>针对工具和模型的包装式钩子:</p>
<p>1、wrap_model_call:每个模型调用时拦截</p>
<p>2、wrap_tool_call:每个工具调用时拦截</p> |
1 |
61 |
1 |
3/23/26, 8:36 PM |
3/23/26, 8:36 PM |
View Edit Delete |
| 73 |
Streamlit基本API |
<h4 style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1.25em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain md-expand" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">1、组件使用方法</span></h4>
<h5 class="md-end-block md-heading" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">1.1 运行代码</span></h5>
<pre class=""><code class="hljs language-python"># 创建第一个应用(app.py)
import streamlit as st
st.title("我的第一个Streamlit应用")
st.write("你好,世界!")
# 在终端运行
streamlit run app.py
streamlit hello</code></pre>
<p> </p>
<h5 class="md-end-block md-heading" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">1.2 文本组件</span></h5>
<pre class=""><code class="language-python hljs">st.title("主标题") # 主标题
st.header("章节标题") # 大标题
st.subheader("子标题") # 子标题
st.text("普通文本") # 普通文本
st.write("万能文本/变量") # 显示任何对象
st.markdown("**Markdown**支持") # Markdown语法</code></pre>
<p> </p>
<h5 class="md-end-block md-heading" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">1.3 数据展示组件</span></h5>
<pre class=""><code class="language-python hljs">st.dataframe(pd.DataFrame()) # 交互式表格
st.table([1,2,3]) # 静态表格
st.json({"key": "value"}) # 显示JSON格式</code></pre>
<p> </p>
<h5 class="md-end-block md-heading md-focus" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain md-expand" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">1.4 输入控件</span></h5>
<pre class=""><code class="language-python hljs">text = st.text_input("输入文本") # 文本输入
number = st.number_input("输入数字") # 数字输入
date = st.date_input("选择日期") # 日期选择
time = st.time_input("选择时间") # 时间选择
is_checked = st.checkbox("复选框") # 复选框
selected = st.radio("单选按钮", ['1', '2', '3', '4']) # 单选按钮
multi = st.multiselect("多选", ['1', '2', '3', '4']) # 多选下拉
slider = st.slider("滑块", 0, 100) # 滑块
st.button("确认") # 按钮
st.file_uploader("上传文件") # 文件上传</code></pre>
<p> </p>
<h4 class="md-end-block md-heading" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1.25em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">2、布局使用</span></h4>
<h5 class="md-end-block md-heading md-focus" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">2.1 侧边栏</span></h5>
<pre class=""><code class="language-python hljs"># 所有输入组件添加sidebar前缀即可放入侧边栏
st.sidebar.selectbox("选项", ['1', '2', '3', '4'])</code></pre>
<p> </p>
<h5 class="md-end-block md-heading" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">2.2 分列布局</span></h5>
<pre class=""><code class="language-python hljs">col1, col2 = st.columns(2) # 创建两列
with col1:
st.write("第一列内容")
with col2:
st.write("第二列内容")</code></pre>
<p> </p>
<h5 class="md-end-block md-heading md-focus" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain md-expand" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">2.3 标签页</span></h5>
<pre class=""><code class="language-python hljs">tab1, tab2 = st.tabs(["主页", "分析"])
with tab1:
st.write("主页内容")
with tab2:
st.write("分析内容")</code></pre>
<p> </p>
<h5 class="md-end-block md-heading" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">2.4 容器</span></h5>
<pre class=""><code class="language-python hljs">container = st.container()
container.write("容器内的内容")</code></pre>
<p> </p>
<h4 class="md-end-block md-heading" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; white-space-collapse: preserve; break-after: avoid-page; break-inside: avoid; orphans: 4; font-size: 1.25em; margin-top: 1rem; margin-bottom: 1rem; position: relative; line-height: 1.4; cursor: text; font-family: 'Open Sans', 'Clear Sans', 'Helvetica Neue', Helvetica, Arial, 'Segoe UI Emoji', sans-serif;"><span class="md-plain" style="box-sizing: border-box; --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; --tw-translate-y: 0; --tw-rotate: 0; --tw-skew-x: 0; --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; --tw-scroll-snap-strictness: proximity; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / .5); --tw-ring-offset-shadow: 0 0 #0000; --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000;">3、 项目页面</span></h4>
<pre class=""><code class="language-python hljs">import streamlit as st
# 页面配置
st.set_page_config(
page_title="智能文档检索助手",
page_icon="🤖",
layout="wide",
initial_sidebar_state="collapsed"
)
# 自定义CSS样式
st.markdown("""
<style>
/* 聊天容器 */
.chat-container {
background: white;
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
margin: 20px auto;
max-width: 800px;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* 头部样式 */
.chat-header {
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
text-align: center;
border-radius: 12px 12px 0 0;
}
.chat-title {
font-size: 24px;
font-weight: 600;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.chat-subtitle {
font-size: 14px;
opacity: 0.9;
margin-top: 5px;
}
/* 聊天消息区域 */
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 20px;
background: #f8f9fa;
}
/* 消息样式 */
.message {
margin-bottom: 16px;
display: flex;
align-items: flex-start;
gap: 12px;
}
.message.user {
flex-direction: row-reverse;
}
.message-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
flex-shrink: 0;
}
.user-avatar {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.assistant-avatar {
background: linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%);
color: white;
}
.message-content {
max-width: 70%;
padding: 12px 16px;
border-radius: 18px;
font-size: 14px;
line-height: 1.4;
}
.user-message {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-bottom-right-radius: 4px;
}
.assistant-message {
background: white;
color: #333;
border: 1px solid #e1e5e9;
border-bottom-left-radius: 4px;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
/* 流式输出动画 */
.streaming-cursor::after {
content: '▊';
animation: blink 1s infinite;
color: #667eea;
}
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
/* 文档卡片样式 */
.doc-card {
background: 000000;
border: 1px solid #e1e5e9;
border-radius: 8px;
padding: 12px;
margin: 8px 0;
}
.doc-card:hover {
border-color: #667eea;
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.1);
}
/* 状态指示器 */
.status-indicator {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 500;
}
.status-rag {
background: #e3f2fd;
color: #1976d2;
}
.status-normal {
background: #f3e5f5;
color: #7b1fa2;
}
/* 隐藏Streamlit默认元素 */
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
/* 自定义按钮样式 */
.stButton > button {
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 8px;
padding: 8px 16px;
font-weight: 500;
transition: all 0.2s;
}
.stButton > button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}
/* 响应式设计 */
@media (max-width: 768px) {
.chat-container {
margin: 10px;
height: 85vh;
}
.message-content {
max-width: 85%;
}
}
</style>
""", unsafe_allow_html=True)
def display_message(role, content, docs=None):
"""显示静态消息"""
message_class = "message user" if role == "user" else "message"
avatar_class = "user-avatar" if role == "user" else "assistant-avatar"
content_class = "user-message" if role == "user" else "assistant-message"
avatar_icon = "👤" if role == "user" else "🤖"
st.markdown(f"""
<div class="{message_class}">
<div class="message-avatar {avatar_class}">
{avatar_icon}
</div>
<div class="message-content {content_class}">
{content}
</div>
</div>
""", unsafe_allow_html=True)
def main():
# 侧边栏
with st.sidebar:
st.markdown("### 📁 文档管理")
# 文档上传
uploaded_files = st.file_uploader(
"上传知识库文档",
type=['pdf', 'docx', 'txt'],
accept_multiple_files=True,
help="支持 PDF、Word 和txt文件"
)
if uploaded_files:
for uploaded_file in uploaded_files:
if st.button(f"📤 处理 {uploaded_file.name}", key=f"process_{uploaded_file.name}"):
st.rerun()
st.markdown("---")
# 已有文档
st.markdown("### 📚 知识库")
documents = [{'filename': '1.txt', 'id': 1, 'created_at': {'strftime': '1:20'}, 'chunk_count': 10},
{'filename': '2.txt', 'chunk_count': 10, 'id': 2, 'created_at': {'strftime': '1:20'}}]
if documents:
doc_options = {f"{doc['filename']}": doc['id'] for doc in documents}
selected_docs = st.multiselect(
"选择知识源",
options=list(doc_options.keys()),
help="选择后将基于文档内容回答问题"
)
selected_doc_ids = [doc_options[doc] for doc in selected_docs]
# 显示文档列表
for doc in documents:
st.markdown(f"""
<div class="doc-card">
<strong>📄 {doc['filename']}</strong><br>
<small>📅 {doc['created_at']['strftime']}</small><br>
<small>📊 {doc['chunk_count']} 个文档块</small>
</div>
""", unsafe_allow_html=True)
else:
st.info("暂无文档,请先上传")
selected_doc_ids = []
total_docs = len(documents) if documents else 0
st.metric("📊 文档数", total_docs)
if st.button("🗑️ 清空对话"):
st.rerun()
# 主聊天界面
st.markdown("""
<div class="chat-container">
<div class="chat-header">
<div class="chat-title">
🤖 智能文档检索助手
</div>
<div class="chat-subtitle">
基于知识库的智能问答系统
</div>
</div>
</div>
""", unsafe_allow_html=True)
# 状态显示
col1, col2 = st.columns([2, 1])
with col1:
if selected_doc_ids:
st.markdown(f"""
<div class="status-indicator status-rag">
🔍 知识库模式 ({len(selected_doc_ids)} 个文档)
</div>
""", unsafe_allow_html=True)
else:
st.markdown("""
<div class="status-indicator status-normal">
💭 普通对话模式
</div>
""", unsafe_allow_html=True)
# 聊天消息显示区域
chat_container = st.container()
with chat_container:
# 欢迎消息
st.markdown("""
<div class="message">
<div class="message-avatar assistant-avatar">🤖</div>
<div class="message-content assistant-message">
👋 你好!我是你的AI智能助手。<br><br>
💡 <strong>我能做什么:</strong><br>
• 📚 基于你上传的文档回答问题<br>
• 💬 进行日常对话交流<br>
• 🔍 提供准确的信息检索<br><br>
请上传文档或直接开始对话吧!
</div>
</div>
""", unsafe_allow_html=True)
# 用户输入
if prompt := st.chat_input("💬 输入你的问题..."):
# 显示用户消息
display_message("user", prompt)
print(prompt)
if __name__ == "__main__":
main()</code></pre> |
1 |
58 |
1 |
4/1/26, 4:58 PM |
4/1/26, 5:03 PM |
View Edit Delete |
| 74 |
Python安装UV |
<p>1、更新Python的pip库</p>
<pre class=""><code class="hljs language-css">pip install --upgrade pip</code></pre>
<p> </p>
<p>2、安装UV</p>
<pre class=""><code class="hljs language-undefined">pip install uv
</code></pre>
<p> </p>
<p>3、通过uv安装程序</p>
<pre class=""><code class="language-perl hljs">为了不让他卸载我本地已经安装好的东西 比如cuda版本的torch,需要加 --no-deps
# 虚拟环境安装程序如MinerU
uv pip install -U "mineru[all]" --no-deps
# 系统环境安装程序
uv pip install -U "mineru[all]" --system --no-deps
</code></pre> |
1 |
58 |
1 |
4/2/26, 6:09 PM |
4/2/26, 6:15 PM |
View Edit Delete |
| 75 |
Python格式化输出 |
<p>1、直接用pprint</p>
<pre class=""><code class="language-python hljs">from pprint import pprint as pr
pr(dic)</code></pre>
<p> </p>
<p>2、用Black</p>
<pre class=""><code class="language-php hljs">import black
def pretty(obj) -> str:
try:
# 生成对象源码字符串
code = repr(obj)
# 格式化(真正 Python 标准风格)
formatted = black.format_str(
code,
mode=black.FileMode(
line_length=50,
)
)
print(formatted)
except Exception:
# 降级输出
print(repr(obj))
pretty(list(parent_graph.get_state_history(config)))</code></pre> |
1 |
58 |
1 |
5/3/26, 12:35 PM |
5/3/26, 12:50 PM |
View Edit Delete |
| 76 |
Redis开启AOF |
<p>Ubuntu24.04默认只开RDB,AOF是不开的</p>
<p>AOF相当于MySQL的binlog</p>
<p>1、打开配置文件</p>
<pre class=""><code class="hljs language-bash">sudo vim /etc/redis/redis.conf</code></pre>
<p> </p>
<p>2、修改参数</p>
<pre class=""><code class="hljs language-bash">appendonly yes
appendfsync everysec</code></pre>
<p> </p>
<p>3、重启服务器</p>
<pre class=""><code class="language-bash hljs">sudo systemctl restart redis-server</code></pre>
<p> </p> |
1 |
29 |
1 |
5/3/26, 8:19 PM |
5/3/26, 8:19 PM |
View Edit Delete |
| 77 |
Ubuntu24.04 安装RedisStack |
<p>1、官方库截止目前没有很好的更新包,也可能我没找到。<br />2、用docker-compose最省心<br />3、先创建docker-compose.yml文件,把其中的Password换成自己的密码就行</p>
<pre class=""><code class="language-yaml hljs">services:
redis-stack-server:
image: redis/redis-stack-server:latest
container_name: redis-stack-server
restart: always
ports:
- "6379:6379"
environment:
- REDIS_ARGS=--requirepass MyPassword --appendonly yes --save 3600 1 --save 300 100 --save 60 10000
volumes:
- ./data:/data
- ./conf:/etc/redis
networks:
default:
driver: bridge</code></pre>
<p> </p>
<p>4、通过docker compose up 执行 看看有没有问题</p>
<p> 正常情况在Ubuntu24.04里面可能会出现一个警告WARNING Memory overcommit must be enabled!</p>
<p> 警告:必须开启 Linux 内存 overcommit(内存超分 / 内存过量提交)机制</p>
<pre class=""><code class="hljs language-bash">echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf
sysctl -p</code></pre>
<p> </p>
<p>5、修改完 再次启动 docker compose up,如果没问题的话后续直接docker compose up -d正常运行即可</p> |
1 |
29 |
1 |
5/4/26, 9:33 PM |
6/3/26, 7:21 AM |
View Edit Delete |
| 78 |
Java CPU飙高排查 |
<pre class=""><code class="language-bash hljs"># 查PID
# 比如查出来是29515
top
# 通过PID查线程
# 比如查出来是29581
top -H -p 29515
# 把日志输出到文件 -l代表长内容
jstack -l 29515 > thread_dump.log
#搜索关于29581的线程内容
vim thread_dump.log
/29581
</code></pre> |
1 |
5 |
1 |
5/20/26, 4:39 PM |
5/20/26, 4:39 PM |
View Edit Delete |
| 79 |
CodeGraph安装 |
<p>windows安装</p>
<pre class=""><code class="language-bash hljs">irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iex</code></pre> |
1 |
70 |
1 |
6/3/26, 8:41 AM |
6/3/26, 8:41 AM |
View Edit Delete |
| 80 |
Ubuntu24.04更新设备号并重启网络 |
<pre class=""><code class="hljs language-bash">sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id
sudo systemd-machine-id-setup
sudo systemctl restart systemd-networkd</code></pre> |
1 |
34 |
1 |
7/2/26, 1:03 AM |
7/2/26, 1:05 AM |
View Edit Delete |