工具调用(Function Calling)怎么设计才好用
工具调用(Function Calling)怎么设计才好用Agent 能不能“动手”,取决于工具调用 很多团队发现:模型明明够聪明,却总是选错工具、传错参数 问题往往不在模型,而在 工具设计 这篇文章从背景出发,讲清楚工具调用的完整流程,总结六条实用的设计原则,给出 Python 与 Java 两套防御式代码,并列出常见坑和检查清单 一次 Function Calling 的完整往返:模型只提请求,程序负责执行 大模型只能输出文字 让它“查天气”“下订单”“读数据库”,中间必须有一层翻译:模型用结构化的方式说出“我想做什么”,你的程序把它变成真实的函数调用 这一层翻译的质量,取决于你给模型的“说明书”写得怎么样 可以做个类比:工具定义之于模型,就像 API 文档之于新入职的后端同事

2026-10-14鱼鱼
mysql前缀索引
mysql前缀索引有时候需要索引很长的字符列,这会让索引变得大且慢 通常可以索引开始的部分字符,这样可以大大节约索引空间,从而提高索引效率 但这样也会降低索引的选择性 前面已经说过,使用前缀索引,定义好长度,就可以做到既节省空间,又不用额外增加太多的查询成本 2.1因为前缀索引无法完全等于判断,只是前缀匹配,所以可能需要扫描的所以数会增加 2.2在特殊的查询里面 select id,email from SUser where email='zhangssxyz@xxx.com'; 前缀索引需要回到 id 索引再查一下,因为系统并不确定前缀索引的定义是否截断了完整信息 select count(distinct left(email,4))as L4,

2020-05-15yangwcn
让 AI 写 SQL 和迁移脚本:语法没错,坑全在数据里
让 AI 写 SQL 和迁移脚本:语法没错,坑全在数据里在我日常用 AI 写的各种代码里,SQL 大概是“看起来最省心”的一类 语法它几乎不会写错,连窗口函数、递归 CTE 都信手拈来 让它写个报表查询,或者写个加字段的迁移脚本,几秒钟就好,读一遍也挑不出毛病 但正是这种“挑不出毛病”,让我吃过好几次亏 SQL 的坑很少出在语法上,而是出在语义、数据量和线上环境上——这三样东西,恰恰是 AI 在对话框里看不到的 这篇就把我踩过、或者差点踩到的坑整理一下,最后再说说我现在的做法 先交代背景:我平时主要接触 MySQL,也维护过一些 PostgreSQL 的项目 下面说到具体行为时,我尽量注明是哪个数据库;不同版本之间行为可能有差异,以你用的版本的官方文档为准

2026-10-14鱼鱼
和 AI 结对写了一整天代码,我为什么比自己写还累
和 AI 结对写了一整天代码,我为什么比自己写还累有一天我做了个小实验:从早上到下班,整个需求全程开着 AI 助手,能问它的都问它,能让它写的都让它写 我原本的预期是“今天应该会很轻松” 结果下班的时候,我累得比平时还厉害 不是手累,是脑子那种被掏空的累 回头看产出,确实比平时多一点,但远没有到“轻松翻倍”的程度 那天晚上我想了挺久:问题到底出在哪? 后来我又观察了自己几周,慢慢摸清楚了一些规律 这篇不讲什么高深技巧,就讲讲这种“沟通疲劳”是怎么来的,以及我试过的、确实有点用的几个办法 我把那天的感受拆了一下,大概有五个来源 一是持续评审 自己写代码时,脑子里是“我要怎么写”;跟 AI 结对时,脑子里一直是“它写得对不对”

2026-10-14鱼鱼
算法:广度优先搜索(BFS)(最短路径)
算法:广度优先搜索(BFS)(最短路径)我们先看一个案例: 遍历一个树结构,按层次输出树的节点内容,即:欲求 A B C D E F 实现方式便是从根节点(A)向下遍历,先获取A,其次是A的子节点B和C,其次是B的子节点D…… 这种遍历树结构或者图结构的方法被称作广度优先搜索(BFS),与之对应的先遍历到最下层子节点的是深度优先 BFS核心采用队列的数据结构,例如上面的树结构中,解法为: A进队列->A出队列 B、C进队列->B出队列 D进队列 ->C出队列 E、F进队列-> D、E、F出队列 如果想要区分层次边缘,使用count参数即可 解法步骤(蓝色部分为已经处理完的节点):

2020-06-05鱼鱼
JVM源码解析 从Launcher类浅谈ClassLoader(类加载器及双亲委派)
JVM源码解析 从Launcher类浅谈ClassLoader(类加载器及双亲委派)首先普及ClassLoader的基础:所有的Java类都是由ClassLoader由class文件加载进内存的,对于一个类,其唯一标识就是类名+加载他的ClassLoader(亦即对于不同的 ClassLoader,即使是加载了同一个Class也不能互通,本质上是两个类),其基本的分类如下图: BootstrapClassLoader是一个特殊的ClassLoader,负责启动时加载jre的类库 并不继承于ClassLoader,因为是jvm逻辑的一部分; ExtClassLoader也会加载jre类库,但是会加载那些额外的扩展类库(jre\lib\ext目录),到这个级别的 类加载器已经可以直接在代码中使用了;

2020-11-28鱼鱼
盘点redis中特殊的数据类型 HyperLogLog Bitmap
盘点redis中特殊的数据类型 HyperLogLog Bitmap 基数计数(cardinality counting)通常用来统计一个集合中不重复的元素个数,例如统计某个网站的UV,或者用户搜索网站的关键词数量 数据分析、网络监控及数据库优化等领域都会涉及到基数计数的需求 要实现基数计数,最简单的做法是记录集合中所有不重复的元素集合S_uSu,当新来一个元素x_ixi,若S_uSu中不包含元素x_ixi,则将x_ixi加入S_uSu,否则不加入,计数值就是S_uSu的元素数量 这种做法存在两个问题: 当统计的数据量变大时,相应的存储内存也会线性增长 当集合S_uSu变大,判断其是否包含新加入元素x_ixi的成本变大 大数据量背景下,要实现基数计数,首先需要确定存储统计数据的方案,以及如何根据存储的数据计算基数值;另外还有一些场景下需要融合多个独立统计的基数值,例如对一个网站分别统计了三天的UV,现在需要知道这三天的UV总量是多少,怎么融合多个统计值
![盘点redis中特殊的数据类型 HyperLogLog Bitmap]()
2022-01-12鱼鱼
让 AI 帮我看别人的 PR,我怎么避免被它带偏
让 AI 帮我看别人的 PR,我怎么避免被它带偏code review 一直是我又爱又烦的环节 爱的是能提前拦住问题;烦的是有些 PR 又长又绕,下午三点看到,眼睛先花了 后来我开始让 AI 帮忙“先看一眼” 效率确实上来了:它能很快列出一堆疑点,有的还挺准 但用了一阵子,我也被它带偏过——有一次它言之凿凿说某段并发不安全,我跟着在评论区写了很长一段,作者委婉回复:那段代码根本不会并发进入 我再看,确实如此 尴尬归尴尬,也逼我把用法收紧了 这篇不是教你“用 AI 替代 review”,而是聊聊:怎么让它当助手,却不把结论权交出去 先说我自己的体感(不是评测数据,是使用感受) 相对擅长: 扫一眼有没有明显的空指针、资源没关、错误被吞

2026-10-14鱼鱼
扫盲——加密那些事
扫盲——加密那些事扫盲加密解密算法 日常开发中我们经常接触MD5算法,以此进行简单的文件完整性校验或者是后台密码验证,MD5是最常见也是最简单快捷的散列算法,常用于参数或文件完整性校验,譬如网络请求发起方与接收方分别对参数做MD5编码,一旦不一致便判断请求被篡改从而拒绝该请求,从而保证信息安全,编码后的字符串是编码前文本的一个简要梗概,因此它也被称作是信息摘要算法 这个算法的特点就是不可逆,只用于信息准确性和防篡改的校验,当然,MD5作为老牌的散列算法,很多经典的编码已经可以被反向解码出来(依靠正向的暴力穷举)以及被碰撞模仿(王小云院士团队的"破解"能够根据MD5编码后串码模拟原始消息,即使它可能与原信息不同),类似的还有SHA1,因此衍生了SHA224、SHA256、SHA512等更多安全的散列算法

2021-05-14鱼鱼
给 Agent 设超时和步数预算:别让它无限跑
给 Agent 设超时和步数预算:别让它无限跑第一次把 Agent 接到真实仓库时,我犯过一个很土的错:只盯着“它能不能做完”,没盯着“它最多能跑多久、最多能走几步” 结果某次工具调用卡在外部接口,它一边重试一边换策略,token 和墙钟时间一起烧,最后我手动杀掉,现场还一堆半成品文件 从那以后,我把超时和步数预算当成和权限同级的安全项 不是为了虐待 Agent,而是承认:自动化一旦没有硬上限,失败模式会从“报错”变成“悄悄耗尽” Agent 的轨迹很会制造希望:每一步都有日志,每一步都像在进步 可进步不等于收敛 常见假象包括: 同一类错误换着措辞重试 在几个文件间来回改,测试始终红 搜索范围越扩越大,上下文越来越脏

2026-10-14鱼鱼
MySQL tips
MySQL tips一些日常接触到的MySQL优化tips,比较散乱 假设有一个用户表,对于一句很简单的查询语句: 假设name与age字段均有单列索引,容易想到的是,MySQL应该会分别走两次索引,并将其结合起来,EXPLAIN也是如此,大多数时候MySQL会进行优化,我们可能会看到EXPLAIN的结果中有Using union或Using soft union,这是MySQL针对OR做了隐性的优化,但当SQL复杂或数据极端情况下,这一语句极容易变成全表扫描,偶尔使用联合索引可能解决问题,更多情况则是MySQL“昏了头”,即使OR条件均涉及数据条数不多,依旧没能在查询语句中使用索引,此时应调整为UNION语句(可以权衡一下重复及顺序是否有影响,可以使用更快的UNION ALL):

2021-01-13鱼鱼
动态路由数据源(多租户)解决方案
动态路由数据源(多租户)解决方案当下有很多服务都使用了多数据源,或是出于跨库查询或是分库分表、读写分离等,多数据源解决方案早已不是稀罕事 常见的解决方案包括使用多数据源框架(例如Shareding-Jdbc)、在数据库端做代理(例如MYCAT)、对于固定的几个数据源连接,也可以直接手动配置多个数据源,这种相关处理有很多源码,我在github上也有简单的实现:fishstormX/dynamicDataSource: 动态数据源的实现,基于maven自定义多模块骨架 Spring Boot2.0.x,本文实现的是动态数据源,主要为了解决 多租户问题(不同的用户群组有不同的数据源和配置,强调数据的隔离性) 本文技术能实现的是动态数据源,基于Spring框架,即能够将注入的Datasource根据租户不同使用不同的来源,同时根据租户增减动态的增删和缓存数据源(增是因为会有新增租户可能使用到项目启动后的数据源,减是因为租户数不可预料,不可直接缓存所有的数据源)

2021-01-07鱼鱼