自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(40)
  • 收藏
  • 关注

原创 AI Agent 中的 Skill:从 Tool 调用到任务能力封装

适用于:用户询问个人知识库中的内容。执行规则:1. 优先检索知识库2. 根据查询内容生成检索关键词3. 获取相关文档片段4. 基于检索结果回答5. 输出引用6. 不编造知识库不存在的内容把 Agent 完成某一类任务所需要的知识、规则、工具和执行策略封装成一个独立、可复用的能力模块。Tool 负责“做什么”Skill 负责“怎么做”MCP 负责“怎么接入 Tool”Workflow 负责“按什么步骤做”Agent 负责“什么时候做、做什么”Skill├── Tool。

2026-09-19 16:25:29 230

原创 GitHub Actions + 阿里云 ECS:给 Go + Vue 项目从零搭一套 CI/CD(附 5 个真实踩坑)

回头看,这套 CI/CD 给我带来的最大收获不是「省了部署时间」,而是三个认知上的转变。第一,把「人肉记忆」换成「流水线校验」。以前发布前要默念一遍:测试跑了吗?配置改了吗?镜像重新 build 了吗?现在这些都会自动检查,漏了就直接红。人靠不住,流程靠得住。第二,「能跑」和「构建成功」是两回事。成功只代表每条指令没报错,不代表容器能起来。健康检查、冒烟测试这些「看起来多余」的步骤,才是真正拦住故障上线的东西。第三,回滚能力比部署能力更重要。一个不能回滚的部署系统,本质上是在赌博——赌每次改动都没问题。

2026-09-11 11:01:25 296

原创 GC揭秘:混合写屏障

方案插入屏障(老Go)删除屏障混合写屏障(Go现版)保护对象新指针旧指针旧指针(全量) + 新指针(仅灰栈)栈处理需STW重扫依赖快照初始全黑,无需STW重扫性能损耗栈写入开销大浮动垃圾较多栈写入零屏障,极速没有完美的银弹,只有最适合的取舍。它牺牲了理论上回收精度的极致(允许少量浮动垃圾),换取了CPU与暂停时间的极度平衡。正是因为这个设计,Go才能在拥有数十万Goroutine的高并发场景下,依然保持亚毫秒级的GC延迟。

2026-08-29 20:30:51 421

原创 MCP:外部工具集成的设计权衡与实践

将MCP集成进Agent系统,本质上是如何在开放性与可控性之间取得平衡。开放意味着用户可以自由接入任意外部工具,快速扩展能力边界;可控则要求系统对每个工具的认证、权限、资源消耗和副作用有明确的约束。这种平衡不是静态的——导入阶段的多层校验、运行时动态授权、调用链的全程审计,都是在不同环节介入控制点,而非一味放宽或收紧。

2026-08-14 15:13:29 397

原创 A2A以及它在Eino框架中的应用

A2A(Agent-to-Agent)协议,是由 Google 于 2025 年 4 月发起、现由 Linux 基金会管理的开放标准。它的核心目标是让不同厂商、不同技术栈开发的 AI 智能体能够顺畅通信、交换信息并协同行动。简单来说,A2A 要解决的是 AI 智能体之间的“横向协作”问题。如果说 MCP(Model Context Protocol)解决的是 Agent 如何调用工具和数据(纵向连接),那么 A2A 解决的就是 Agent 之间如何分工配合——前者是“手”,后者是“大脑之间的对话”。

2026-08-06 20:37:11 325

原创 LLaMA-Factory进行模型微调、合并与Ollama部署全流程指南

准备数据:从魔搭等平台获取数据集,转换格式后在中注册LoRA微调:配置YAML文件,执行训练合并模型:将LoRA适配器与基座模型合并为完整模型格式转换:使用llama.cpp将HF格式转为GGUF格式部署Ollama:创建Modelfile,用导入,ollama run运行整个过程虽然步骤不少,但LLaMA-Factory把大部分复杂操作都封装成了配置文件和命令行,大大降低了门槛。希望这篇文章能帮助到正在学习模型微调的朋友们。

2026-07-30 17:38:52 268

原创 基于 Eino 框架实现简单的 RAG

RAG(Retrieval-Augmented Generation,检索增强生成)是目前解决大模型幻觉问题最有效的手段之一。它通过从外部知识库中检索相关信息,并将其作为提示输入给大语言模型,从而增强模型处理知识密集型任务的能力。然而,网上的 RAG 教程大多是 Python + LangChain 的 Demo,Go 语言开发者长期以来缺乏一套成熟、可用的 AI 应用开发框架。直到字节跳动 CloudWeGo 团队开源了Eino框架,这一局面才得到根本改善。

2026-07-23 17:01:35 209

原创 MCP:大模型 Agent 时代的“万能插座板”协议

MCP 没有发明新的黑科技,但它用“加一层”的经典思路,解开了 AI Agent 工具链中最关键的耦合死结。它让我们看到,大模型与外部世界的交互,可以不再是一堆零乱的胶水代码,而是一套优雅、可复用、可发现的协议。

2026-07-13 20:35:51 407

原创 什么是RAG?

简单来说,RAG是一种让大模型“开卷考试”的技术。传统的大模型回答问题,好比一个闭卷考试的考生——只能依靠自己记忆中的知识。而RAG则让这个考生可以翻阅指定的参考资料——在回答问题之前,先从外部知识库中检索相关信息,再结合这些信息生成答案。检索(Retrieval):根据用户的问题,从知识库中找出最相关的文档或片段增强(Augmentation):将检索到的信息与用户问题拼接,形成 enriched 的提示词生成(Generation):大模型基于增强后的提示词,生成最终的答案。

2026-07-04 21:48:22 336

原创 Ollama: 模型快速部署与使用

Ollama 的出现,真正把大模型从“只有深度学习工程师才能摆弄”的高阁拉回到了每一个开发者的终端里。它屏蔽了底层复杂的依赖和优化细节,却保留了足够的灵活性和可扩展性。无论你是想在个人项目中嵌入 AI 能力,还是在公司内部搭建隐私安全的 LLM 服务,Ollama 都是那个值得首选的“快速部署与使用”方案。

2026-06-27 21:36:07 443

原创 Gorm: 让 Go 语言数据库操作更优雅

GORM 是一个全功能的 Go 语言 ORM 框架,它通过将结构体(struct)映射为数据库中的表,将结构体字段映射为表中的列,让开发者可以用面向对象的方式操作数据库。无需手写冗长的 SQL 语句,即可完成增删改查、关联查询、事务、钩子函数等高级操作。官方仓库官方文档GORM 通过结构体来定义数据库表模型。约定优于配置:默认使用结构体名称的蛇形复数形式作为表名,字段名的蛇形形式作为列名。not null"`size:255"`结构体标签(tags)可以详细定义列名、类型、索引、约束等。

2026-06-20 10:34:23 245

原创 Transformer:让机器读懂上下文的艺术

让每个词都能直接注意到句子中的任何其他词,从而捕获全局依赖。这个简单的机制凭借高度的并行性和可扩展性,战胜了循环和卷积架构,开启了自然语言处理乃至计算机视觉的新纪元。

2026-06-14 15:06:20 363

原创 事件驱动机制:从餐厅点餐说起

事件驱动并不是某个框架的专有名词,而是一种把控制权交给“事件”,用响应代替轮询的编程思想。理解它的关键在于把握三个转变:1. 从主动调用到被动通知——不再是“你持续去问好了没有”,而是“好了之后你告诉我”。2. 从线性执行到异步分发——程序流程不是一串直行到底的代码,而是由一个个独立的事件处理片段拼接而成。3. 从紧耦合到松耦合——事件生产者和消费者之间通过“事件”媒介沟通,实现系统的弹性与可扩展性。

2026-06-03 19:31:10 351

原创 一篇读懂JWT

JWT 全称,是由RFC 7519标准定义的一种紧凑、自包含的令牌格式,用于在网络双方之间安全地传输信息。紧凑(Compact):JWT 本质上是一个很短的字符串,可以方便地放在 URL 参数、HTTP 请求头里传输。自包含(Self-contained):JWT 里面已经包含了用户的所有必要信息(比如用户 ID、角色、过期时间等),服务器收到后直接解析就行了,不需要再去数据库里查用户信息。无状态(Stateless):服务器不需要存储任何会话信息。

2026-05-23 16:01:06 443

原创 生成式AI的响应原理:文字接龙

读到这里,你应该已经对生成式 AI 的响应原理有了清晰的认知。无论是文本大模型还是图像/视频生成模型,它们在本质上都是庞大的“概率机器”——通过对海量数据中蕴含的统计规律进行建模,生成出符合我们预期的内容。文本大模型的核心流程是Token 化 → 词嵌入 → Transformer 自注意力计算 → 概率采样 → 逐词自回归生成。用简单的话描述就是:ai使用你的输入去计算出最有可能出现的下一个字,再把这个结果当作输入再次计算,直到输出结束标志或者超出文本限制。

2026-05-02 11:09:07 460

原创 布隆过滤器,看这一篇就够了

一句话记住布隆过滤器它就像一张画有黑点的草稿纸——要检查的点有任何一处是白的(0)→ 元素绝对没来过;全是黑的(1)→ 元素可能来过,但也有可能是别人的指纹误伤。经典布隆过滤器的死穴:不支持删除。一旦数据需要频繁变更,就会很麻烦。进化版:布谷鸟过滤器(Cuckoo Filter)为了解决删除痛点,布谷鸟过滤器引入了“桶”和“指纹”的存储方式,支持安全删除,并且在低误判率场景下空间利用率更高,查找、插入、删除均为 O(1) 时间复杂度。

2026-04-25 08:48:29 406

原创 Gin:自定义日志、验证器与中间件全指南

在使用 Gin 开发 Web 服务时,默认的功能已经能覆盖大部分场景,但在生产环境中我们往往需要更精细的控制——比如定制日志格式以便于 ELK 采集、增加业务专属的参数校验规则、或者编写通用的请求拦截中间件。Gin 本身提供了非常优雅的扩展机制,本文将结合四个实际示例,带你彻底掌握 Gin 中四个常用自定义能力的实现方法。虽然信息完整,但格式较为固定。如果我们需要与现有日志平台对接,或希望记录更多字段(例如 User-Agent、错误信息等),可以使用自定义日志输出格式。// 使用自定义格式的日志中间件。

2026-04-19 11:34:14 190

原创 goweb表单

对于多选框(checkbox)、多选列表(select multiple),同一个。客户端验证可被轻松绕过(禁用 JS、改请求)。等,但普通 HTML 表单只支持 GET/POST。读取整个文件到内存,大文件会导致 OOM;会提交多个值,服务端需用数组方式接收。属性,否则不会被浏览器提交到服务器。示例:多值字段(checkbox),或需要区分参数来源,显式调用。:对于 RESTful 风格,防止重复提交和重放攻击。可获取多值字段的切片;)等,根据业务需要添加。若只需单个值,直接用。补充:手动解析的时机。

2026-04-11 14:49:13 386

原创 HTTP状态码

HTTP响应状态码用来表明特定的HTTP请求是否完成,共有五大类:1.信息响应(1xx)2.成功响应(2xx)3.重定向消息(3xx)4.客户端错误响应(4xx)5.服务端错误响应(5xx)

2026-04-02 09:42:24 320

原创 Git 从入门到实战:一篇搞定版本控制

在软件开发中,版本控制是必不可少的一环。Git 作为目前最流行的分布式版本控制系统,几乎是每位开发者的必备技能。本文将从零开始,带你全面掌握 Git 的核心概念与常用操作,包括安装配置、本地仓库管理、分支策略、远程仓库协作,以及在 IDE 中的集成使用。无论你是刚接触 Git 的小白,还是希望巩固基础的老手,相信都能从中受益。

2026-03-28 21:16:26 301

原创 redis缓存

问题核心原因应对策略缓存击穿热点 key 失效瞬间高并发互斥锁、永不过期、预加载缓存穿透查询不存在的数据缓存空对象、布隆过滤器、参数校验缓存雪崩大量 key 同时失效或节点故障随机过期时间、多级缓存、高可用架构、限流降级通过合理设计和组合这些方案,可以有效提升缓存系统的稳定性,保护后端数据库。

2026-03-21 10:58:13 163

原创 Redis持久化策略

数据量大时 fork 子进程可能造成主线程短暂阻塞,不适合强实时、零丢失场景。

2026-03-14 09:44:51 337

原创 go-redis使用聊天室功能实现

Redis 作为内存数据存储,凭借丰富的数据结构和高效性能,在即时通讯系统中扮演着重要角色。本文通过一个聊天室项目的实际代码,分析了用户缓存、历史消息、消息队列和排行榜的实现。希望这些内容能对你有所帮助,欢迎留言讨论!备注:本文是借助ai分析代码来写的,内容有不当地方请仔细辨别!!!

2026-03-08 10:47:32 330

原创 redis发布订阅和Stream

Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。Redis 客户端可以订阅任意数量的频道。缺点:消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。简单来说发布订阅可以分发消息,但不能记录历史消息。

2026-02-27 16:21:02 735

原创 docker私有仓库搭建以及镜像上传、拉取和删除

docker ps,用该命令看有无该容器,查看有后我们可以去浏览器输入地址来查看我们的私人仓库: http://私有仓库ip:端口号/v2/_catalog 这里的私人仓库ip是我们linux通过ip addr查看ens33里的ip,例如192.168.100.188。通过该命令来修改此文件,我们进入文件内部后,查找到 "insecure-registries": 语句,在里面加一行 "私人仓库ip:端口号" 后保存文件退出就可以了(ip和端口号要改成自己的)。

2026-02-04 20:49:29 514

原创 go栈与队列之窗口最大值

再设计pop()函数,由刚才的push()函数设计就知道,队列里面的元素个数不一定等于滑动窗口里的元素个数。单调递减队列是左边(队列出口处)的值最大,所以窗口最大值就是索引0处,通过队列的pop()和push()函数,来设计吧。当要进来的元素比入口处元素大时,进来后就不成单减队列了,所以要先比较,把比他大的元素都弹出,然后再将该元素加入队列。最开始的滑动窗口值,只能用push()函数,通过它让我们的队列成单调递减,那么我们先设计push()函数。// 比入口元素大的就弹出元素,直到比它小。

2026-01-26 20:25:36 569

原创 go栈与队列之有效的括号

首先需要的栈的功能入栈和出栈是必备的,要匹配栈顶元素的括号是否对应,还需要返回栈顶元素的功能,最后匹配完后看是否有多余的括号,需要返回栈是否为空的功能。当在s的1索引后,栈内是 ( [ ,到2索引后s[2] = ] ,此时出栈,将 ] 和 [ 进行匹配,栈内只有( 了。if val == '(' || val == '[' || val == '{' { //左括号入栈。当遇到左括号入栈,遇到右括号先返回栈顶元素进行匹配,若对应则出栈。情况一:左边有多余括号,如((){[]},多了最左边的(

2026-01-24 09:26:06 600

原创 go栈和队列之用栈实现队列

func (s *MyStack) Peek() int { //返回栈顶元素的值。func (s *MyStack) Size() int { //查看栈内元素个数。func (s *MyStack) Size() int { //查看栈内元素个数。func (s *MyStack) Push(val int) { //入栈。func (s *MyStack) Push(val int) { //入栈。func (this *MyQueue) Fill() { //输出栈的填充。

2026-01-15 16:48:12 564

原创 关于罗振宇跨年演讲的感受

还有一个ai在教育上的革命。在ai面前,在知识广度上老师都弱爆了,但没有老师精通,如果学校的教育和ai结合起来就好了,我十分不喜欢现在类似的流水线的教育,就像现在大学的教育,教的落后时代太多,教育还没有从以前需要的“流水线”中转变为当今时代所需要的(当然我并清楚现在需要什么样子的)。现在的ai还没有那么发达,只能干掉一小部分工作,但它渗透的广度却令人震惊,就连小超市都充满它的身影,跟长在人身体里的毛细血管一样几乎处处存在,莫名有些担忧,若干年后ai足够强时,它要“反”,岂不是方方面面都难以防备。

2026-01-05 20:54:20 272

原创 go字符串算法查找其他字符串最先出现的位置

2]=b开始再匹配。kmp是计算出字符串每个位置的最长相等前后缀(已经匹配了的内容)将它存到数组中(该数组通常叫next,也有其他叫法),然后若遇到不匹配的地方就利用刚才的信息直接跳到已经匹配的最长的地方。我们拿"abaabf"来说,总长度是6,我们用大小为6的数组来存每个位置的最长相等前后缀(从开始到指定位置的子串的最长相等前后缀)。下标2处是” aba “,前缀有a、ab,后缀有a、ba,有相同的a,所以为1。剩余的不做计算了,我们可以得出它的最长相等前后缀数组next=[0,0,1,1,2,0]。

2026-01-03 16:01:40 585

原创 go字符串算法之右旋字符串

给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。我们可以发现,右旋后字符串分两个部分(拿上面的例子来说),fg和abcde。分开来就很容易发现右旋后的两部分fg和abcde其实就是反转后两部分gf和edcba的再反转而已。只要写过反转字符串(将字符串顺序都从后往前调换,比如abc,反转后就是cba)这道题就很容易想出来了。fmt.Println(string(rever(s, n, len(s)-1))) //反转剩余的并输出。

2025-12-25 15:41:31 283

原创 go字符串反转其中的单词

推荐使用快慢指针的方式,让快指针跳过头部空格或中间多余的空格,让慢指针从头获取快指针的值,这样可以获取到想要的无多余空格和首尾空格字符串。解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。输入: "a good example"输入: "the sky is blue"输出: "blue is sky the"输出: "example good a"//去除中间多余的空格。// 反转字符串a到b的内容。

2025-12-20 09:35:37 388

原创 go字符串之替换数字算法

对于go语言的处理方法比较简单,只要识别到数字就在数字位置的前方追加字符n,u,m,b,e,r即可,然后跳过数字,在把其后面的内容加上(非数字)就可以了。给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。对于输入字符串 "a5b",函数应该将其转换为 "anumberb"输入:一个字符串 s,s 仅包含小写字母和数字字符。

2025-12-14 11:37:57 367

原创 go链表算法之两两交换链表节点的理解

1再指向3,再让虚拟头节点指向3进行下一次(提前存一下指向下一对要交换的节点的第一个节点,在这里是3),之后更新一下虚拟头节点和要交换的节点的头的位置即可,交换直到结束。给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。head.Next.Next = head//2指向1。虚拟头节点:自己创建的一个节点,但不用它的值当做一个指针使用。以实例来说,先让虚拟头节点指向第一个节点1,然后让2指向1,ptr.Next = head.Next//指向2。head.Next = next//1指向3。

2025-12-06 16:23:42 7497

原创 Go算法之设计链表的理解

其次1中:仔细想一下和在二、三中处理类似,虚拟头节点可以帮我们插入到index个节点前,至于插到末尾只需使遍历index次可以得到下标为index-1的节点(从虚拟头节点开始遍历)此时的位置的一个节点就是要插入的位置(当index等于链表大小时刚好指向最后一个节点,其实就是在size+1个节点前插入新节点),而此时让新节点指向该索引节点的下一个节点,让当前节点指向新节点即可;如果从第一个节点开始遍历,链表为空时(大小为0),若index=0则是插入为头节点,而第一个节点为空无法遍历,所以会报错。

2025-11-29 11:38:18 912

原创 链表算法之反转链表笔记

3.让当前节点指针指向temp(第一个指向为空,其余指向上一个节点)1.先创建一个空的链表节点temp作为头节点的指向。2.从头节点开始遍历,先创建next接收下一个节点。//第一个指向空,其余指向上一个节点。输入: 1->2->3->4->5->NULL。输出: 5->4->3->2->1->NULL。4.再让temp指针指向当前节点。5.让当前节点指向下一个节点。//创建空指针做末尾。题意:反转一个单链表。

2025-11-19 20:25:04 149

原创 数组算法之土地权值划分最小差(仅限横竖划分)的理解

对于下面这道算法题,给出我的理解题目链接:44. 开发商购买土地(第五期模拟笔试)

2025-11-14 16:53:43 886

原创 2025.11.2考核感受以及图片拷贝

这个函数也很简单,picturename是图片路径,target是目标路径,只需要将两个路径传入就会提取到io.copy需要的reader和writer,然后copy会帮我们复制好图片放到对应路径。要说拷贝图片的实现其实我并没有写出来,主要是靠io.copy来实现的,也就是goland自带的,前面是对图片和要拷贝到的地方的一个小处理,让他们符合io.copy的要求。总体感受下来考核时意外的挺放松的,考核更像是一个对知识的回顾和补充,问问题既是看你有没有记住,也可以帮你补充不了解的方面或是小知识点。

2025-11-08 12:10:35 251

原创 关于一个简单的Go语言计算器

result = operatorPrecedence(slice) //将括号结果放入result。result = operatorPrecedence(slice) //将括号结果放入result。= -1 { //不为-1则说明含有括号。for i < len(str) {// str是输入的算数表达式或是括号内的表达式。//处理负数:开头是负数或中间是负数,中间是负数其前一个是操作符号。// 处理无括号计算式 符号优先级: * / > +- 括号单独处理。

2025-10-31 15:07:26 590

原创 Go文件操作——关于文件的打开和写入笔记

O_CREATE int = syscall.O_CREAT // 若不存在就创建。O_EXCL int = syscall.O_EXCL // 文件必须不存在。O_TRUNC int = syscall.O_TRUNC // 打开时清空文件。O_SYNC int = syscall.O_SYNC // 同步打开。O_RDONLY int = syscall.O_RDONLY // 只读。O_APPEND int = syscall.O_APPEND // 追加。

2025-10-26 16:37:12 142

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除