原文 Agentic AI Frameworks Architectures Protocols and Design Challenges.pdf Agentic AI design taxonomy 1. 智能体核心 (Agent) 这部分定义了单个智能体的基本属性和能力: 基于角色的 (Role-based): 为智能体设定特定的身份或专业角色(如:程序员、客服、分析师)。 智能体行为 (Agent behaviour): 定义智能体如何响应指令或环境变化。 规划 (Planning): 智能体将复杂任务分解为更小、可执行步骤的能力。 学习 (Learning): 智能体通过经验或反馈不断改进自身表现的能力。 2. 交互 (Interaction) 描述了智能体之间或与人类之间的协作方式: 协议 (Protocols): 智能体通信遵循的标准或规则。 任务共享 (Task sharing): 多个智能体共同承担并协作完成一个任务。 消息传递 (Message passing): 智能体之间交换信息的技术手段。 3. 智能体即服务 (Agent-as-a-Service) 探讨了智能体的部署与云服务化趋势: W3C 规范 (W3C specifications): 遵循万维网联盟的标准,以实现 Web 端的标准化。 智能编排 (Intelligence orchestration): 对多个智能体进行调度和管理,以完成复杂流程。 RESTful 暴露 (RESTful Exposure): 通过 REST API 的方式将智能体功能开放给其他系统。 4. 框架 (Frameworks) 开发智能体所使用的底层结构: ...
Spring Security 6 类图
@startuml abstract abstract abstract class "abstract class" annotation annotation circle circle () circle_short_form class class class class_stereo <<stereotype>> diamond diamond <> diamond_short_form entity entity enum enum exception exception interface interface metaclass metaclass protocol protocol stereotype stereotype struct struct @enduml
CSS支持嵌套语法—CSS Nesting
已经很久没有关注CSS本身的发展了,看到一篇国外的文章介绍了CSS Nesting特性,感觉挺有意思的。 CSS Nesting模块定义了一种用于嵌套选择器的语法,提供了将一个样式规则嵌套在另一个样式规则内部的能力,子规则的选择器相对于父规则的选择器。 CSS Nesting与CSS预处理器(如Sass)不同,它是由浏览器解析的,而不是由CSS预处理器预先编译的。 CSS Nesting有助于提高CSS样式表的可读性、模块化和可维护性。它还可能有助于减小CSS文件的大小,从而减少用户下载的数据量。 我们都使用过Sass,Less这些CSS预处理工具,写CSS非常的舒服,用多了之后你可能已经忘记了原始的CSS如何写的,这些CSS预处理工具极大的提升了前端的开发效率和体验。 浏览器支持情况 使用Can I use网站查看哪些浏览器支持了CSS Nesting的特性 我们可以看到Firefox是支持得相对较好的,在多个版本都添加了CSS Nesting的支持,其次是Safari的技术预览版,其他浏览器也在跟进,像Chrome、Edge、Opera都已经部分支持CSS Nesting的功能。 CSS Nesting应用 Sep 20, 2023年9月20号,Safari Technology Preview 179发布了一个对CSS Nesting的更新,添加了对新的“宽松解析行为”的支持。这意味着你不再需要担心每个嵌套选择器是否以符号开头。它意味着现在像这样的嵌套CSS将正常工作: article { h1 { font-size: 1.8rem; } } 上面的代码等同于 article h1 { font-size: 1.8rem; } 而在之前的版本当中, h1 标签前面必须有一个符号出现才可以实现嵌套的特性 /* 更早的版本 */ article { & h1 { font-size: 1.8rem; } } 现在已经完全不需要前置的符号了,这里的符号指的是+ > ~ 等。 官方的草案给出了CSS Nesting的语法: main { div { ... } .bar { ... } #baz { ...} :has(p) { ... } ::backdrop { ... } [lang|="zh"] { ... } * { ... } + article { ... } > p { ... } ~ main { ... } } 一些例子 让我们来看一些例子,以更好的展示CSS Nesting的工作。 ...
Linux下文件拆分,多个文件打包后拆分
处理和传输大文件,以及处理和传输大量小文件一直很有挑战。特别是在多个存储介质,以及网络之间传输的时候。大文件无法放入一张4.7G的光盘当中;大量小文件传输需要系统打开非常多文件描述符,会造成资源浪费的情况。 本文介绍如何应对这两种情况,使用文件分割、文件压缩以及压缩时分割的方法处理文件,然后如何还原分割后的文件。 分割文件 在Linux下分割文件最常用的方法之一是使用split命令。split命令可以按固定大小分割,还可以按分割后的数量进行分割 假如我们有一个50M的文件,我们需要把它分成5个10M的部分: # 使用dd命令创建一个50M的test.txt文件 dd if=/dev/zero of=test.txt bs=50M count=1 # 可以看到文件创建成功了 # $ls -alth test.txt # -rw-r--r-- 1 Kevin None 50M Sep 14 10:34 test.txt split -b 10M test.txt test_ 上面的split命令把50M的test.txt文件拆成了5个以 test_ 开头的10M大小的文件,查看分割后的文件列表: $ ls -alth test_* -rw-r--r-- 1 Kevin None 10M Sep 14 10:36 test_ae -rw-r--r-- 1 Kevin None 10M Sep 14 10:36 test_ab -rw-r--r-- 1 Kevin None 10M Sep 14 10:36 test_ac -rw-r--r-- 1 Kevin None 10M Sep 14 10:36 test_ad -rw-r--r-- 1 Kevin None 10M Sep 14 10:36 test_aa 解释一下split命令 ...
如何微调一个大语言模型
在当今的数字化时代,大语言模型的发展正在以前所未有的速度推动着人工智能领域的进步。大语言模型,也称为大型预训练语言模型,代表了人工智能语言处理领域的一种突破。国外的有OpenAI的ChatGPT,Google的Bard,Anthropic的Claude;国内的有百度的文心一言,智谱AI的智谱清言,讯飞的星火大模型。这些都是闭源的大模型,提供了一个应用程序供使用。 现在,许多公司和研究机构都在落地大语言模型。都在尝试把大语言模型部署到企业内部,让企业内部的数据可以更加智能的利用起来。落地的方式有两种:一种是调用各大公司提供的API接口,快速把大模型的能力接入到企业内部;另外一种方式是部署开源大模型。第一种方式适合无企业敏感数据,迫切希望接入大模型的智能;而第二种针对企业的敏感数据,不希望敏感数据流出企业。 引言 本文针对企业落地大模型的第二种方式,谈一谈如何构建一个可以运行大模型和训练大模型的环境,这是企业落地大模型的第一步。 下面我们以构建一个可以使用**LLaMA-Efficient-Tuning**来微调大语言模型的镜像为例来说明。 如果你服务的企业有足够好的硬件及网络条件,同时在物理机上有安装软件的权限,那么建议你直接在物理机上安装驱动、依赖、下载微调源码,下载模型,然后进行微调。 下面介绍的流程更多的是在网络条件不允许的情况下,把所有东西都放在Docker里面是十分方便的一种做法,只需要企业内部的服务器支持Docker的运行和安装了nvidia驱动的机器即可。 构建镜像 LLaMA-Efficient-Tuning这个开源项目已经集成了非常多的开源模型的微调,比如流行的ChatGLM2,LLaMA-2等待。开箱即用,简直不要太方便。官方还提供了非常多实用的数据集 克隆项目源代码 git clone https://github.com/hiyouga/LLaMA-Efficient-Tuning.git 本文只构建训练用的Docker镜像环境,所以只需要requirements.txt的内容即可,把依赖的模块全部安装上,requirements.txt内容如下: torch>=1.13.1 transformers>=4.30.0 datasets>=2.12.0 accelerate>=0.21.0 peft>=0.4.0 trl>=0.7.1 scipy sentencepiece protobuf tiktoken jieba rouge-chinese nltk gradio>=3.36.0 uvicorn pydantic==1.10.11 fastapi==0.95.1 sse-starlette matplotlib 最好是创建一个目录,把requirements.txt放在创建好的目录下面,从这个目录启动一个docker容器: docker run -it \ --gpus=all \ --name=llm_builder \ -v "`pwd`/requirements.txt:/build/requirements.txt" \ -w "/build" \ pytorch/pytorch:2.0.1-cuda11.7-cudnn8-devel \ bash 本文以pytorch/pytorch:2.0.1-cuda11.7-cudnn8-devel Docker镜像为基础镜像进行构建,运行完上面的命令,你会进入到容器的/build目录,这个目录下面就可以看到requirements.txt文件。这是一定要加上—-gpus=all 参数。同时还要注意,物理机上必须要安装nvidia的驱动,移步官网下载安装。 然后使用下面的命令安装依赖 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple 指定了使用清华的镜像源,安装起来会快很多。 最后,需要把运行的容器保存为镜像: docker commit llm_builder cuda-11.7_pytorch-2.0.1_llm-training-runtime:v1.0 这时我们获得了一个可以运行LLaMA-Efficient-Tuning的Docker镜像了。 微调 什么是微调呢?微调语言模型涉及在较小的、特定于任务的数据集上训练模型,以适应特定的任务或领域。预训练的基础模型充当起点,网络的权重将根据特定于任务的数据进一步优化。微调有助于模型更好地理解它正在微调的任务的特定上下文和语言模式。 本文以微调ChatGLM2-6B为例,介绍如何使用LLaMA-Efficient-Tuning进行预训练、指令监督、奖励模型以及PPO和DPO训练的微调。 ...
如何构建类似Vue的极简前端框架
在开始之前,我们做一些前提设置,这个极简框架的目标是让我们避免去写一些常规的html和JavaScript代码,比如: <p id="cool-para"></p> <script> const coolPara = 'Lorem ipsum.'; const el = document.getElementById('cool-para'); el.innerText = coolPara; </script> 这个极简框架是让我们可以写一些神奇的HTML和JavaScript,就像Vue一样: <script setup> const coolPara = 'Lorem ipsum.'; </script> <template> <p>{{ coolPara }}</p> </template> 或者像React一样: export default function Para() { const coolPara = 'Lorem ipsum'; return <p>{ coolPara }</p>; } 这样的一个框架的好处是显而易见的,写代码的时候问题要记住多章节的内置变量和方法是困难的,如document、innerText、getElementById,而且也不利于软件的扩展。 我们的极简框架有两个特点:响应式和组合式。 响应式 在Vue和React代码中,数据和UI元素的显示内容有一个绑定,只要我们修改了数据,html元素的innerText值就会自动进行更新。这被称作响应式(Reactivity) 组合式 可以定义一个组件并重复使用它,而无需每次使用到它的时候还要再次定义它,这被称为可组合性。普通的HTML + JavaScript并不具备这个特性。因此,下面的代码并没有达到预期效果(仅仅是做了定义而,这有点类似Web Components的做法): <!-- Defining the component --> <component name="cool-para"> <p> <content /> </p> </component> <!-- Using the component --> <cool-para>Lorem ipsum.</cool-para> 响应式和组合式是现代前端框架的两个主要特性,例如Vue, React等待。 要利用这些抽象概念(例如框架和库),我们需要先学习很多特定的概念。当这些东西以某种神奇的方式运作时,我们还要处理它们可能产生的问题。更不用说,我们还要处理一大堆容易出错的依赖关系。 但事实上,使用现代 Web API 来实现这两件事并不困难。而且,在大多数情况下,我们可能并不需要大而全的框架及其纷繁复杂的特性… 响应式(Reactivity) 一个句话解释响应式就是:当数据更新时,自动更新 UI。 ...
如何终止无响应的 Linux 会话
使用 Linux 终端时,有时会卡住,失去响应,这时应该如何终止会话? 对于Linux用户来说,遇到卡住或不想要的用户会话可能是一种令人沮丧的体验。同时,这些会话可能会使您的系统面临潜在风险,使其容易受到未经授权的访问或数据泄露的影响。 无论是由行为不端的应用程序、系统故障还是用户错误引起的,这些延迟的会话都会阻碍生产力,并危及系统的安全性和性能。 但不要害怕;本文旨在为您提供重新获得控制权和维护平稳运行的Linux系统的知识和工具。通过学习处理这些情况的正确方法,您可以确保一个更安全的计算环境,并保护您的宝贵数据。 然而,在我们继续之前,我们需要澄清两个术语 TTY 和 PTS 的含义,它们在 Linux 中直接涉及到终止用户会话。 在Linux中什么是 TTY 和 PTS? 在Linux中,“PTS”和“TTY”都指用于在用户和操作系统之间进行通信的不同终端设备。它们充当输入命令和接收系统输出的接口。 TTY (Teletype) “TTY”最初代表电传打字机(Teletype),这是一种类似打字机的设备,在计算机早期用于输入和输出。 在现代 Linux 系统中,TTY 代表一个物理或虚拟控制台,用户可以在此处直接与系统互动。 PTS (Pseudo-Terminal Slave) PTS代表伪终端从设备。它是一个虚拟终端,模拟硬件终端,但不直接连接到任何物理设备。 相反,系统创建并管理它,以支持终端多路复用、远程登录和各种交互式应用程序。 例如,当您使用终端模拟器应用程序(如GNOME的终端或KDE的Konsole)来访问Linux系统时,通常会使用伪终端。 这些仿真器充当伪终端的“主”端,而shell或在终端中运行的进程充当“从”端。 当您打开多个终端窗口或选项卡时,每个窗口或选项卡对应一个单独的PTS。例如,如果打开三个终端窗口,它们可能被标识为/dev/pts/0、/dev/pts/1和/dev/pts/2。 总之,TTY和PTS都是Linux中的终端设备,允许用户与操作系统交互。TTY表示物理或虚拟控制台,而PTS用于终端模拟器,并提供多路复用和远程登录的附加功能。 有了这样的澄清,我们现在可以继续讨论主要议题。 如何在Linux中终止阻塞/不需要的用户会话 阻塞我们一般俗称“卡住” 😆 你可以通过两种方式来实现这一点,因此我们将在下面分别进行研究。 通过 TTY 终止用户会话 我们将使用 w 命令来获取有关我们 Linux 系统上已登录用户的信息。它显示了当前登录用户的信息和他们的活动。 当你运行 w 命令时,它会为每个用户提供以下细节的摘要: USER: 当前登录用户的用户名 TTY: 与用户会话相关联的终端名称或设备(例如/dev/tty1,pts/0) FROM: 用户登录的远程主机或IP地址。如果用户在本地登录,它将显示 TTY’s name 或者 - 符号 LOGIN@: 用户登录的日期和时间 IDLE: 用户会话处于非活动状态的持续时间。如果用户主动使用终端,它将显示 old JCPU: 与用户会话相关联的所有进程使用的CPU总时间 PCPU: 用户当前进程使用的CPU时间. WHAT: 用户执行的命令或与终端相关联的进程 以下是 w 命令的输出示例: ...
VSCode中的变量
Visual Studio Code 支持调试和任务配置文件中的变量替换以及某些选择设置。 launch.json 和tasks.json 文件中的某些键和值字符串支持使用${variableName} 语法进行变量替换。 预定义变量 支持以下预定义变量 ${userHome} - 用户主文件夹的路径 ${workspaceFolder} - 在 VS Code 中打开的文件夹的路径 ${workspaceFolderBasename} - 在 VS Code 中打开的文件夹的名称,不带任何斜杠 (/) ${file} - 当前打开的文件 ${fileWorkspaceFolder} - 当前打开文件的工作区文件夹 ${relativeFile} - 相对于workspaceFolder当前打开的文件 ${relativeFileDirname} - 当前打开的文件相对于workspaceFolder的目录名 ${fileBasename} - 当前打开的文件的基本名称 ${fileBasenameNoExtension} - 当前打开的文件的基本名称,没有文件扩展名 ${fileExtname} - 当前打开的文件的扩展名 ${fileDirname} - 当前打开文件的文件夹路径 ${fileDirnameBasename} - 当前打开文件的文件夹名称 ${cwd} - VS Code 启动时任务运行器的当前工作目录 ${lineNumber} - 活动文件中当前选定的行号 ${selectedText} - 活动文件中当前选定的文本 ${execPath} - 正在运行的 VS Code 可执行文件的路径 ...
使用WebSocket技术实现ChatGPT应用
在之前的文章当中介绍了利用Server-sent events技术实现了ChatGPT消息流回复,也就是ChatGPT在回复的时候的打字效果。本文介绍如何使用WebSocket技术来实现类似的效果,同时还实现在实时聊天的过程当中可以停止生成的功能。 WebSocket简介 WebSocket是一种网络通信协议,通常在web应用当中作用他。看这名字就知道他跟Socket有一些相似之处,但又没有太多的联系。 什么是Socket Socket翻译为套接字,就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。 Socket 通信示例 主机 A 的应用程序必须通过 Socket 建立连接才能与主机B的应用程序通信,而建立 Socket 连接需要底层 TCP/IP 协议来建立 TCP 连接。而建立 TCP 连接需要底层 IP 协议来寻址网络中的主机。 上图直接画出来了编程模型,如果用C语言或者Java语言编写过Socket应用,对上面的一些函数调用就非常的熟悉了。后面介绍的WebSocket编程模型与上面的有非常相似的地方,熟悉Socket编程模型对实现WebSocket是非常有帮助的。 什么WebSocket WebSocket是一种与HTTP不同的协议。两者都位于OSI模型的应用层,并且都依赖于传输层的TCP协议。 虽然它们不同,但是RFC 6455中规定:it is designed to work over HTTP ports 80 and 443 as well as to support HTTP proxies and intermediaries(WebSocket通过HTTP端口80和443进行工作,并支持HTTP代理和中介),从而使其与HTTP协议兼容。 为了实现兼容性,WebSocket握手使用HTTP Upgrade头从HTTP协议更改为WebSocket协议。 WebSocket协议支持Web浏览器(或其他客户端应用程序)与Web服务器之间的交互,具有较低的开销,便于实现客户端与服务器的实时数据传输。 服务器可以通过标准化的方式来实现,而无需客户端首先请求内容,并允许消息在保持连接打开的同时来回传递。通过这种方式,可以在客户端和服务器之间进行双向持续对话。 通信通过TCP端口80或443完成,这在防火墙阻止非Web网络连接的环境下是有益的。另外,Comet之类的技术以非标准化的方式实现了类似的双向通信。 大多数浏览器都支持该协议,包括Google Chrome、Firefox、Safari、Microsoft Edge、Internet Explorer和Opera。 与HTTP不同,WebSocket提供全双工通信。此外,WebSocket还可以在TCP之上实现消息流。TCP单独处理字节流,没有固有的消息概念。 在WebSocket之前,使用Comet可以实现全双工通信。但是Comet存在TCP握手和HTTP头的开销,因此对于小消息来说效率很低。WebSocket协议旨在解决这些问题。 早期,很多网站为了实现推送技术,所用的技术都是轮询。轮询是指由浏览器每隔一段时间(如每秒)向服务器发出HTTP请求,然后服务器返回最新的数据给客户端。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求与回复可能会包含较长的头部,其中真正有效的数据可能只是很小的一部分,所以这样会消耗很多带宽资源。 比较新的轮询技术是Comet。这种技术虽然可以实现双向通信,但仍然需要反复发出请求。而且在Comet中普遍采用的HTTP长连接也会消耗服务器资源。 在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。 Websocket使用ws或wss的统一资源标志符(URI)。其中wss表示使用了TLS的Websocket。如: ws://example.com/wsapi wss://secure.example.com/wsapi Websocket与HTTP和HTTPS使用相同的TCP端口,可以绕过大多数防火墙的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。 优点 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。 保持连接状态。与HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。 更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。 WebSocket的基本教程推荐阮一峰的博客https://www.ruanyifeng.com/blog/2017/05/websocket.html ...
在Spacemacs中使用conda环境启用lsp-pyright
如果你是Emacs的用户,那么肯定听说过Spacemacs,以开箱即用而出名,界面也非常的漂亮。放弃了一段时间的Emacs,之前都是自己写的配置,没有时间维护,便尝试了一下Spacemacs。 在使用Spacemacs开发Python的时候,启动lsp-pyright对Python的支持,lsp-pyright可以识别virtualenv虚拟环境,暂时还没有对conda env的支持。好在还是有办法设置python程序的路径。 实现方式用到了几个关键词方法: dotspacemacs-configuration-layers列表添加python、lsp以及conda directory local variable with-eval-after-load 下面解释每个点的配置 Spacemacs layers 启动python和lsp,这两个layer不需要做过多的设置。 启动conda的时候需要设置conda-anaconda-home变量,如下: (conda :variables conda-anaconda-home "D:/path/to/miniconda3") python解释器我使用的是miniconda,可以修改成自己对应的路径。 Directory local variable Emacs支持在项目目录创建一个 .dir-locals.el 文件,来创建针对项目文件的本地变量,而不会覆盖全局的变量。这样多个项目之间就不会相互影响了。这块可以参考官方文档。 在我们的Python项目根目录下创建一个 .dir-locals.el 文件,写入以下内容: ((python-mode . ((eval . (with-eval-after-load 'lsp-pyright (progn (lsp-register-custom-settings `(("python.pythonPath" "D:/path/to/miniconda3/envs/stringle_pro/python.exe")))) ))))) 首先python-mode 指定只有在python模式下后面的代码才会执行; (eval . func_call)是一个cons pair,eval函数相当于是标记后面的fanc_call是一个可以执行的S表达式; 如果要设置指定模式下的变量值,则使用下面的代码: ((python-mode . ((variable-name variable-value)))) with-eval-after-load with-eval-after-load 是Emacs内置的一个宏,定义在 subr.el。 这个地方是很需要注意代码运行的顺序与时机的。在Emacs打开python代码的时候会调用 lsp 启动lsp-mode,lsp会询问使用的lsp后端,python的lsp后端有非常的多,pyls, mspy等。我选择的是lsp-pyright。然后lsp根据设置的python lsp后端,加载lsp-pyright的代码。 这时上面的with-eval-after-load就会起作用了,在加载完lsp-pyright.el的代码后就会执行with-eval-after-load里面的代码。把 python.pythonPath 这个lsp变量设置完成后。 lsp就会调用lsp-pyright里面lsp相关函数,启动pyright后端。 总结 本文说明了如何在spacemacs下启用lsp来支持在conda env虚拟环境下开发python的配置工作,需要对Emacs和lsp的工作原理有一定的认识与了解。