CrossBox 使用记录

CrossBox 是一个 All-in-One 的,可自行架设的,的通信套件,包含了及时通信,邮件,文件存储等等组件。CrossBox 致力于为托管/电子邮件提供商提供一体化的、100%自托管的通信套件。它允许服务提供商利用现有的基础设施,为客户提供通常仅在 Gmail、Outlook 和其他大型 SaaS 平台上可用的通信功能(并且完全符合 GDPR 规定)。

服务提供商的特性

最值得注意的功能就是 CrossBox Cluster。它使服务提供商能够为不同服务器上的所有客户提供单一的入口点。其中包括统一的 Webmail URL,统一的 IMAP,SMTP,POP3 主机名以及统一的 MX。在更复杂的线上环境中,提供商还可以选择构建高可用性,负载均衡和地理分布式设置 - 使得它可以轻松实现 100%可用性,水平扩展以及来自世界不同地区的用户获得快速访问。

终端用户的特性

CrossBox 集成了超过 40 多个工具和功能,包括了邮件,即时通信,音频和视频通话,会议,屏幕分享,文件存储分享,等等。可以从官方页面的介绍中了解更多。或者直接试用线上版本 进行体验。

CrossBox 的 White-label Add-on 也可以让服务提供商自定义应用的名字,Logo,主题颜色,登录地址,[[webmail]] 域名,IMAP/SMTP/POP3 hostnames,MX 等等细节。更甚至服务提供商可以利用 在线的应用构建程序 直接生成 Android/iOS 的应用。

CrossBox 还提供了 [[DirectAdmin]],[[cPanel]],[[Plesk]] 控制面板的集成。服务提供商一键接入即可,无需任何的修改。1

现在 EV Hosting 也上线了自定义域名邮箱服务,如果你想要一个可以自己控制的域名邮箱,欢迎订购使用,现在使用 EV_MAIL_INIT 可以享受年付 5 折优惠。

reference


2023-04-29 crossbox , email-hosting , email-server , linux , mxroute

《How to Invest》 读书笔记

怎么知道的这一本书

很偶然的机会在 Twitter 上看到有人分享了读书笔记,于是就加入了待看书单。

关于作者

大卫-鲁宾斯坦 David Rubenstein 是彭博一个备受欢迎的财经访谈节目主持人。出于对历史的热爱,他还主持了一档历史节目。作为亿万富翁,他是著名的私募股权公司凯雷集团(The Carlyle Group)的联合创始人。他曾是职业律师,并担任过政府官员。

几句话总结书的内容

这是作者以主持人身份采访了一批当今大师级投资者后写的。试图总结出这批人的投资风格、思维模式、行为方式和人生态度等多方面共性。 而作者的经历也体现出富翁们的共性:高度的职业精神。

这本书的目的,他说是要向几十年前的《金钱大师》(The Money Masters)致敬。当年那本经典著作总结了 9 位大师的投资之道。而本书的重点并不是投资的干货,而是努力观察 23 位现在很活跃的投资家共同的特点。

大多数来自普通家庭 “这些人多来自蓝领和中产阶级家庭。 受过良好教育,有很好的数学能力,也有巨大的求知欲。 他们是获取信息的海绵。喜欢做最后决定,而不想把决定权交给别人。 犯了错以后也愿意承担后果,然后继续去干下一件事。”

大多数半路出家 “很多人职场的起步不是投资,之前的教育也与金融无关。都是因缘际会进入投资领域。 所以投资大师不一定是顶尖商学院出身。 如吉姆-西蒙斯是数学家,他从没想过要做投资,但他发明了量化投资。 斯坦-德鲁肯米勒原本只是想拿一个经济学博士学位,然后投身到华尔街。”

大多数失败过,所以很低调谦虚 “他们都亏过很多钱,但习以为常了。及时纠正错误是优秀投资者的标志。如果总是纠结于错误,永远不会有所成就。 他们都很谦虚,有些情况下可能是刻意的。 不喜欢吹嘘成绩。如果你遇到一个自吹自擂的人,那么这个人肯定不会成为大师级投资者。”

大多数酷爱读书的人“他们真的很热衷于阅读,阅读内容涉及各个领域,不仅仅局限在投资相关的资料上。所以他们对各种事物都有所了解也就不足为奇了。很多从事股票投资的年轻人不明白为什么要阅读书籍,他们只是跟着别人的潮流而已。他们没有发现真正的投资入门之道。优秀的投资者应当养成阅读习惯,并且要清楚自己在做什么。

大多数天生不愿盲从 “人生最容易的路是遵循传统智慧: 父母让你做,老师让你做,朋友让你做,跟着做就是了。 你可能会有不错的生活,但不会成为成功的投资者。 要获得巨大成功,你必须打破陈规,违背传统智慧。“

传统智慧会说不可能建立像亚马逊、苹果这样的公司。会告诉约翰-保尔森(08 年大空头之一),在抵押贷款市场上的空头肯定会输。会告诉吉姆·西蒙斯,量化投资不可能超过人类的头脑。 人们只是认为不能违背传统智慧。 但如果你很聪明,看到别人看不到的东西,作为投资者就会赚很多钱。”

大多数没有定见 “斯坦·德鲁肯米勒对于投资从没有定见。他做宏观投资,有时做空有时做多。 他会做任何他认为值得的事。但也有可能第二天就改主意。 所以他不喜欢给别人建议,因为他也不知道第二天会不会改变主意。”

大多数很慷慨 “他们把投资当作事业来做,不是因为钱赚不够,而是因为喜欢投资中对智慧的挑战。 但他们几乎都会最后将工作重心转向慈善,因为做慈善是一种乐趣,你必须在生活中找到真正喜欢的东西。这样当你每天做的时候,它是愉快的而不只是工作。”

“有时人们看到华尔街赚了很多钱,就认为他们非常贪婪。 实际上作为投资者,你的职业就是赚钱。通过赚钱,把资金配置给需要的公司,让这些公司创造更大的价值。 美国经济过去 200 年取得的成功,很大程度上就是因为这些投资者在做着配置资金的高效工作,他们和其他职业一样应该得到肯定。”

启发或想法

在阅读的过程中,我脑海中一直会跳跃处 [[Naval Ravikant]] ,[[芒格]] 等等人的形象,好的投资人都有一些共同的技能和特点,我一直都认为好的投资一定是做对了什么,而这些投资家做对事情的过程,以及思考,往往就隐藏在他自己的思考之中。他们所拥有的「技能」,「思想」,「习惯」,都是值得我们普通人去学习和借鉴的。在书中可以看到的是,这些投资家大多数来自于普通的家庭,往往并不是金融领域的,并且可能还遭遇过很多的失败。但是他们从来不因此而放弃,也从来不跟随市场,他们愿意承担自己的做出的选择所带来的后果,并且愿意承担错误的后果,能够及时地纠正自己的错误,谦虚低调。

最后我想说的是,投资是一门手艺,投资的经验是不可代替的,我们不应该期望通过阅读成功投资者的采访来成为更好的投资者,就像我们不应该期望通过阅读 NBA 球员的采访来成为更好的篮球运动员一样。但是我们要看到成功者身上独特的闪光点:

  • 习惯失败
  • 不愿盲从
  • 没有定见
  • 谦虚低调
  • 乐于慈善
  • 最重要的就是阅读,广泛的阅读,并形成自己独特的思考和判断能力。

谁应该看这本书

对投资感兴趣的人。


2023-04-26 invest , reading-2023 , reading , reading-2023q2

ChatGPT 打字机显示效果的背后:Server-sent Events 介绍

在使用 [[ChatGPT]] 的时候总是对它一个字一个字的出结果感到焦急,虽然也知道 AI 生成内容的时候确实是一个字一个字计算出来的。OpenAI 使用这样的一个打字机效果也确实符合这个使用场景。但是当我想要自己去实现这样的效果的时候就突然遇到了我的知识盲区,观察 Chrome DevTools,我原本还以为是用 Web Socket 实现的,但是观察了一番发现并没有 Web Socket 的连接。再观察 https://chat.openai.com/backend-api/conversation 接口,发现 content-type: text/event-stream; charset=utf-8,于是就有了这篇文章。

什么是 Server-sent Events

Server-sent Events (SSE) 是一种服务器推送技术,利用该技术可以让服务器通过 HTTP 连接向客户端推送通知,消息,事件。SSE 通常用于向浏览器客户端发送消息更新或连续数据流,通过称为 EventSource 的 JavaScript API 来增强本机跨浏览器流媒体,客户端通过请求特定 URL 来接收 Event Stream。 SSE 的 media type 为 text /event-stream

服务器推送内容

当我们开发需要数据实时更新的项目时,通常有一个问题,就是「如何从服务端向客户端发送消息/更新」,通常情况下有三种处理方式:

  • Client Polling
  • Web Socket
  • Sever-Sent Events(SSE)

Client Polling

客户端以固定间隔向服务端轮询查询更新。这个技术不是很新,实现比较简单。但这种技术只能算作准实时。

Web Socket

Websocket 是一个流行的技术,用来提供客户端和服务端的双向数据传输。

Websocket 不是基于 HTTP 协议的,所以需要额外的安装和集成,开发和实现难度稍微比 Client Polling 复杂一些。

Server-Sent Events

Server-Sent Events 是一个最新的技术,基于 HTTP,提供从服务端到客户端的异步消息通讯。几乎所有的浏览器都支持 SSE,除了 Internet Explorer。

SEE 使得服务器可以不依赖任何 polling 或 long-polling 的机制来发送消息给客户端。

GET /api/v1/live-stream
Accept: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

text/event-stream 表示客户端会从服务端等待事件流。no-cache 表示禁止缓存。

这个请求会开启一个长连接,服务端可以将实时的内容发送给客户端。Events 发送的内容是 UTF-8 编码的文本内容。

缺点

  • Server-Sent Events 的一大缺点就是数据的格式只支持 UTF-8,二进制数据是不支持的。
  • 当没有使用 HTTP/2 的时候,另一个限制就是同一个浏览器最多只能有 6 个并发连接。当使用多个标签页的时候可能成为瓶颈。

Ya7w

reference


2023-04-24 chatgpt , server-sent-events , openai , http , websocket , client-polling

在 Hestia CP 的 VPS 上安装 ionCube Loader

Hestia Control Panel ([[HestiaCP]]) 是一个免费开源的 Web 服务器控制面板,它提供了一个易于使用的 Web 界面来管理 Web 服务器和网站。Hestia CP 支持多种 Linux 发行版,包括 Ubuntu、Debian、CentOS 等,可以安装和配置 Apache 或 Nginx、PHP、MySQL 等常见的 Web 服务器和数据库软件。Hestia CP 还提供了一些额外的功能,如邮件服务器、防火墙、文件备份和恢复等。

ionCube Loader 是一个 PHP 扩展程序,用于解密和执行使用 ionCube 编码技术加密的 PHP 脚本。它通常用于保护商业 PHP 应用程序的源代码,以防止未经授权的访问和复制。我之前在安装 Clientexec 的时候短暂地接触过。之前在 lnmp 和 [[aapanel]] 上都是手动安装的,基本步骤也相差不错,下载 ionCube,然后修改 PHP 配置,在配置里面将 ionCube 扩展的本地路径配置上。

首先访问 ionCube Loader 官网,然后根据自己的系统下载对应版本的二进制。

解压之后可以得到很多 .so 文件。

cp ioncube_loader_lin_7.4.so /usr/lib/php/20190902
echo zend_extension=ioncube_loader_lin_7.4.so > /etc/php/7.4/fpm/conf.d/00-ioncube.ini
echo zend_extension=ioncube_loader_lin_7.4.so > /etc/php/7.4/cli/conf.d/00-ioncube.ini

配置 8.1

echo zend_extension=ioncube_loader_lin_8.1.so > /etc/php/8.1/fpm/conf.d/00-ioncube.ini
echo zend_extension=ioncube_loader_lin_8.1.so > /etc/php/8.1/cli/conf.d/00-ioncube.ini

重启

service php7.4-fpm restart

验证

php7.4 -v

YmCr

可以在 /usr/lib/php 目录下看到三个日期的目录,上面提到了一个 20190902 的目录。如果要配置其他 PHP 的版本,就需要用到其他的目录。

这三个数字分别代表 PHP 的版本号。20190902 代表 PHP 7.4,20200930 代表 PHP 8.0,而 20220829 代表 PHP 8.1。这些数字用于指定 PHP 扩展或应用程序所需的最低 PHP 版本。如果一个应用程序需要 PHP 7.4 或更高版本,则可以使用 20190902,如果需要 PHP 8.0 或更高版本,则可以使用 20200930,如果需要 PHP 8.1 或更高版本,则可以使用 20220829。

要注意的是 ionCube 是不提供 8.0 版本的,所以如果要求 8.0 以上,那么就需要配置 8.1 的。


2023-04-20 hestiacp , php , hestia , linux , vps

Chatwoot Nignx 代理丢失 Header 信息

之前的一篇文章介绍过如何使用 Docker 自建 [[Chatwoot]],但是最近调用 API 的时候总是发现问题。在调用最普通的接口的时候,按照要求在 Header 中传了 api_access_token,但是接口返回 401 或者是

{"errors":["You need to sign in or sign up before continuing."]}

简单的查询了一下之后,发现问题出现在 Nginx 上,Nginx 默认情况下不允许带下划线的 Header,所以当请求到 Nginx,然后转发到后台 Chatwoot 的时候这个 api_access_token 就丢了。所以一直出现 401 和需要登录的状况。

解决办法非常容易,在 Nginx 的配置 server 块中增加如下的配置

underscores_in_headers on;

然后 Nginx 配置 reload 即可,因为我使用 [[HestiaCP]] 控制面板,所以后台修改一下配置模板即可。

reference


2023-04-17 chatwoot , online-business , self-hosted , nginx , http-header , http-request , postman

Proxmox VE 安装 Ubuntu Server 22.04

之前的时候,有一台小主机,在上面安装了 [[Proxmox VE]],然后在其中安装了 [[iKuai]] 和 [[OpenWrt]] 作为软路由使用。现在已经不需要再将其作为软路由代理使用,所以今天就拿出来整理一下,正好放在家里面作为一个 Linux 小服务器,跑一些小一点的程序,然后顺便挂载一个硬盘作为一个小型的媒体服务器。

因为之前在 Proxmox VE 上安装过很多次的系统,这里就不展开,把一些重要的配置和截图放在下面。

准备 ISO

在创建虚拟机之前,需要到 Ubuntu Server 官网 下载最新的 ISO 镜像,然后把镜像上传到 ISO Images 中:

643b79d2eeb21

之后就可以开始创建 Ubuntu Server。具体的步骤如下。

创建虚拟机

首先第一步设置节点的名字(Name)

643b6ae8acf5d

然后第二步选择需要挂载的镜像。 643b73b26a6d2

第三步配置 BIOS,保持默认即可。 643b73d6849ac

第四步,选择磁盘,这里个地方可以根据自己的需要调整虚拟磁盘大小。 643b741125266

第五步,设置 CPU 核心,默认是不能超过物理 CPU 的数量的。 643b7439c5ae0

第六步,设置网络设备,我这边默认有一个 Linux 网桥(vmbr0),默认即可。 643b748c50f63

之后点击下一步,确认自己的配置,然后点击完成虚拟机的创建。

之后就可以开启虚拟机,第一次会使用设置 ISO 启动虚拟机,然后进入 Ubuntu Server 的安装界面。

安装 Ubuntu Server

第一次启动虚拟机之后会自动进入安装的程序,安装的过程比较简单,使用键盘选择,确认即可,基本上会分成如下几步:

  • 选择语言,English
  • 选择安装的类型,默认的 Ubuntu Server 即可
  • 配置网络,这个地方需要注意
    • 默认情况下安装程序会根据 DHCP 自动获取一个 IP 地址,如果这个 IP 地址不是你想要的,可以使用 Mannual 自动配置一个
    • subnet 192.168.2.0/24
    • IP 选择一个想要的,比如 192.168.2.30
    • Gateway: 网关 192.168.2.1
    • Name Server: 设置一个 DNS 解析服务器,比如 8.8.8.8
    • Search Domain: 设置一个 Search Domain,Search Domain 的作用就是当本地网络的一个解析,比如设置了 Search Domain 是 einverne.info ,那么在 Ubuntu Server 中解析 webserver 的时候会首先尝试去解析 webserver.einverne.info
  • 配置代理,不需要设置,但如果是在局域网,或者无法访问互联网的时候这个地方可以根据自己的需要设置一下
  • Ubuntu Archive Mirror,默认即可
  • 配置磁盘,可以根据自己的需求调整,我就按默认
  • 创建用户名密码等
  • 开启 SSH
  • 选择是否要安装其他组件,比如 [[microk8s]], [[NextCloud]], [[weken]], [[Docker]] 等等
  • 最后就是确认,等待安装完成

进入系统

等待安装程序安装完成之后就可以通过 IP 地址和端口,用户名和密码登录到 Ubuntu Server。


2023-04-16 proxmox , proxmox-ve , ubuntu-server , ubuntu

Sieve 一个过滤邮件的语言

之前在搭建 Mailcow 邮件服务器的时候简单的了解到了 Sieve 这个可以用来编程过滤邮件的语言。刚好现在要充分利用起 Mailcow,所以系统地学习一下 Sieve 这个邮件过滤编程语言。

什么是 Sieve

Sieve 是由 RFC 5528 定义的一门专门用来处理电子邮件的语言。它被设计不仅可以用于邮件客户端的邮件过滤,也可以在邮件服务器端进行过滤。设计它的目的在于扩展性,且独立于邮件架构和操作系统。 它适合运行在不允许用户执行程序的邮件服务器上运行,例如在 IMAP 服务器上。因为 Sieve 中没有变量,没有循环,也不运行调用外部的 Shell。

Sieve 不是什么

  • Sieve 不计划独立成为一门成熟的编程语言
  • Sieve 并不适用于过滤或处理除 RFC 822 消息以外的内容
  • Sieve 也不打算代替现存的其他工具

Sieve 过滤器的格式

Sieve 没有特别复杂的结构,只是包含一组命令,比如 discard, if, fileinto 等等

require ["fileinto", "reject"];

# Daffy Duck is a good friend of mine.
if address :is "from" "[email protected]"
{
    fileinto "friends";
}

# Reject mails from the hunting enthusiasts at example.com.
if header :contains "list-id" "<duck-hunting.example.com>"
{
    reject "No violence, please";
}

# The command "keep" is executed automatically, if no other action is taken.

第一行脚本(require 命令)告诉 Sieve 解释器将使用可选的命令文件。然后是两个过滤规则。第一个过滤规则将所有来自 “ [email protected]” 的邮件存储到名为“friends”的邮箱中。第二个规则拒绝头部包含字符串“”的 List-Id 字段的邮件。

如果脚本中没有匹配的条件,则应用默认操作,即隐式“保留”命令。该命令将邮件存储在默认邮箱中,通常是 INBOX。

Sieve 有两种注释写法

# Everything after # character will be ignored.

/* this is a bracketed (C-style) comment. */

和地址比较,From:, To:, Sender:

还有三个可选的参数可以用来比较

  • :localpart@ 符号前面的部分
  • :domain@ 符号后面的部分
  • :all,全部
# The two test below are equivalent;
# The first variant is clearer and probably also more efficient.
if address :is :domain "to" "example.com"
{
    fileinto "examplecom";
}
if address :matches :all "to" "*@example.com"
{
    fileinto "examplecom";
}

一个邮件地址通常是 "FirstName LastName" <[email protected]> 这样组成的。

比较 Header 中其他字段。

# File mails with a Spamassassin score of 4.0 or more
# into the "junk" folder.
if header :contains "x-spam-level" "****"
{
    fileinto "junk";
}

匹配类型

Sieve 提供了三种比较方法:

  • :is,比较两个字符串完全相等
  • :contains,是否包含
  • :matches,使用通配符 ? 来匹配一个未知字符,使用* 来匹配零个或多个未知字符
# Reject all messages that contain the string "viagra"in the Subject.
if header :contains "subject" "viagra"
{
    reject "go away!";
}
# Silently discard all messages sent from the tax man
elsif address :matches :domain "from" "*hmrc.gov.uk"
{
    discard;
}

List of Strings

匹配列表:

# A mail to any of the recipients in the list of strings is filed to the folder "friends".
if address :is "from" ["[email protected]", "[email protected]", "[email protected]"]
{
    fileinto "friends";
}

如果要表达,from 或 sender 是某邮箱的时候,做什么

# Check if either the "from" or the "sender" header is from Porky.
if address :is ["from", "sender"] "[email protected]"
{
    fileinto "friends";
}

如果要组合表达

# Match "from" or the "sender" file with any of Daffy, Porky or Speedy.
if address :is ["from", "sender"] ["[email protected]", "[email protected]", "[email protected]"]
{
    fileinto "friends";
}

allof, anyof

  • allof 测试列表,如果列表中的每一个都是 true,则返回 true,逻辑上的 and
  • anyof 测试列表,只要其中一个满足,则返回 true,逻辑上的 or
# This test checks against Spamassassin's header fields:
# If the spam level ls 4 or more and the Subject contains too
# many illegal characters, then silently discard the mail.
if allof (header :contains "X-Spam-Level" "****",
          header :contains "X-Spam-Report" "FROM_ILLEGAL_CHARS")
{
    discard;
}
# Discard mails that do not have a Date: or From: header field
# or mails that are sent from the marketing department at example.com.
elsif anyof (not exists ["from", "date"],
        header :contains "from" "[email protected]") {
    discard;
}

过滤信息大小

可以使用 size 来检测

# Delete messages greater than half a MB
if size :over 500K
{
    discard;
}
# Also delete small mails, under 1k
if size :under 1k
{
    discard;
}

Example

一个简单的 Sieve 过滤器的例子是将所有来自特定发件人的邮件自动转发到另一个邮箱。下面是一个示例 Sieve 脚本:

if header :contains "From" "[email protected]" {
  redirect "[email protected]";
}

这个脚本将检查邮件的发件人是否是”[email protected]”,如果是,则将邮件重定向到”[email protected]”。

Mailcow

在 Mailcow 中可以通过如下的路径设置 Sieve 过滤器。

Configuration -> Mail Setup -> Filters -> Add filter

另外如果有人想要创建自己的自定义域名邮箱,欢迎到 EV Hosting 订购使用。

reference


2023-04-12 mail , mailcow , sieve , email , programming-language

Raycast AI 使用体验

在之前的文章中就提到过 Raycast,前不久看到 [[Raycast]] 快速跟进了 OpenAI,现在推出了 Raycast AI,我没有想到的是,Raycast 的使用场景可以如此完美地和 AI 结合在一起。

Raycast 代替了如下我过去常常做的事情:

  • 再不需要打开网页,或者 ChatGPT 客户端再输入问题
  • 再不需要打开 Papago(或者 DeepL 等客户端)翻译段落(短句和单词基本靠 Chrome 插件和 [[GoldenDict]])
  • 再不需要打开 OpenAI Translator 对文本进行润色
  • 直接在 Obsidian 中让 Raycast AI 进行语法检查,改写,并一键替换原文
  • 代替 [[Cursor.so]] 编辑器的自然语言编程,Raycast AI 可以用来解释代码,生成代码并直接插入编辑器

直接提问

sna8

翻译

选中文本,然后 Cmd+Space,translate 即可。 ss9n

润色文本

直接使用 Improve Writing,并将润色过的文本直接粘贴回 Obsidian。 sYjl

总结

如果在网上看到一段非常长的文章,可以直接选中,然后让 Raycast 总结。 sA2g

Create AI Command 创建自己的命令行

可以看到的是上面的所有的操作,大部分都是 Raycast AI 默认自己定义的,但是 Raycast AI 更强大的一点在于它可以自己创建 AI Command(prompt),也就是说可以利用 OpenAI 的上下文对话的能力,将一些固定的模式写道 Raycast 中,然后下次使用的时候就可以直接输入几个字母触发了。也可以利用 Raycast 自己的快捷键来一键呼出。

一些使用小 Tip

Raycast 本身已经非常强大了,但是有一些贴心的功能他没有展示出来,需要用户自己去发现,下面就是一些使用的小 Tip。

  • 如果不满意 Raycast AI 的结果,可以直接按 Cmd+R 重新生成。
  • 生成内容之后可以使用 Cmd+k 来对结果进行更多的操作,比如复制,比如粘贴回选中的地方
  • Raycast AI 可以设置快捷键,比如可以将常用的 Ask AI,translate 等等设置一个单独的快捷键

alternative

如果还没有排到 Raycast AI,还可以试试 macOS 上的 MacGPT

折扣码

Raycast AI 将会进入 Raycast Pro 的套餐,每个月 8 美元,目前可以使用 RAYFRIENDS10 来获取 10% 的折扣。

raycast ai pro


2023-04-09 raycast , launcher , macos , openai , ai , chatgpt

LangChain 是什么

LangChain 是一个围绕大型语言模型 ([[LLM]])的应用开发框架,或者说是工具集,使用 Python 编写。LangChain 是由 Robust Intelligence 前的机器学习工程师 Chase Harrison 在 10 月底开源的工具库。众多 AI Hackathon 决赛项目使用 LangChain,它的 Github Star 迅速突破万,成为 LLM 应用开发者在选择中间件时最先想到的名字。

LangChain 能做什么?

  • 个人助理,记住用户的行为数据并提供建议
  • 聊天机器人,语言模型天然擅长生成文本
  • 生成式问答
  • 文档回答,针对特定的问题回答
  • 文本摘要,从文本中提取信息
  • 代码理解,理解代码的意图
  • 文本总结,从较长的文本中总结信息

模块

LangChain 主要提供如下的模块来支持快速开发:

  • Models 支持各种模型及集成
    • LLMs,LLM 通用接口,LLM 相关常用工具
  • Prompt,Prompts 管理,提示优化,提示序列化
  • Document Loaders,文档加载的标准接口,与各种格式的文档及数据源集成
  • Chains,包含一系列的调用,可能是一个 Prompt 模板,一个语言模型,一个输出解析器,一起工作处理用户的输入,生成响应,并处理输出
  • Agents,Agent 作为代理人去向 LLM 发出请求,采取形同,检查结果,直到工作完成。
  • Memory,是在 Chains 和 Agent 调用之间的持久化状态
  • Indexes 将自己的文本做索引

用不到 50 行代码实现一个文档对话机器人

我们都知道 [[ChatGPT]] 训练的数据只更新到 2021 年,因此它不知道最新在互联网上产生的内容。而且 ChatGPT 的另一个缺点就是当他不知道的时候就会开始一本正经的胡说。但是利用 LangChain 可以用不到 50 行的代码然后结合 ChatGPT 的 API 实现一个和既存文本的对话机器人。

假设所有 2022 年更新的内容都存在于 2022.txt 着一个文本中,那么通过如下的代码,就可以让 ChatGPT 来支持回答 2022 年的问题。

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os

import jieba as jb
from langchain.chains import ConversationalRetrievalChain
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import DirectoryLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import TokenTextSplitter
from langchain.vectorstores import Chroma


def init():
    files = ['2022.txt']
    for file in files:
        with open(f"./data/{file}", 'r', encoding='utf-8') as f:
            data = f.read()

        cut_data = " ".join([w for w in list(jb.cut(data))])
        cut_file = f"./data/cut/cut_{file}"
        with open(cut_file, 'w') as f:
            f.write(cut_data)


def load():
    loader = DirectoryLoader('./data/cut', glob='**/*.txt')
    docs = loader.load()
    text_splitter = TokenTextSplitter(chunk_size=1000, chunk_overlap=0)
    docs_texts = text_splitter.split_documents(docs)
    api_key = os.environ.get('OPENAI_API_KEY')
    embeddings = OpenAIEmbeddings(openai_api_key=api_key)
    vectordb = Chroma.from_documents(docs_texts, embeddings, persist_directory='./data/cut/')
    vectordb.persist()
    openai_ojb = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")
    chain = ConversationalRetrievalChain.from_llm(openai_ojb, vectordb.as_retriever())
    return chain

chain = load()

def get_ans(question):
    chat_history = []
    result = chain({
        'chat_history': chat_history,
        'question': question,
    })
    return result['answer']

if __name__ == '__main__':
    s = input('please input:')
    while s != 'exit':
        ans = get_ans(s)
        print(ans)
        s = input('please input:')

reference


2023-04-05 langchain , llm , ai , artificial-intelligence , chatgpt , gpt-3 , gpt-4 , openai , embedding , vector-database

介绍一下新推出的 EV Hosting 网络共享托管服务

因为自己之前买过一些 VPS,但是一直空闲很多,所以想着是否能够充分利用起来。最近正好看到可以免费使用 [[Clientexec]] 管理 Web Hosting 账单,所以隆重介绍一下刚刚推出的新服务 EV Hosting,目前上线了两个功能,共享网站托管服务和自定义域名邮箱服务。

新加坡 共享网站托管服务

共享网站托管服务(Shared Web Hosting) 是一种网站托管服务,是将多个网站存储在同一台服务器上,并共享服务器上的 CPU、内存和带宽。这种类型的托管服务通常是最便宜和最受欢迎的选择,特别适合个人和小型企业。

如果你是一个不懂技术的个人但想在网络上有一片属于自己的空间,或者你想以最低的成本开展在线商城,欢迎来订购使用。

本站提供的托管服务,服务器位于新加坡,CPU 是 AMD Ryzen 9 3900X 12-Core Processor,服务器共 128 GB 内存。

ev hosting sg

一键安装超过 400 种应用

目前该服务托管于新加坡的服务器,使用 [[DirectAdmin]] 面板,装有 [[Softaculous]],可以一键安装包括 [[WordPress]],[[Joomla]],[[NextCloud]],[[Tiny Tiny RSS]],[[miniflux]],[[FreshRSS]],[[phpmyadmin]] 等等超过 450 种的应用程序1,不少的应用我之前也是介绍过的,并且还一直在用,比如 [[NextCloud]] 这个文件同步工具,[[miniflux]] 这个 在线的 RSS 阅读器。Softaculout 非常强大,很多功能和特性有待你去发现。

DirectAdmin 后台也有一个在线的文件管理器,可以直接基于网页对网站内容进行管理。

nrWr

自定义域名邮箱

另外订购所有的套餐都可以在后台配置自定义邮箱,每一个邮箱每个小时可以发送至多 200 封邮件。请不要滥用发件发送恶意、垃圾邮件。

也可以使用后台提供的 Roundcube 网络邮箱界面来管理自己的邮件。

MySQL 数据库

购买套餐之后可以在后台创建响应的 MySQL 数据库供应用程序保存数据使用。所有的数据库内容及网站内容都会定期通过备份来保证安全。

附加功能

可以通过附加功能,来设置 Node.js,PHP,Python 等应用程序。

neId

为了庆祝上线,在订购所有年付套餐的时候输入 EVHOSTING 则可以享受 5 折的优惠(优惠截止 4 月末)。最低可以以 8 元购买一年 Bronze 套餐(限量 10 个,如果看到界面显示优惠券代码无效则表示优惠码用完或已经过期)。

加利福尼亚 网络优化 共享空间

加利福尼亚的共享空间是大陆网络优化空间,到大陆的网络延迟非常文档。

ev hosting us

自定义域名邮箱服务

如果你只需要发送邮件的服务,那么也可以订购这个自定义域名邮箱的服务,订购服务之后需要我手工启用,后台使用的是 Mailcow,我再添加了域名之后会给你的邮箱发送相应管理后台的信息。

所有在线购买的产品都可以通过在线提交工单的方式获得支持,并且后续会陆陆续续更新更多相关的使用技巧,欢迎关注。另外服务刚刚上线,如果有任何使用的问题,反馈并且到的验证的都可以免费获取一年的 Bronze 套餐。


2023-04-04 hosting , email , mailcow , clientexec , online-business , vps

电子书

最近文章

  • macOS 自定义系统设置记录 因为电脑空间告警,所以用 Clean Me 这个应用对系统进行了一次清理,没想到的是,可能在我误操作的情况下把我系统的设置和全部软件的设置都给清空了。我所有的系统配置都恢复了初始的状态,让我使用起来非常变扭,我在之前有写过一篇 MacBook 初始化和应用安装 的文章,但是那篇文章写的比较啰嗦,索性就重新整理一下。
  • EV Hosting 共享邮件服务 过去的一个月里面 EV Hosting 陆陆续续更新了共享主机服务,域名注册服务,现在因为我自己使用域名邮箱一直也在使用域名邮箱,所以现在也推出了域名邮箱服务。
  • 《非暴力沟通》读书笔记 怎么知道的这一本书
  • Drift 一个开源可以自托管的 Gist Drift 是一个可以自行架设的 Gist 代替。使用 [[Next.js]] 13 和 React Server Components 编写。
  • Google Analytics 代替产品对比 虽然我把其他服务陆陆续续从 Google 迁移出来,但 Google Analytics 一直都运行良好所以也没有怎么管,但 Google Analytics 到今年年中的时候会强行升级 GA4,看了一下升级的过程和 Google Analytics 的操作实在太复杂,就诞生了迁移出 Google Analytics 的想法。简单地了解了一下目前的 Google Analytics 的代替品,收费的,自行架设的还很多选择。这篇文章就简单地对比一下。