简栈

拥抱AI,持续成长

最近媒体在密集传播一个观点:Skills 正在替代 MCP。

你信吗?

我第一反应是——这话听起来有道理,但哪里不对劲。

就像有人说”操作手册要替代机器”。手册写得再详细,机器不在,活儿还是干不了。

Skills 到底是什么?

说白了,Skills 是一段结构化的提示词

它告诉模型:遇到这类任务,你应该怎么思考、按什么步骤来、注意哪些边界。比你随手写一句”帮我分析这个问题”要强得多——它更像一本操作手册,有流程、有角色、有约束。

但本质上,它还是提示词。

它的能力来源,是模型自身。

这一点很关键,也是后面所有判断的基础。

阅读全文 »

一句话概括:MCP(Model Context Protocol)是给 Agent 接上”手”和”眼”的标准插头。它定义了一套严格的握手协议,让 Agent 知道”有什么工具可用、怎么调用”——从建立连接到最终执行工具,每一步都有明确的分工。LLM 在其中只负责推理和决策,真正调用 MCP 的是 Host(宿主应用)。


背景:为什么需要 MCP?

LLM 本质上只会”说话”,它没有办法自己去查数据库、调接口、读文件。要让 LLM 具备这些能力,必须给它一个标准化的方式来”发现工具”并”使用工具”。

以前每家公司都自己搞一套,乱得很。Anthropic 提出了 MCP,相当于制定了一个通用的 USB 接口标准——不管是什么工具(数据库插件、网页抓取、代码执行器),只要实现了 MCP 协议,LLM 就能用统一的方式调用。


整体架构:三个角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌─────────────────────────────────┐
│ Host(宿主应用) │
│ │
│ ┌───────────┐ ┌─────────────┐ │
│ │ LLM │ │ MCP Client │ │
│ │ (推理决策) │ │ (协议通信) │ │
│ └───────────┘ └──────┬──────┘ │
└─────────────────────────┼───────┘
│ JSON-RPC

┌───────────────────┐
│ MCP Server │
│ (工具提供方) │
└───────────────────┘
  • Host(宿主):运行整个 Agent 的应用,比如 Claude Desktop、Cursor、你自己写的 Agent 程序。它同时持有 LLM 调用能力和 MCP Client。
  • LLM:只负责推理和决策,输出 tool_use JSON 表达意图,从不直接调用任何工具
  • MCP Client:嵌在 Host 内部,负责实现 MCP 协议、与 MCP Server 通信。Host 解析 LLM 的 tool_use 输出后,由 MCP Client 代为执行。
  • MCP Server:一个独立进程(或远程服务),向外暴露”工具 / 资源 / 提示词”。

通信方式有两种:

阅读全文 »

背景

Proxyman抓包来分析一下CODEBUDDYCLAUDE CODELLM之间的交互,如果是用Terminal的方式发现无法抓到,发现需要在环境变量里开启才行,所以就了解了下多种开启代理的区别。

两种方式的区别

有本质区别,作用范围完全不同:

  1. networksetup — 系统级代理
    修改的是 macOS 系统网络设置(等同于在「系统设置 → 网络 → 代理」里手动勾选)
    立即生效,无需重启终端
    影响范围:所有 GUI 应用(SafariChromePostman 等)以及大多数遵循系统代理的程序
    不影响终端里的命令行工具(curl、npm、pip、node 等默认不读系统代理)

  2. ~/.zshrc 环境变量 — Shell 级代理
    修改的是 Shell 进程的环境变量
    需要重新 source ~/.zshrc 或开新终端才生效
    影响范围:仅终端内的命令行工具(curlnpmpipgitnode 等)
    不影响 GUI 应用

对比总结

对比项 networksetup 系统代理 ~/.zshrc 环境变量
作用对象 GUI 应用 命令行工具
生效方式 立即生效 需 source 或新开终端
Proxyman 抓包 ✅ 能抓 GUI 流量 ✅ 能抓终端流量
curl / npm ❌ 通常不走 ✅ 走代理
Chrome / Safari ✅ 走代理 ❌ 不走

结论

如果你用 Proxyman 抓 终端命令行工具(如 curlnpminstallnode 发的请求)的包,必须设置 ~/.zshrc 环境变量,networksetup 对这些工具无效。
两者可以同时开启,互不冲突,Proxyman 本身也建议两者都配置。

你有没有遇到过这种情况——

同一个 AI 助手,在 A 项目里像个老手:熟悉技术栈、遵守规范、说话有分寸。换到 B 项目,却像个刚入职的新人,什么都不知道,什么都要从头解释。

为什么?

因为 LLM 本身没有记忆。

每次对话,它都从零开始。它不知道你的项目用什么语言,不知道你的团队有什么规范,不知道你上次说了什么。它只是一个极其强大的”推理引擎”——给它什么上下文,它就基于什么上下文思考。

这就是问题所在,也是 AGENT.md 存在的原因。


LLM 是大脑,但大脑需要被”装配”

想象你雇了一个能力极强的顾问。

但每次见面,他都完全不记得你是谁、你的公司做什么、你们上次谈了什么。你每次都要从头介绍,每次都要重新建立信任,每次都要重新解释规则。

阅读全文 »

背景

前段时间做了很多慢SQL的优化工作,这周刚好又被反馈服务出现了死锁导致了业务报错。看了一下云数据库的告警日志,发现出现了比较多的事务未提交死锁等待行锁的严重警告。都是一些棘手的运维工作,涉及到业务流程的梳理、SQL的优化等工作。

今天趁这个机会,我们一起看下如何去分析这些问题,主要看下等待行锁、死锁。

数据库有哪几种锁?

每次说数据库锁,感觉一大堆。其实如果按照一定的纬度去整理下,还是比较清晰的。如图:

力度划分:表锁、页锁、行锁

算法划分:Record LockGap LockNext-key Lock

实现机制:乐观锁、悲观锁

兼容性:排它锁、共享锁、意向锁

阅读全文 »

背景

我们来先看一个图,了解一下故()事()的背景:

http://static.cyblogs.com/Jietu20211113-162059.jpg

2个跑批任务,其实做的事情是同一件事情,都是为了跟下游系统保持数据的一致性。大任务是每个2h跑一次,小任务是每隔10mins跑一次。除了这2个定时任务以外,还有一个额外的监控任务来做类似的对账,如果发现出现对账不平,就会出现邮件/短信告警到相关的责任上。

这是一个非常有特点的定时任务跑批任务+监控告警的场景了。

从上面的场景上看,我们可以得出一些结论:为了保证一致性写了大小Job来保证,并且还给出了监控告警,说明数据的重要性是比较强的。

某天,出现了频繁的告警提示,每10分钟就告警一次,而且内容没有发生变化,说明同步的index没有变化过。

错误排查

任务有在正常的执行吗?

第一反应肯定是在思考,我的大任务与小任务都有正常执行吗?因为之前的都是正常的。上午看了一下日志与进程发现有在跑,还跑除了多次任务,日志打印不明确,看不到具体分支的逻辑。总结一下问题点:

阅读全文 »

前言

现在对于一个开发来说,Docker应该是再熟悉不过了。 还记得在2013~2014左右的时候,听说多最多的就是Cloud Foundry,那个时候就一直在说云的事情。后面Docker就绝杀了它~

那它帮我们解决了一个什么问题了?面试的时候也许会问到。

在很久以前,我们开发代码,估计最蛋疼的事情就是发布版本了。我还记得在房多多的时候(2014~2016)左右,每次发布几个开发围绕在运维的身边,有时候运维忙不过来,开发就直接在运维的电脑上开始VIM干活了,修改若干配置。由于多环境的原因,我们无法保证每个环境都是一样的。

  • 可能你的操作系统不同,导致打包、发布的脚本不同
  • 环境不同,没有很好的配置管理,你的代码有不同的写法
  • 特别是跟操作系统相关的那些参数,可能瞬间就会带来性能问题

那么Docker就可以把我们的操作系统、代码、脚本等都一起打包成一个Image,就可以保证只要是运行同一个Image,我们的所有内容都是一样的。就不会出现,我在测试环境跑的好好的,一到生产连启动都成问题。

问题

现在一般一个POD就只跑一个进程,DevOps会根据我们的发布流水线自动的将一个项目进行打包、发布,整套的CI、CD做的是行云流水。但是,每个项目ROOT下都会需要一个叫Dockerfile的文件。但偏偏有一些历史项目,没有Dockerfile文件,只有一个Run的容器再跑,真的是非常惊悚。docker rm [OPTIONS] CONTAINER [CONTAINER...],就GAME OVER了。

怎么办?

方法1:以当前容器作为基础镜像
阅读全文 »

背景

之前在思考双活/多活架构的时候,其实对于蓝绿发布是有一些了解的,也梳理过在底层存储是一份,服务是多份的模式有做过深入的分析。但那个时候对于Kubernetes的了解还不是很熟悉,是通过传统的方式来考量的。

因为现在的互联网公司基本都是上云了,我们也必须对于Kubernetes那一整套要有比较深入、熟悉的运用才能真的提高我们的效率。先聊一下,我为什么需要利用灰度+蓝绿发布的模式来去做?

现在有一个比较老的项目,应该在10年+,每天请求量大概在1.5亿+,峰值的QPS在6000/s,存在着比较多性能问题。现在需要在它上面新增一个服务,为了后面优化做准备,比如:请求的分流、限流、熔断、日志的上报与监控(新)、统一编译处理,特殊报文转换等。也就是说,只要你新增加了一层,你才有可能更好的去做更多的事情。

那么我们需要达到一些什么的基础条件了?

  • 服务流量比较大,我们需要对新服务的可靠性需要验证,需要灰度先了解
  • 因为存在慢查询,不能在滚动发布中,导致请求还未执行完毕,就被k8s kill掉了,业务会感知到502

如果是你?针对于这2个基础的要求,你会如何去思考的你架构方案呢?

思考

新增服务的思考:

  • 它的性能必须要强、服务稳定。一个服务的性能好不好,其实跟它的:I/O模型、线程模型、数据结构、算法等息息相关。比如:你在思考Redis单线程为什么快的时候?应该就很能get到这里的点了。解决这个问题,我们选择了Go语言来开发(当然,最熟悉的语言风险最小),为了保证性能,也是做了2轮非常细致的压测。
  • 发布过程中不能因为kill掉服务导致请求502。如果说我在发布的过程中,我把滚动这一步省略掉,直接先准备好一份最新的,验证可以后,我一刀直接把流量引导最新服务上,老的服务也不会断掉,这是否就可以达到效果了?
阅读全文 »

我们在新做项目的时候,需要对我们的服务有有一些性能指标,比如:SLA(需要达到多少个9)、QPSTPS等。因为这些量化的数字让我们更加的了解我们的系统。

我们如何压测?其实个人觉得有2种场景。

第一种:是我们明确的知道目标,看我们通过大量的并发看我们是否有达到。如果没有达到,我们需要通过水平扩容、性能优化等让其达到。

第二种:是我们不知道目标,通过压测可以知道一个固定配置下的单机单服务的最大性能,让我们对它有一个彻底的认识。为后面的目标做更多的铺垫与准备,或者跟行业水平对比,看看差距有多少。

如何用wrk进行压测?

Github地址:https://github.com/wg/wrk,该项目也是开源项目,关注的人还不少,有30.4K。咨询了一下身边的同事,使用它的人还不少。主要的语言的是C语言。

http://static.cyblogs.com/Jietu20211023-153923.jpg

安装
1
2
3
4
5
6
git clone https://github.com/wg/wrk

make

-- 拷贝wrk到bin
cp wrk /usr/sbin/wrk
压测脚本
阅读全文 »

背景

项目中开始用Go,最近写了一下Demo,发现语法还是非常好用,大部分比Java还是简洁很多,也有一些很细节的约定。比如:

  • 字母大小写控制是全包还是本包内访问
  • 变量定义了就一定要使用,否则就会编译不通过等等

更好的就是方法可以返回多个值,这个跟Java比较就是减少很多的封装。因为Go的线程模型特点,用来写一些需要高并发、高性能的项目还是非常好的。所以,趁这个机会也好好的深入了解下。现在也是把PythonPHPGo等都学习一遍,每种语言都有它的优缺点,其实都还挺不错的。

针对于Go语言里:&*的区别,什么时候该用什么做一个总结。

指针

我们经常会听到别人说Go是值传递,某某某是引用传递,某某某是指针传递,等等各种各样的说法。

那么首先他们的区别是什么呢?什么是指针?指针其实也是一个变量,只不过这个变量里面存的不是intfloatstruct,而是一个地址address,然后在这个address上所存储的数据可以通过指针来被阅读到。

OK,指针变量存储的是一个地址,地址从哪里来的?那就得问一个变量的地址怎么取得呢?在变量前面加上一个&符号就行。

好的,指针变量存储了这个地址了,那这个地址所存储的值怎么被阅读到呢?也就是指针所指向的值怎么拿到呢?在指针变量前面加上一个*符号就行。

阅读全文 »
0%