- 博客(78)
- 资源 (3)
- 问答 (1)
- 收藏
- 关注
原创 第九章 工具3-内置中间件
本章介绍LangChain中剩余的内置中间件,涵盖能力扩展、输出质量、测试开发及文件搜索四大类。能力扩展类包括:TodoListMiddleware实现任务拆解与进度跟踪;FilesystemMiddleware提供虚拟文件系统与上下文卸载,支持持久化与安全执行;SubAgentMiddleware实现子任务委派,缓解上下文膨胀;ShellToolMiddleware赋予持久化Shell会话,结合Docker等策略保障安全。输出质量方面,RubricMiddleware通过自我评估迭代优化结果。测试开发使用
2026-11-06 19:17:56
314
原创 第八章 中间件2——内置中间件
第七章介绍中间件的核心作用,涵盖容错、成本控制、安全合规与上下文管理四大类。内置中间件如ToolErrorMiddleware和ToolRetryMiddleware实现异常捕获与自动重试;ModelFallbackMiddleware应对主模型故障;ModelCallLimitMiddleware防止无限循环;PIIMiddleware与HumanInTheLoopMiddleware保障数据安全与人工审批;SummarizationMiddleware压缩长对话上下文,LLMToolSelectorMi
2026-11-06 19:17:38
323
原创 第七章 中间件
中间件为Agent核心循环提供钩子机制,分为节点式与包裹式。节点式钩子在固定节点执行,适用于日志、校验等一次性操作;包裹式钩子则包裹模型或工具调用,可控制执行流程,实现重试、请求修改等功能。通过ModelRequest和ToolCallRequest,可安全修改调用参数、路由不同角色请求,提升Agent的灵活性与可控性。
2026-11-06 19:12:36
201
原创 第六章 工具2
ToolRuntime是LangChain 1.0引入的统一运行时机制,使工具能安全访问用户上下文、状态与长期记忆,而无需暴露给模型。它通过context传递不可变调用信息(如user_id),防止越权;通过state读取短期对话状态,结合Command实现安全写入;通过store实现跨会话的长期记忆存储;并通过stream_writer向用户推送实时进度。该机制保障了安全性与可扩展性,支持复杂代理系统的构建。
2026-11-05 15:38:04
321
原创 第四章 结构化输出
LangChain支持通过response_format与Schema配合实现结构化输出。推荐使用Pydantic模型,可自动选择ProviderStrategy或ToolStrategy,返回对象可直接点调;Dataclass和TypedDict也支持自动策略,返回字典。JSON Schema需显式包裹在策略中,Union类型仅支持ToolStrategy。structured_response是结构化结果容器,保留纯净机器可读数据,流式场景下需等待完整后再访问。
2026-11-05 15:37:36
157
原创 第三章 模型、智能体和输出
本文介绍LangChain中智能体的初始化与输出机制。推荐使用init_chat_model进行模型初始化,支持灵活参数配置。通过create_agent创建智能体,可指定模型、工具、记忆和系统提示词。输出分为同步(invoke)与流式(stream)两种模式,支持updates、messages等多类型流式输出。结构化输出可通过response_format配合Pydantic、Dataclass、TypedDict、JSONSchema或联合类型实现,其中Pydantic最推荐,能保证严格校验与类型安全
2026-11-03 14:30:08
183
原创 第二章 LangChain的使用示例
本章基于基础Agent,演示了构建功能完整的LangChain应用。通过定义get_weather工具函数并传入create_agent(),实现天气查询功能;结合InMemorySaver记忆机制,使用configurable thread_id保存对话历史,支持多轮交互。代码展示了工具调用与记忆功能的集成,适用于快速原型开发,生产环境需替换为持久化存储。
2026-11-03 09:41:14
110
原创 第一章 认识 LangChain
和是目前通用的基于大语言模型(LLM)的开源应用程序开发平台。主打开箱即用,低代码平台,直接在web界面上进行工作流编排,适合快速上线智能客服、知识问答、企业助手等场景;是的开发框架,通过编写代码实现复杂的 Agent 核心逻辑;相对于Diyf的众多限制,LangChain有足够的灵活性,当然技术难度更高。
2026-11-03 08:55:27
200
原创 log4c使用一
除了application_1.c中使用的 category、appender、layout和指定的rollingpolicy外,其它的配置都可以删除。rollingpolicy,指定滚动格式的设置,在log4crc中需要设置这种格式,即每个文件大小1024KB,最多10个日志文件。它们的关系是在category中指定appender,在appender中指定layout。初次使用,最好的教程就是源码目录下的examples/,这里面是示例代码。layout,是datad格式,这是源码库已经定义好的格式。
2025-12-19 10:48:54
663
原创 strace调试工具
在linux下写代码(在没有IDE工具的情况下,比如vi直接写程序),如果遇到段错误,通常是生成core文件,通过gdb检查错误点。但如果没有段错误,而程序没有按自己意愿执行,怎么办呢?此时可以通过对进行进行追踪。strace 主要用于追踪和,揭示了程序低层的“黑盒”。发现是因为解压缩时,目录下已经存在相同的文件,询问是否覆盖?,但因为我是通过popen()执行的gzip解压缩命令,故我直接改为使用命令强制覆盖。
2025-06-24 15:57:13
594
原创 ubuntu 20.04 安装 5.4 内核
目前已安装的虚拟机,Centos8的默认内核是4.18,Redhat9.1的内核是5.14,Ubuntu20.04的内核是5.15,故在ubuntu20.04上安装5.4内核。内核(发现它和5.14 在Block层有些差异),以对比和。(/etc/default/grub)后,还是进入默认进入。选择generic的版本进行安装,如我选择的109。若是进入Memtest x86,直接按。,从“高级”中选择5.4的内核启动。我只能暂时在系统启动时,按。确保软件包列表是最新的。
2025-01-07 10:10:24
2034
原创 删除ssh key
背景,通过ssh远程机器,第一次都会给出关于key的提示,输入:yes 可继续,此时远程机器的ssh key就保留本地,以后使用就能直接ssh。如果远程机器重装系统了,我们再ssh,由于本地存储的是之前远端机器的ssh key,就造成无言验证通过。
2024-10-18 15:31:22
907
原创 编译gcc-8.3
由于目标版本上的gcc工具很低(gcc version 4.8.5 ),此版本下无法编译驱动,故通过编译gcc-8.3源码的方式升级gcc版本;如果成功ok,如果失败。则需要分别下载download_prerequisites文件内的四个软件压缩包;(要先编译gmp);分别执行configure;会自动替换系统默认的gcc。执行完毕,再看gcc版本已经变为8.3。
2024-10-08 18:12:53
808
原创 5、闪存简述
如下图所示浮栅晶体管,当判断是0或1的时候,是在加电,当源极和漏极能导通则为1,否则为0;源极和漏极能导通的前提是源极和漏极之间充满电子。假如在加电(电子具有向电性),衬底的电子就会被吸到浮栅极,源极和漏极之间就无法导通了,此时就为0,即浮栅极充满电子为0;如在加电,电子又会从浮栅极吸出,源-漏极之间就能导电,即为1。这就是浮栅晶体管能标识0/1的原理。当随着控制极-衬底之间加电次数的增多,隧道氧化层会变得越来越薄,导致浮栅极-衬底之间电子可以相互逃逸,次数晶体管的状态就不稳定了,也就坏了。
2024-07-10 09:15:36
800
原创 4、SSD主控
主控中也有与主机中对应的队列,主控会把主机SQ中的命令搬到自己的队列中,此时的命令传输就是PCIe接口完成的,PCIe的报文格式是TLP,也就是说nvme_commnad会被封装为TLP经过PCIe传输到设备后再恢复为nvme_command;比如写,I/O请求时携带数据的,所携带的数据是不放在提交队列中的,也不会随着命令下发到主控的队列中;其次在控制器与后端闪存接口模块中,可以看到后端闪存接口模块也有自己的SRAM/DDR,此时控制器中有SQ、CQ,闪存接口模块中也有对等的队列。
2024-07-04 09:59:53
1444
原创 2、SSD基本技术
NVMe SSD有稍微区别,区别点就在于底层驱动不同,SATA/SAS接口(不管是SSD,还是HDD),底层驱动用的是SCSI,而NVMe SSD,底层驱动用的是NVMe驱动。HDD是靠磁存储,SSD是靠电存储;虽然1967年就发明了浮栅晶体管,但直到上世纪90年代,一些厂商才尝试用闪存制造SSD,闪存SSD逐渐代替RAM SSD,称为SSD市场的主流,甚至在存储市场能跟HDD抗衡。前端的接口和通信协议是标准化的,后端和闪存的接口和操作也是标准化的,所以体现不同SSD差异的地方就在FTL的算法。
2024-07-02 09:34:10
409
1
原创 1、什么是SSD?
闪存的基本结构是浮栅晶体管,他与HDD存储介质最大的区别是写之前要先进性擦除操作,但由于NAND不能只擦除一个字节,而是一次擦除一个固定大小的区域,所以即使我们只写一个字节,也要擦除整个区域,为了避免影响到这个区域的其他数据,就要先进行读取,然后再内存中进行修改,然后擦除这个区域,再把整个修改后的数据写进去;可见闪存介质的写入是比较麻烦的,要经过。NOR的特点,读快写慢,容量较小,多用于存储系统的启动程序,如BIOS,或设备的FW,这种一次写入的场合。闪存,也就是常说的flash,分为。
2024-07-01 09:30:57
1396
原创 ffmpeg压缩视频
最近需要压缩视频,windows下没找到好的工具(大部分工具需要收费),于是想到通过ffmpeg工具进行压缩;ffmpeg不仅是一款强大的视频、图片处理工具,还是一款开源的多媒体框架。需要调整的参数就是-cfr的值,这里使用的是20,它的取值范围是 [0(无损)到51(最糟)], 值越低得到的文件质量越高,一般使用18-28之间的值。
2024-06-18 15:22:38
755
原创 7、软中断原理
函数如下,不再深入介绍,我们只需要知道,通过如下函数引发中断后,内核就会通过do_softirq() 函数循环处理中断数组中的所有中断;至于如何禁用中断、如何清除软中断位图等操作也不再深入。,当并不深入介绍软中断,仅仅记录以下软中断的结构类型;毕竟用户不会直接用到软中断。结构体,只有一个成员函数指针,自然是用于绑定软中断要执行的函数:;事实上内核用一个数组表示所有的软中断,数组名为。, 每个元素的类型为。
2024-05-06 09:17:15
266
原创 6、tasklet原理与软中断
由于硬中断执行期间不能被调度且会屏蔽同类型的中断,所以它的执行时间要特别短,就需要把不紧急的任务放在所谓的“下半部”延后处理;软中的类型和编号如下,可见其资源确实比较稀缺,但由于它主要作为其他延时机制的基础,所以其限制不算大;但内核对tasklet做了更多的限制,同类型的tasklet只能串行的在一个cpu上执行;就激活了tasklet,处理器就能择机尽快执行tasklet绑定的函数了;我们上节介绍的是常规tasklet;使用软中断,只有中枢的内核代码才会用到软中断,因为软中断是很稀缺的资源;
2024-04-29 09:43:39
475
原创 5、tasklet
tasklet也是用于中断下半部的一种方法,而且是I/O驱动程序的首选方案;守护线程大部分时间都在睡眠,当进程会把工作项添加到进程所在的处理器上,守护线程被唤醒;2、初始化: 参数1,是tasklet变量;参数3,是传给函数的参数。我们首先仍然只看tasklet的用法,只需如下几部,以megaraid博通Raid。但是要注意,守护线程可以在本cpu上运行,也可以调度到其他cpu上运行。),它会创建一个cpu数量的数组,且每个数组项有一个守护线程;介绍完工作队列,不得不说一下tasklet;
2024-04-28 09:51:02
246
原创 4、工作队列用法
内核创建了一个标准的工作队列,称为events(注:每个处理器都有这样一个工作队列);故用户无需在创建工作队列,只需创建工作项;基本上每个内核模块都会自定义工作队列,一个队列上可以有多个工作项,包括延时工作项;工作队列是用内核线程去实现所需的工作,这样看来比用户空间编程还方便些,毕竟用户空间需要用户自己创建线程。由于工作队列的实现比等待队列复杂,我们不深入介绍,这里还是只看一下工作队列的用法。这种方式适合执行时间短的工作,如果执行时间长就延误了其他工作项的执行。:内核自带了工作队列,用户只需定义工作项;
2024-04-25 10:01:33
646
原创 3、完成量
这就意味着 进程不必要等待已经发生的事件;因为事件发生已经调用了complete() ,此时done已经++,而后在调用wait_for_completion()时,发现done!=0,进程就不会睡眠;这就是完成量与等待队列的差别支持!(名称上区别信号量),是根据等待队列实现的,看如下定义,可见它就是一个。函数,这俩函数我们不再展开介绍,我们主要看一下这俩函数对。但wait_for_completion()只有在。complete() 时。等待队列另加一个计数器。
2024-04-22 09:13:12
345
1
原创 2、等待队列原理深入
在上一节从使用者的角度分布介绍了等待队列、完成量和工作队列的使用场景和使用步骤;本节我们稍微深入一下,先看一下等待队列的基本工作原理,当然不会太深入,因为那是内核的工作。
2024-04-18 09:52:56
304
原创 1、等待队列、完成量、工作队列的使用场景
首先创建一个工作队列,然后加入工作项,这些工作项稍后由内核线程去执行;完成量跟等待队列的使用场景非常类似,起始完成量就是通过等待队列实现的,我们在后续介绍原理的时候看完成量的定义就一目了然了。关键在“等待”二字,用于使进程(线程)等待某一特定事件发生,进程在等待期间会睡眠,在事件发生时由内核唤醒。在名称上区分于“等待队列”;以上是我们自定义了工作队列,其实系统自带了标准的工作队列,我们只需要将新的工作项添加到该队列就行了;,但如果我们在开始等待时,起始事情已经发生,这样就永远无法唤醒睡眠的进程了;
2024-04-17 13:34:37
907
原创 Linux系统报错锦集二: engine libaio not loadable
本来我以为不需要fio源码编译了,毕竟我下载的是3.26版本的,这里已经有fio-3.27的rpm包了,但是rpm -ivh fio-3.27xxxx.rpm 后,没有找到fio的可执行文件,但安装libaio-devle需要依赖fio-3.27.幸亏还安装了redhat9.1 的vmware虚拟机,经查,在目录 /run/media/qwe123/RHEL-9-1-0-BaseOS-x86_64/AppStream/Packages/ 下存有rpm包,把需要安装的报拷贝到服务器上,
2024-01-05 18:30:17
3568
原创 Linux系统报错锦集一
我编译软Raid1.ko后,拷贝到 /lib/modules/5.15.78/kernel/drivers/md/ 目录下,重启系统依然加载的是原驱动(我驱动里面增加了日志,但是没有打印);这个问题的原因,是因为系统镜像initramfs文件的,默认先从initramfs中加载,只有镜像文件中不存在才会去标准目录下加载,所以编译ko文件,并拷贝到标准目录后,要重新生成镜像文件,命令是。只需要增大虚拟机的内存(我原虚拟机已经给了4G,给到8G后启动正常)。:Ubuntu 编译驱动,替换原驱动。
2023-12-27 17:18:56
611
原创 .png图片文件生成.h c数组文件
默认携带的头文件说是用bin2h.exe生成的,但是没有查到用法,我大概试了下无法生成.h文件;背景是edk2的开发包中背景和图标都是图片,若要修改仅仅替换图片是不行的,必须替换图片生成的.h的头文件;需要注意的是新图片和原图片尽量大小一致,不然若新图片过大,素组就会太大,可能会导致图片无法加载。之前处理文件都是通过base64编码,但在UEFI中的图片文件是通过c数组来表示的。对生成的.h文件修改数组大小的变量名及数组名,即可。重新编译edk2,发现图片已更换。
2023-10-25 09:51:50
701
原创 自编efi文件测试vmware虚拟机如何进入UEFI环境
UEFI的开源框架是edk2,开发环境配置起来还是有些麻烦,完全按照文档编译不过,经人帮助总算编译通过,但如何测试又是问题;网上各种说进入shell uefi、做uefi启动u盘,但是对我这种完全小白来说,操作起来终是困难;2、把编译的efi文件拷在u盘里,efi文件要重命名为 bootx64.efi ,不然会运行报错;四、进入步骤如下,选中u盘,比如我的u盘名称为U-TEST,然后回车进入,找到efi文件运行即可。同事突然让帮忙编一下UEFI,之前完全没有接触过,在此粗鲁记录其过程。
2023-10-24 10:31:38
2219
原创 linux进程调度三:继续实时进程
上节我们实现了实时进程,其实非常简单只需要修改进程的调度策略即可。但实时进程被调度在哪个处理器上是未知的,本节主要实现实时进程与指定处理器的绑定。命令:cat /proc/cpuinfo, 我的机器一共有4个处理器,编号从0-3,如下图显示第一个,processor:0。多观察一下就会发现,处理器的编号会发生变化,即进程发生了调度。未完待续.......
2023-10-24 10:14:46
209
原创 ubuntu设置core文件
b)设置core文件生成目录:vi /etc/sysctl.conf ,新增:kernel.core_pattern=core-%p,应该是默认开启了apport服务,ubuntu目前使用这个服务手机错误信息,但会阻止core文件的产生,这个服务用处不大,可以关闭。a)在环境变量中增加开启core文件:vi ~/.bashrc ,新增 ulimit -c unlimited,长久不写代码,突然发现ubuntu当前运行目录下没有生成core文件,记录如下,避免下次重找。这三个参数可加可不加。
2022-12-27 09:19:35
4500
原创 c++万能引用、完美转发
一、万能引用只有两种形式的引用:左值引用和右值引用,万能引用不是一种引用类型,而是代表要么是左值引用要么是右值引用。1、万能引用用在需要推断类型的场合,即以下两种场合:a)用在模板template<typename T>void tempFun(T&& t) {} //模板类型的这种用法 T && 是万能引用最常见的使用场合b)auto推断类型auto&& var2 = var1; //auto这种需要推断类型的
2022-04-19 11:21:40
7160
1
原创 c++函数模板 不定参数
函数模板不定参数,记忆中c++ primer中的例子大概如下,用到包扩展://用于匹配递归结束void func(){ }template<typename T, typename... U> //这里的U可以是不同类型void func(const T& first, const U& ... args){ cout << first << endl; func(args...);//递归调用,最后一次args为空,调用特化func
2022-04-14 11:21:31
2533
读取QTextEdit中的图片
2016-11-21
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅