别把LLM当万能:Skills才是AI应用的最小单元

发布时间:2026/10/20 15:30:04

别把LLM当万能:Skills才是AI应用的最小单元 2. 别把 LLM 当成一切重新理解 AI 应用的最小单元过去一年我见过太多团队栽在同一个坑里动不动就上复杂的 Agent 框架又是多智能体编排又是记忆系统结果项目卡在调试阶段动弹不得。原因其实很简单——大家把大语言模型的能力想象得太万能却忘了真正干活的时候它连解析一条自然语言指令然后调用一个准确的外部工具这种基础动作都常常出错。我个人的选择是把一切拉回最朴素的单元——Skills。你可以把它理解成给模型的预置剧本 配套工具包让模型在特定场景下不用从头思考而是按你的设计路径走。这个思路不是想出来的是反复在生产环境里被验证出来的。所谓 Skills本质上是一个定义好的、可复用的能力模块。它包含三样东西模型该怎么理解当前任务指令词和上下文策略、模型该调用什么工具定义、模型该遵循什么边界约束条件。它很像给一个新员工写岗位说明书——不指望他天生什么都会但你告诉他遇到什么情况、做哪几步、用什么系统、不能碰什么他就能稳定扛事。这个项目围绕AI 应用的最小合理单位应该是什么展开。核心结论是不要先造 Agent先造 Skills。Agent 是目标Skills 是原子。没有 Skills 支撑的 Agent本质上是让模型裸奔所有推理都在黑盒里随机游荡而有了 Skills你才能对 AI 行为做版本管理、灰度实验和定向优化。这一点想通了以后你的整套架构思路会立刻清晰每个功能场景拆成一个或多个 Skill每个 Skill 有独立的输入输出协议、触发条件、验证方式和兜底逻辑。调试时不用再面对整个 Agent 的一团迷雾而是面对一个一个小单元哪个 Skill 出问题就修哪个像修管道一样哪一节漏水拆哪一节。适合看这篇文章的人不是那种只玩过几次聊天机器人的朋友而是正打算或已经在把大模型集成进真实业务系统、想摆脱demo 很强、上线就废困局的开发者、技术负责人和产品负责人。我会从核心概念讲到文件结构再讲到技能模块怎么拆、怎么写、怎么防坑最后附一套我实测下来的排错清单。整个过程用的都是我在某模拟项目企业知识助手里反复打磨出来的经验可以直接对应到你自己的场景里。3. 设计与拆解先搭好技能这套骨架再谈其他3.1 为什么是 Skills而不是 Prompt 模板或 Plugin很多人问这不就是 Prompt 模板吗我一开始也觉得有点换汤不换药但把两者放在一起对比以后区别就清楚了。Prompt 模板是一段写给模型的文字静态、一次性、无结构化。Skills 则是一个完整的功能包除了模型指令还包括工具定义、参数约束、前置校验、后置处理甚至自我纠错逻辑。两者不在一个层级。也有人觉得这就是 Plugin。Plugin 更偏重外部工具的接入方式Skills 更偏重模型如何按场景有序使用这些工具。Plugin 回答的是我能调用什么Skills 回答的是在这个情形下我应该按什么顺序和策略调用什么。前者是能力的堆料后者是行为的编排。做过 Agent 的朋友应该深有体会——差的 Agent 不是不会调用工具而是不知道该在什么时候、以什么理由调用、调用完怎么判断结果可靠性。所以这套设计里我把 Skills 定义为 AI 应用的行动单元。每个 Skill 内部可能包含多个工具调用可能包含多轮推理但它对外暴露的是一个清晰的语义接口像函数签名一样。模型看到需求后不是自由发挥而是触发匹配的 Skill进入预设的行为路径。3.2 Skills 目录让每个能力模块变得可插拔这套体系落地的时候我用的目录结构非常简单但信息密度高skills/ ├── skill_registry.yaml # 技能注册表 ├── skill_loader.py # 加载、检索、校验的统一入口 ├── definition/ # 每个技能的独立定义文件 │ ├── knowledge_retrieval.yaml │ ├── document_summary.yaml │ ├── data_analysis.yaml │ └── report_generation.yaml ├── scripts/ # 技能对应的实际可执行脚本 │ ├── retrieve.py │ ├── summarize.py │ └── analyze_data.py ├── prompts/ # 技能内置的模型指令片段 │ ├── retrieval_handler.txt │ └── summary_writer.txt └── tests/ # 每个技能对应的测试用例 ├── test_knowledge_retrieval.py └── test_report_generation.pyskill_registry.yaml是核心索引一条记录长这样- name: knowledge_retrieval version: 1.3.0 description: 根据用户问题从知识库检索最相关的片段 trigger_keywords: [知识库, 检索, 查询, 哪里提到, 资料] model_temperature: 0.1 input_schema: query: type: string required: true max_length: 500 top_k: type: integer default: 5 min: 1 max: 20 output_schema: results: type: array items: content: string source: string score: float tools: - vector_search - keyword_search fallback_behavior: - 若向量检索结果置信度低于0.6合并关键词检索结果重新排序 - 若全部结果置信度低于0.3明确告知用户暂无相关知识 validation: - 输出内容必须包含引用来源 - 禁止编造知识库中不存在的内容注意这里我刻意不做成 JSON 而是 YAML。原因有两方面一是 YAML 可写注释这在多人协作和 Code Review 时价值巨大二是手写复杂嵌套 JSON 容易出错YAML 的缩进结构能逼着你把层次理清楚。当然加载的时候用正则或轻量解析都能处理不强求上重型库。3.3 设计原则三个不要拆好 Skills我建议记住三个不。第一个不不设计万能的 Skill。一个技能就干一件事宁可多拆几个细粒度的也不要把检索、摘要、分析全塞进一个技能里。技能越聚焦指令越清晰调试越容易触发准确率越高。我现在做企业知识助手时把查资料读文档做分析写报告分别拆成四个技能彼此独立但可以串联。每个技能的内部逻辑都短到一眼能看完。第二个不不把技能当成提示词库。如果只是把一堆 Prompt 放进 YAML那就失去了这套体系的意义。技能一定要包含工具调用、输入输出协议和验证逻辑。只写 Prompt 的话模型的行为没法被硬性约束而工具调用和验证逻辑才是让系统落到实处的那道闸门。实测下来加入工具定义以后模型瞎说但格式正确的概率提高了很多而加入验证逻辑以后业务上不可接受的幻觉风险也被压低了。第三个不不把上下文策略写死。模型的行为质量高度依赖上下文窗口里塞进去的东西。如果你给得太多模型抓不住重点给得太少模型开始脑补。我在设计每个技能时会特意通过 prompt 告诉模型你只需要关注 X 和 Y其他信息忽略。这个视野控制非常关键很多时候模型跑偏不是能力不够而是视野太宽。4. 核心环节实现从触发到兜底把每个技能做成一条完整的路4.1 技能加载与匹配不靠命中关键词全靠缘分整个系统的入口是skill_loader.py它做的第一件事是技能匹配。模型收到的任何用户请求先经过一个匹配层来判断应该激活哪个技能。我做匹配时用了一套分层策略第一层是意图语义匹配。把用户请求文本向量化然后与每个技能的trigger_keywords以及description做向量相似度计算取分数最高的作为候选。这一步解决的是用户没说关键词但意思接近的场景。比如用户问公司今年第一季度卖了多少虽然没提数据分析四个字但向量匹配能够把请求拉进data_analysis技能。第二层是上下文前缀触发。如果用户说接着刚才那个报告继续改单纯的向量匹配容易出错因为它缺乏上文信息。我的做法是在会话层维护一个最近活跃技能列表当匹配分数低于阈值时优先激活最近用过且语义边缘相关的技能。这个方法简单粗暴但实际效果很好并且避免了所有请求都靠大模型决定的不可控开销。第三层是硬规则覆盖。凡是输入里包含明确的命令式动词和对象比如调取生成图表输出表格直接压给指定技能不走向量计算。为什么这样设计因为这类请求语义足够明确靠模型判断反而会引入随机性。匹配完成之后对候选技能做参数校验。拿knowledge_retrieval举例query字段必须有值长度不能超过 500 字如果缺失就从用户的请求文本里自动提取。这样就不是模型想怎么调就怎么调而是模型必须在协议内调用。一旦协议被违反直接返回结构化错误而不是让模型自行发挥。4.2 Prompt 书写与工具调用把重话说在前面我在prompts/里给每个技能写好指令模板但这些模板不是散文而是规则条例。以retrieval_handler.txt为例其中最关键的几行是你是知识检索助手。你的唯一目标是帮助用户从企业内部知识库中找到相关且可靠的答案。 严格遵循以下规则 1. 如果用户明确询问具体事实或出处你必须基于检索结果回答禁止凭背景知识作答。 2. 如果检索结果少于1条或置信度低于0.3直接回复“知识库中暂未找到相关信息”禁止强行拼接内容。 3. 输出格式必须包含“结论”“参考来源”两个部分参考来源必须来自本次检索返回的真实文档标识。 4. 当用户的问题与你的技能范围无关时回复“该问题超出了我的处理范围”不要尝试回答。为什么这么写因为模型在自由对话里很擅长讨好用户它会倾向于硬答哪怕手里没材料。这段 Prompt 的作用不是给它更多知识而是给它划牢笼、定边界。规则写得越具体模型越不敢乱来。工具调用方面我用的是一个极简的 JSON-RPC 模式。retrieve.py接收结构化参数调用向量库查询返回一个标准结果对象。所有工具都注册到一个统一的调用表里TOOL_REGISTRY { vector_search: vector_search, keyword_search: keyword_search, get_document_by_id: get_document_by_id, summarize_text: summarize_text, }这看起来像多此一举但实际价值在于所有工具调用都变成了可观测的函数调用日志里能完整看到模型决定调用哪个工具、传了什么参数、拿到什么结果。如果没有这一层模型直接拼一个 JSON 去调 API出错了你根本不知道是模型幻觉还是参数格式问题。4.3 输出约束与结果校验防的是一本正经地胡说八道技能的最后一步是校验和清洗。我不会直接把模型的裸输出转给用户而是先过一层校验器。校验器检查的维度包括输出是否包含所有必填字段来源引用是否真实存在于检索结果集中内容中是否包含明显的实体前后矛盾以及事实性断言是否都能在参考源中找到支撑。这步不能省特别是对生产环境的输出模型生成的内容再流畅没有校验就等于没锁门。一个让我印象深刻的例子某次测试中模型在报告生成技能里给出了一份非常漂亮的季度分析数据一眼看过去完全合理。但校验器发现它引用的两个数据点根本不在这季度任何一张表里是模型自己推算并脑补出来的。如果直接放出去业务方一定会拿着假数据做决策。校验器从那以后成了我的标配。校验通过的输出会被打上已核验标记写入结构化结果校验不通过则触发兜底逻辑要么让模型重新生成并附上哪些字段不合格的提示要么直接返回错误信息给用户。这里要特别注意兜底最多尝试两次第三次必须硬性终止否则模型会在循环里自我纠偏消耗大量 token 后仍然给你一个看似更合理的幻觉答案。4.4 灰度与回溯没有版本管理的技能体系撑不过三个月刚开始我也没有版本管理的意识直到某次我改了一个 Prompt 里的措辞结果知识检索的准确率一夜之间掉了 7 个百分点。从那以后每个技能文件里我都写死version字段并且所有的技能都走 git 管理。每次调整无论是 Prompt、工具定义还是参数约束都作为一个独立 commit 存在并且配套跑一遍该技能的测试集。测试集里的用例不是随便写的每一条都是在历史真实用户请求里挑出来的易错样本。灰度发布的方式更简单——同一个 Skill 可以存在两个版本knowledge_retrieval和knowledge_retrieval_v1.4.0线上流量按比例切分对比核心指标之后再决定全量还是回滚。这套路在工程上非常成熟但放在 AI 应用里很多团队反而忘了做。大家总有一种模型行为无法预测所以没法灰度的错觉其实只要你把技能定义当成普通代码看待它就能享受所有软件工程应有的待遇。5. 常见问题与排错实录我踩过的坑你别再踩5.1 问题类型速查表我把过去半年在模拟项目里遇到的典型故障整理成了一张速查表每遇到一个现象先查表定位比自己瞎猜快得多。现象可能原因排查路径技能从未被触发语义匹配分数阈值过高降低向量匹配阈值检查 trigger_keywords 是否覆盖常见问法技能被错误触发trigger_keywords 太宽泛增加负向关键词列表细化 description 限定范围模型输出格式混乱Prompt 约束不足或字段描述不清在 Prompt 中给一个输入输出示例明确字段层级引用来源不存在模型编造来源跳过校验器在输出校验中强制比对来源 ID 与检索结果集工具调用参数缺失模型不知道参数从哪取在工具定义里写明参数来源字段把用户原始请求片段作为参数候选回答极其冗长上下文塞入太多无关内容收紧视野控制提示只保留与当前技能直接相关的系统信息检索结果全是低质片段向量检索只按相关度未按质量分排序引入质量分加权或业务规则过滤改了技能配置无效果缓存未更新或注册表未重载检查加载逻辑是否用了强缓存必要时手动清理这里重点说一个最隐蔽的坑缓存。如果你的加载器用 functools 的 lru_cache 或全局单例缓存了技能定义那么你改了 YAML 文件线上可能还跑着旧配置而且没有任何报错。这属于静默失败比直接报错难找得多。我在加载器里特意加了一个--reload参数开发模式下每次请求都重新读文件生产模式下才开启缓存并带版本号。5.2 案例复盘一次检索失灵的完整排障流程有一次线上反馈说企业知识助手查不到某某制度文件但明确知识库里确实有这个文档。我一开始以为是向量索引没更新查了索引状态发现一切正常。然后把用户原话提出来做复现发现直接走向量检索能查到相关度高达 0.82 的文档说明检索链路本身没问题。问题就出在技能匹配层。用户的问法是咱们现在请假的规则按哪个版本走里面既没有触发词检索也没有知识库于是语义匹配分数卡在了阈值以下模型被降级成了通用对话模式自然就只能瞎答。定位后我做了三处修复第一把skill_registry.yaml里的trigger_keywords扩充了业务常见问法例如规则制度规定流程怎么操作等但注意不是无脑堆词而是结合测试集里的真实问法反向提炼。第二给knowledge_retrieval的 description 改成了更明确的功能描述负责查找公司内部的制度、流程、规定、SOP、模板文件等当用户询问任何内部资料时优先考虑本技能。第三把语义匹配阈值从 0.72 下调到 0.65同时增加一个负向关键词表避免误触发。这个案例最值得记录的教训是很多时候系统表现差不是模型变笨了而是技能设计和配置没有覆盖用户真实自然的表达方式。测试集必须来自真实请求而不是自己拍脑袋编的用例。5.3 防坑清单九条实操心得关于 Skills 的落地我沉淀了几条实际用起来特别管用的心得按优先级排列先给技能起一个动词短语的名字比如generate_report不要用report这种名词。动词命名让匹配语义更明确也不容易和别的模块混淆。每个技能必须显式声明它能做什么、不能做什么不能做什么比能做什么更重要。模型对禁止的理解力比对可以强得多。Prompt 里放至少一组输入输出示例。模型对抄格式的可靠性远高于理解抽象规则。工具结果先缓存同一请求重复调用时直接走缓存。LLM 的调用链里最贵的往往不是 token而是外部接口的延迟。永远给模型提供无法处理时的出口。模型一旦没有退路就会开始编答案。这句话值得刻在墙上。校验逻辑必须在技能内部完成不是在应用层统一做。每个技能的验证点不同统一校验器既笨重又容易错杀。技能文件不要用中文命名。文件名只允许字母、数字、下划线避免各种编码和跨平台问题。更新技能时先小流量灰度观察至少一天的日志再全量而不是上线后靠用户反馈发现问题。保留一份技能变更日志文档哪怕就几行字记录每次改动机的理由。三个月后再看你会感谢自己。6. 再进一步从 Skills 到 Agent从原子到生态这套体系做到后面你会自然发现一个现象——技能之间开始需要协作。比如用户问总结一下上季度的销售问题并且给出改进建议这就同时涉及knowledge_retrieval、data_analysis和report_generation三个技能。如果每个技能只独立工作流程就断了。我处理这个问题的方式是增加一个编排层但编排层不管理具体行为只负责技能间的调用顺序和数据流转。你可以把它想成一条流水线检索技能先把原始材料取出来分析技能对材料做统计和判断报告技能把结论组织成最终输出。每个环节仍然是独立的技能各自有校验逻辑各自可被替换。这种设计比让一个大模型 Agent 自己决定一切要可靠得多因为你随时能定位是哪个环节出了问题。从更长远的角度看Skills 也带来了一个工程上极大的好处可售卖、可复用、可测试。当你的技能库积累到一定规模新的业务场景往往不需要新写代码而是在已有技能里做排列组合。我这个企业知识助手项目只是整个思路的一个切面但它验证了一个判断——AI 应用不再是一大段魔法般的推理过程而是一个可组合、可管理的工程体系。这个体系的基础就是我前面反复强调的 Skills。这套东西运行了一段时间以后我最大的感受是它把 AI 应用从玄学拉回了工程。你不再需要靠调 Prompt 碰运气而是可以通过观察技能触发率、校验失败率、兜底触发次数这些硬指标来掌握系统的健康度。我个人的建议是如果你正打算把一个新 AI 功能接入业务系统别再急着构建复杂的 Agent 流程。先在项目里搭一个轻量技能目录把场景拆成技能逐个实现、逐个验证。等你攒了五六个可靠的技能再考虑让它们协作。到那时候你会意识到AI 应用真正难的部分不是模型有多聪明而是你能不能把它的能力做成一个又一个清晰、可控、可验证的单元。
延伸阅读

更多相关文章

2026/10/20 15:30:03

2026年AI检测算法升级,降AI工具如何从词句替换走向语义级重建?

这两年在写作圈和学术圈里,降AI工具一直处于相当微妙的位置。一边是各种平台对AIGC痕迹的识别越来越紧,另一边是不少写作者确实需要借助工具来润色、梳理逻辑、降低机器感。2026年的算法升级消息放出来之后,我身边好几个做论文辅导、期刊投稿…

2026/10/20 15:25:03

从零搭建PPT自动生成工具:Python实战与架构设计

1. 从零搭建一个"PPT大师":为什么我要自己造这个轮子做技术分享、写项目复盘、给团队做培训,绕不开的一件事就是做PPT。我粗略算过,过去一年我至少做了四十多份演示文稿,平均每份从构思到定稿要花掉三到五个小时。最要命…

2026/10/20 16:30:36

DSP28335 XINTF外扩SRAM完整指南:从时序配置到CMD段分配

做DSP开发的人,迟早会撞上内存不够用的墙。28335虽然带浮点单元,可内部那块SARAM总共也就三十几K字,跑个FFT、存一组采集数据、塞个查找表,说满就满。这时候最顺手的解法就是走XINTF外扩SRAM。这个实验在普中DSP28335开发攻略里被…

2026/10/20 16:30:36

REA模型实战:告别状态字段地狱,用事件溯源重构订单系统

上个月做了一次代码走查,对象是一个跑了两年的订单履约系统。最让我坐不住的不是某个算法写得有多绕,而是orders表里那十几个状态字段:PENDING、PAID、SHIPPED、DELIVERED、CANCELED、REFUNDING、REFUNDED……每排查一个线上问题,…

2026/10/20 16:30:36

Spring Boot配置文件敏感信息加密:Jasypt集成与密钥管理

1. 为什么要给SpringBoot配置文件里的敏感信息加密先说一个我亲身经历的场景。某客户的测试环境数据库密码泄露了,排查了一圈,发现是开发同学为了方便,把生产库地址和密码直接写在了项目里,提交代码的时候连同仓库一起推到了内网G…

2026/10/20 16:30:36

高德地图JS API本地调试:安全密钥与白名单配置实战

前阵子帮一个朋友调他手里的地图项目,页面在浏览器里打开,地址一输入,点击查询,控制台直接甩出一排红字。我一看报错码,心里基本就有数了——典型的本地调geocoder.getLocation没配安全密钥。这个问题在社区里问的人特…

2026/10/20 16:25:35

双栈模拟队列:用堆栈实现FIFO行为的原理与工程实践

1. 项目概述:为什么用堆栈去“假装”队列?这题不是考代码,是考思维切换 “7-22 堆栈模拟队列 (25 分)(详解夹思路)”——这个标题一出来,很多刚学数据结构的同学第一反应是懵的:堆栈(Stack)是后…

2026/10/19 18:06:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/20 1:05:37

单片机C运行时从启动到多任务:中断安全与共享资源冲突

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:05:37

GCC编译四步详解:预处理、编译、汇编、链接实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:05:37

FIW线是什么?FEP注塑线与普通氟塑料线的区别及应用指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑