用Agent Skills打破数据孤岛:跨系统智能查询的轻量方案 上周五我处理一个客户投诉前后开合了四个后台先翻CRM看客户合约周期再去工单系统查最近三个月有没有服务记录然后回知识库翻产品说明最后还要找运维要一份日志摘要。整个过程四十分钟大部分时间都耗在点菜单和复制粘贴上。数据其实一直都在CRM有客户全景工单里有交互轨迹知识库里有标准答案可它们谁也看不见谁——这就是最典型的数据孤岛。最近我换了个思路不再费劲去搭数据中台而是花了一天时间整理出一套Skills交给Agent按需调用让它在一次对话里替我完成跨系统查证。这篇文章就是这套方案的完整复盘包含设计思路、核心文件写法、实测效果和踩坑记录适合正在被多系统来回切换折磨的运维、业务开发以及想给团队引入Agent工作流的朋友参考。1. 数据孤岛的真问题不是没有数据而是数据不具备“即问即答”的能力1.1 客户的完整画像被拆散在四个系统里那个客户案例特别能说明问题。客户打电话进来的时候客服只能看到CRM里一句合约还有45天到期但看不到这45天里客户已经提了三次工单也看不到知识库里对应产品线最近刚出过版本变更公告。要搞清楚这个客户续约时该怎么谈人肉操作是没法绕开的先记住CRm里的合约号切到工单系统搜一遍把投诉记录复制到文档里再去知识库查产品公告最后还得猜一下日志里显示的服务中断跟客户反馈是不是同一件事。这个场景里的数据孤岛不是没有数据而是数据被各自的系统锁死了。每个系统都在自己的界面里回答自己的问题但你问一个跨系统的问题没有任何一个界面能给出完整答案。我把这种状态总结成一句话数据能存、能查但不会答。存储做到了单点查询也做到了唯独组合式问答这个能力完全缺失。更麻烦的是这种缺失不是靠多打开几个系统就能补上的。客户问得快运营翻得慢中间的信息损耗比数据损耗还大。我在复盘这个案例时意识到很多公司其实不缺数据中台规划也不缺BI报表最缺的是一个能让人用自然语言直接把问题抛给所有数据源、并且当场拿到组装后答案的入口。Skills这个机制恰好能在这一层派上用场。1.2 传统的打通孤岛方案为什么总让人感觉使不上劲过去我们聊数据孤岛第一反应都是上数据仓库、做ETL、搞API聚合层、建BI报表。这些方案我没少用过结论是都能解决一部分问题但都有让人难受的代价。传统方案解决的问题主要代价数据仓库/ETL把数据集中存放支持跨域分析建设周期长跨部门协调成本高口径统一难API聚合层给前端和移动端提供统一接口要重新建模、立项、排期临时问题等不起BI报表固定维度可视化分析只能看预设维度新问题要提需求单人工查询灵活、零成本效率低人肉容易出错ETL的问题是重。拿我们这个小团队来说真要打通CRM和工单系统得约数据负责人、谈字段映射、定同步频率、处理脏数据光初始方案就能磨两周。API聚合层听着轻巧但每个新场景都要改代码重新发布本质上还是把业务问题翻译成开发任务。BI报表则是给决策者看趋势用的你让它回答这个客户能不能续约它就哑火了。问题的根源在于这些方案都在做数据层面的搬迁而我们真正需要的其实是问答层面的连接。业务同事不在乎数据放在哪只在乎当我问出那个跨系统的问题时能不能立刻得到答案。这个目标用重型数据平台去做就像为了喝杯热水专门盖个锅炉房方向对但用力过猛。1.3 换个思路把查询口变成能力包而不是把数据搬到一起我第一次接触Agent Skills时脑子里立刻浮现的就是那个客户投诉场景。Skills这套机制的核心理念和传统打通孤岛的方式正好相反它不搬数据它给每个数据源装一个会说话的窗口。CRM的数据继续留在CRM工单的数据继续留在工单区别是每个系统边上多了一个按标准格式描述好的技能包——告诉Agent这个系统里有什么、怎么查、什么时候该用它、返回什么格式。这样一来跨系统问答变成了Agent的编排活。用户说查一下这个客户最近的投诉和合约到期时间Agent看到问题里有投诉和合约两个概念就会分别调用工单查询技能和CRM查询技能拿回数据后在上下文里完成关联最后给出人话答案。数据还是散落在各处的但提问—取数—组装—回答这条链路被打通了。这个思路尤其适合中小团队。我们没有专职数据平台团队但有业务系统API、有少量脚本能力、有一堆想少点几个系统的业务同事。Skills刚好落在够用且灵活的位置不用动基础设施只要把取数逻辑封装成技能包就能在Agent里获得一个跨系统的虚拟入口。2. Skills机制拆解为什么它天生适合做跨系统连接器2.1 一个Skill到底长什么样元描述、脚本与数据的三层结构Skills并不是什么玄乎的新技术拆开看就是一个标准的目录结构加一套可执行脚本。我们团队约定的每个Skill长这样skills/ ├── crm-query/ │ ├── SKILL.md # 技能说明书名字、描述、触发场景、参数说明 │ ├── scripts/ │ │ └── query.py # 真正干活的脚本调CRM接口、过滤字段、返回结果 │ └── assets/ │ └── config.json # 辅助参考配置比如字段白名单 ├── ticket-lookup/ │ ├── SKILL.md │ ├── scripts/ │ │ └── search.py │ └── assets/ └── kb-search/ ├── SKILL.md ├── scripts/ │ └── retrieve.py └── assets/这三层各有分工。SKILL.md是给Agent看的里面用自然语言写清楚这个技能在什么情况下被启用、怎么传参数、返回什么格式。scripts里是给机器执行的承担真正的HTTP请求、鉴权、字段裁剪和错误处理。assets则放一些辅助数据比如映射表、关键词列表、配置项。我一开始对这个结构不以为然觉得不就是传统接口套了个壳。用久了才体会到SKILL.md这层描述文本的重要性因为Agent不像代码那样靠函数签名判断调用它靠的是语义理解。技能能不能被正确触发、会不会被误触发全靠SKILL.md写得好不好。从这个角度看SKILL.md就是技能包的招聘启事写得不清楚Agent要么不找你要么乱找你。2.2 和插件、API、Prompt模板相比Skill多出来的东西很多人问我Skills跟以前的插件系统、API封装、Prompt模板有什么本质区别。我梳理过一张对照表机制本质Agent参与度典型问题插件给应用扩展功能低用户手动点和Agent原生能力割裂API被动等待调用无由业务代码发起要开发排期临时场景成本高Prompt模板纯文本指令高但无执行能力只能动嘴不能动手Skill描述代码数据三合一高Agent按需选描述写得差会误触发插件是我给某个应用装了个功能和Agent掌握全局上下文这件事是两套逻辑。API是我在代码里显式调用不会因为用户一句话就被临时选上。Prompt模板能引导Agent的思路但没有执行能力说完话还是得有人去点系统。Skill是把这几种东西凑齐了有自然语言描述让Agent理解用途有可执行代码让它真正去拿数据有assets让它理解业务上下文。它更像一个带简历的工人Agent读到简历觉得合适直接派他去干活。国外有些文章从First Principles角度讨论Agent Skills我读下来收获很大但落到实战层面观察起来其实很朴素这个机制解决了Agent知道该问谁和能真正问到数据之间的空隙。没有Skills时Agent再聪明也只能在用户给定的一段上下文里推理有了SkillsAgent可以主动去系统里取数再基于新数据继续推理。2.3 用运行时聚合替代ETL里的多表Join我最喜欢Skills的一点是它用运行时聚合替代了传统ETL的预聚合。过去我们要回答最近30天有投诉且下月合约到期的客户有哪些得把CRM的合约表和工单系统的事件表都导到数仓做一次Join再输出结果。这个链路周期长而且一旦口径变了整套ETL都要调整。Skills方案完全换了个姿势。Agent收到问题后先去CRM技能那里拿下月合约到期客户列表再去工单技能那里查这些客户的投诉记录然后在自己的上下文窗口里做交集。这个过程很像人在手动操作只是把人换成了Agent技能包。优点是数据不动、口径可控、按需组合缺点是别指望它对几百万行全量数据做分析——它不是为大数据设计的而是为业务问答设计的。我特别想强调一句Skills不会消灭数据仓库它消灭的是等数据仓库给答案这件事的焦虑感。前者继续负责全量分析、指标统一和深度建模后者负责日常业务问答里那些零碎的跨系统查询。两者不打架反而互补。2.4 生态热度背后是一个趋势给Agent配好工具箱最近社区里关于Skills的内容一下子多了起来前端开发skills、AI编程助手的技能包、文档处理、数据分析、逆向分析等场景都有现成技能包也有一些专门的技能市场冒出来。我理解这股热度背后的逻辑Agent的能力瓶颈已经从模型智商转移到了工具可触达性。模型再聪明拿不到数据也是巧妇难为无米之炊。Skills恰好把模型能力和系统数据之间的胶水给补上了。对我们这种被数据孤岛困扰的团队来说这个趋势是个好消息。通用技能可以从市场上找现成的改造内部系统技能自己写一套两者拼起来Agent就不是一个只能聊天的玩具而是一个带着整套工具箱上岗的准员工。这一步跨过去数据孤岛问题才算真正有了一个轻量级、可落地的解法。3. 一套打通数据孤岛的Skills我是怎么设计的3.1 先盘点数据源我把数据源清单做成了设计起点真正动手写Skill之前我花了大半天做了一件看起来特别不技术的事列数据源清单。我把团队日常查询最多的系统一个个列出来记下每个系统里有什么数据、通过什么方式访问、有没有只读权限、最常见的查询需求是什么。数据源核心数据访问方式权限情况CRM客户资料、合约周期、跟进记录HTTP API只读token工单系统服务记录、投诉记录、处理状态HTTP API只读token知识库产品文档、操作手册、公告检索API应用账号只读数据库订单、日志类明细SQL只读账号监控平台服务可用性、报错摘要API只读token做完清单才发现我们对每个系统最常做的就是查询而且基本都是低并发、低频次的临时查询。这个发现让我彻底打消了上数据仓库的念头既然高频需求只有查询那让Agent学会查询就够了。清单做出来后每个系统对应几个技能包就顺理成章了——CRM一个、工单一个、知识库一个、数据库一个、监控一个。清单本身也是后续配置权限和网络白名单的依据。每个Skill脚本里访问什么域名、用什么凭证都可以从这张表里直接对照出来省得后面反复问这个系统的token在哪里。3.2 四条设计原则单一职责、显式触发、返回裁剪、安全只读Skills设计得不好很容易变成一个大而全的脚本最后Agent根本不知道该不该用它。我的经验是坚持四条原则单一职责。一个技能只回答一类问题。CRM技能就管客户和合约别顺手把报表统计也塞进去。职责越单一Agent越容易准确触发。我见过把十多个功能写进一个SKILL.md的情况结果描述怎么写都有遗漏实际调用全靠猜。显式触发。SKILL.md里的描述不能含糊。要写清楚何时使用更要写清楚何时不用。比如工单查询技能里加一句本技能不处理工单创建和状态修改能挡住一大串误触发。返回裁剪。脚本返回给Agent的数据必须是最小充分集。字段按白名单输出行数设置上限长文本截断或摘要。这既是为上下文窗口考虑也是为了让Agent不被无关信息带偏。安全只读。所有连接内部系统的Skill一律使用只读凭证网络访问做白名单限制。Agent本身没有恶意但你无法保证它每次都被用户正确引导权限边界必须从基础设施上兜住。这四条写起来简单但每一条背后都有一次翻车经历支撑。后面第5节我会展开讲几个具体踩坑案例现在先按住不说。3.3 三个核心技能包实例CRM查询、工单检索、知识库问答挑三个最典型的技能包展示一下核心设计。CRM查询技能的SKILL.md我写成了下面这个样子--- name: crm-query description: 查询CRM系统中的客户基本资料、合约状态和最近跟进记录。仅在需要了解客户信息、合约周期、到期时间时使用。不处理销售统计和市场分析。 --- # CRM客户查询 ## 适用场景 - 用户询问某客户的基本资料、联系人或所属负责人 - 用户询问合约是否到期、还剩多长时间 - 用户需要客户维度的信息作为续约/服务判断依据 ## 参数 - customer_id: 客户ID或手机号 - keyword: 客户名称模糊查询关键字可选 ## 输出约定 - 始终以JSON返回 - 字段限制为customer_id, name, owner, contract_end, last_follow_up - 无结果时返回: {status: no_result}工单检索技能的脚本核心逻辑更简单import json import os import urllib.request def search_ticket(customer_id, days90): base os.environ[TICKET_API_BASE] token os.environ[TICKET_TOKEN] url f{base}/tickets?customer_id{customer_id}days{days} req urllib.request.Request(url, headers{Authorization: fBearer {token}}) with urllib.request.urlopen(req, timeout10) as resp: data json.loads(resp.read().decode(utf-8)) # 裁剪字段只保留时间、类型、标题、状态 result [ {time: t[created_at], type: t[category], title: t[subject], status: t[status]} for t in data.get(tickets, []) ][:20] # 限制最多20条 return json.dumps({status: ok, tickets: result})知识库问答技能稍微特殊一点它需要先调检索接口拿到相关文档片段再做长度裁剪def retrieve(query, max_chars1200): # 调用知识库检索API取相关度最高的文档 # 对文档做章节切分取与query相关的片段 # 确保返回的纯文本不超过max_chars这三个技能包固定下来以后团队里任何一个人都能往里面加新的查询入口遵循同一个模式就行。3.4 一次真实的编排日志Agent怎样跨系统组装答案设计完成不代表能用我找了个真实问题做验证客户A的合约还有多久到期过去三个月有没有投诉适合按什么策略谈续约Agent的执行路径是这样的先调kb-search查询知识库里当前产品线的续约策略和产品变更公告拿到策略框架。再调crm-query拿客户A的合约到期时间和最近跟进记录。看到到期时间后调ticket-lookup拉取客户ID对应的工单列表筛选投诉类别。把三份结果拼成一个上下文按策略—客户状态—风险点的结构输出建议。整个过程中Agent每一次取数都只做一件事但编排起来就是一次完整的跨系统问答。以前这个流程要我开三四个系统翻半小时现在一分钟内出结论。这个例子让我确信Skills方案的核心价值不在单个技能本身而在Agent对技能的组合调度能力。4. 从零到一落地Skill怎么建、怎么注册、怎么调4.1 目录与依赖管理让每个Skill自带干粮写Skill时有几个实现层面的细节特别容易踩坑。第一个是依赖管理。Skill脚本如果依赖一堆第三方库会让部署变得很痛苦。我的建议是脚本尽量走标准库HTTP调用用urllib就够JSON解析用内置的json。实在要requests也可以用但要把依赖写清楚且保证在目标环境里装好。第二个是环境变量。SKILL.md和脚本里绝对不能写死token、域名、账号。我们有个约定凡涉及连接信息的一律从环境变量读取Agent注入这些变量脚本只负责消费。这样一套技能包可以在测试、预发、生产环境之间原样移动不会因为代码里写了一个测试域名而出事故。第三个是自包含。每个技能包的assets里放自己的参考配置不依赖外部共享目录。当初为了省事共享过一个config.json结果某个技能改了配置其他技能行为全变了排查半天才发现是共享文件被改。自包含虽然多花一点存储但心智负担小很多。4.2 SKILL.md怎么写才能少误触发好描述与烂描述的差距SKILL.md是误触发的重灾区。我最早写过一个文档查询技能描述只有一句用于查找文档资料结果Agent只要听到文档两个字就触发用户问帮我生成一份Word文档它也去查知识库完全驴唇不对马嘴。后来我总结了SKILL.md里必须写清楚的几个点系统的边界这个技能的数据来自哪个系统只覆盖哪几类查询。触发词尽量列出典型触发词比如合约到期客户投诉记录产品公告。负面排除明确写不用于什么场景这是减少误触发最有效的一招。输出格式自描述在SKILL.md里贴一段示例返回JSON帮助Agent理解后续能拿到的数据长什么样。用一个对比来说明。写得差的描述description: 查询客户数据。写得好的描述description: 查询CRM系统中的客户基本资料、合约状态和最近跟进记录。仅在需要了解客户信息、合约周期、到期时间时使用。不处理销售统计和市场分析。后者多出来的内容都是在帮Agent做选择题。Agent不是人它不会主动追问只能靠描述里的信号来判断该不该调用。描述写得越像一份精确的需求说明书误触发概率就越低。4.3 脚本接口设计参数校验、超时、错误码一个都不能少脚本是Skill的手如果脚本写得糙Agent拿到的数据就不可靠。我用三个规范来约束脚本质量参数校验。脚本入口要对传入参数做严格检查缺参数时返回结构化错误而不是抛异常。比如查询客户ID为空时返回{status: error, message: missing customer_id}Agent看到这个错误会知道自己参数传错了还能尝试补救。超时设置。所有外部调用必须有超时时间我们统一设10秒。内部系统再慢也不能让Agent在取数这一步无限等待。超时后返回错误码2并给出提示系统暂时不可用可稍后重试。白名单字段。返回数据永远从接口原始字段里挑出需要的再返回不直接把整个响应体透传。这样既控制token消耗也避免把无关敏感字段漏给Agent。def safe_return(data, allowed_fields, max_rows20): rows data.get(items, [])[:max_rows] return [ {k: item.get(k) for k in allowed_fields if k in item} for item in rows ]这个小函数是我所有Skill脚本的公共底座把最容易被忽略的返回裁剪做成了强制逻辑。4.4 把Skills挂到Agent上的两种方式本地技能包与团队共享技能包写好后挂载方式决定了团队协作的顺畅度。我们试过两种方式。第一种是本地挂载。把技能包放在自己机器的Agent技能目录下修改后重启Agent就能生效。这种方式适合个人开发调试改起来最快但问题是团队其他人看不到你的改动。第二种是项目共享。把技能包放进一个git仓库部署时同步到公共目录团队所有人共一套。好处是一致性强、可审查可以走代码评审流程。缺点是升级时要通知大家刷新否则有人用的旧版有人用的新版行为不一致。我的建议是个人实验用本地正式接入业务线用项目共享。现在很多Agent工具都支持从技能市场或压缩包安装第三方技能社区里那批现成的文档处理、前端开发、编码辅助技能包就是这么分发出去的。内部系统技能因为涉及连接信息建议本地维护不要上传到公开市场通用型技能则可以大胆用现成的没必要重造轮子。4.5 权限模型只读账号最小化token审计日志安全这块我特别想多说几句。Skills给了Agent执行能力这是好事也是风险。Agent可能在用户诱导下查询本不该查的数据也可能因为脚本bug误操作。我们的权限模型是三件套。第一所有业务系统统一用只读账号。查询类技能全部使用只读token不允许有任何写接口。写操作以后另做一套审批流程绝不让普通查询技能碰。第二token范围最小化。CRM的token只能查客户和合约查不了订单明细数据库账号只授权了必要的几张表的SELECT权限其他表一律没授权。第三审计日志。每个Skill脚本执行时都把调用时间、入参、返回条数、执行结果摘要打到一个独立日志文件里出了问题可以追溯是哪一次调用、传了什么参数。这套权限模型不复杂但对防线来说已经够用。Agent本身的推理能力再强只要执行层权限足够小风险就能被锁在笼子里。5. 实测效果与翻车现场哪些坑真实存在5.1 第一轮翻车SKILL.md写太泛所有问题都找它上线第一天就出洋相。我们把爱问技能挂上去结果所有问题都往那里跑。用户问出差报销流程它去查CRM用户问帮我起个英文名它去查客户数据库甚至问今天午饭吃什么它也想从系统里找答案。我打开Agent调用日志一看触发词就一个查询描述里没写任何排除条件。加上这个技能排在技能列表靠前的位置Agent在犹豫时就倾向于它。修复方案很简单把描述重写明确列出仅当需要客户资料/合约信息时使用并加了负面排除不用于报销流程、不用于产品咨询、不用于一般性问答。改完以后误触发率立刻降下来了。5.2 第二轮翻车返回原文太长上下文被塞爆第二个坑来自知识库检索。刚开始我偷懒让检索脚本直接把命中的文档段落整段返回想着Agent能自己筛重点。结果一段产品文档返回了三四千字再叠加其他技能的返回数据Agent的上下文窗口很快就满了输出质量肉眼可见地下降甚至开始漏掉关键信息。这个问题的本质是技能返回数据里噪音太多。后来我做了两层处理脚本里先对检索结果做相关性截断每段最多返回1200字符SKILL.md里明确写本技能返回的是文档片段摘要具体细节可要求进一步查询。这才是Skill和上下文窗口的正确相处方式——把最小充分集交给Agent而不是把整个文档搬过去。5.3 第三轮翻车并行调用时两个技能给出同一指标两个口径最隐蔽的一个坑出现在CRM技能和数据库技能同时被触发的时候。用户问这个月销售额是多少CRM技能返回的销售数据里含未回款订单数据库技能返回的订单金额只统计已支付订单数字对不上。Agent拿到两个数都很自信最后给出一个被拼凑出来的答案——单独看每步都对整体看是错的。这暴露了Skills方案的天然短板它解决数据可达不解决口径一致。两个系统对同一个指标定义不同Agent是无从判断的。我们的补救措施是在SKILL.md里加口径定义字段明确每个技能返回的指标是怎么统计的并且给同域技能加权威源标记。如果用户问的指标存在多源冲突SKILL.md指引Agent优先采用权威源必要时直接提示该系统与另一系统口径不一致请确认。5.4 调稳之后跨系统查证从40分钟到1分钟以内把上面三个坑填平之后这套Skills方案才真正进入可用的稳定状态。现在团队处理类似的跨系统客户查询流程统一变成用户提问Agent按需调用技能输出结构化结论。以前我开四个系统翻半小时才能确认的事实现在一分钟内就能拿到而且每个结论后面都带着数据出处可以直接追溯验证。另一个让我意外的收益是业务同事开始主动提新需求。他们发现加一个技能包比自己翻系统容易多了于是能不能也查一下物流信息能不能顺便把合同状态也查了这类需求接踵而至。技能的扩展成本低业务方自然愿意拥抱这比推一套正式数据平台遇到的阻力小得多。6. 这套方案能用到什么程度边界与取舍6.1 适合Skills做的三件事把一段时间的使用经验压缩成结论我认为Skills在三个场景里表现最好。第一跨系统只读查询与聚合。这是最核心的用武之地客户资料、工单记录、知识库文档、订单状态这类高频业务问答用技能包组合调度体验拔群。第二知识库与文档检索问答。文档类技能把翻知识库变成提问即答非常适合做内部IT支持、新员工入职问答。第三可控的自动化动作。在权限严格受限的前提下技能也可以触发开票、创建工单这类简单动作但一定要走单独的审批和审计流程不要跟查询技能混在一起。6.2 不适合硬塞给Skills的事能力项Skills方案表现更合适的方案全量数据分析差没有预聚合能力数据仓库/OLAP高频低延迟接口差Agent每次都有推理开销正式API服务强事务写入危险多步操作缺事务保证业务系统原生接口复杂指标口径统一弱只能靠SKILL.md约定指标平台/数据治理拿表格里的全量数据分析来说Skills方案本质上是对点查询的编排你让它处理几百万行明细做聚类分析既没这能力也没这必要。高并发低延迟更是Agent的软肋每次问答都要走一遍模型推理延迟从几百毫秒到几十秒不等这不是技能代码能优化的。强事务写入则是红线——几条数据改错了可以人工修资金或库存类的写入绝对不能靠Agent技能包去碰。6.3 什么时候应该回头用正规数据平台如果团队已经明显出现这些信号——指标口径反复扯皮、需要统一的大屏实时看板、数据团队开始专职做分析、业务对准确性要求上升到财务审计级——那就说明组织已经跨过了轻量打通阶段该认真上数仓或指标平台了。Skills解决的问题是最后一公里的问答它替代不了数据中台里的指标治理、质量监控和数据建模。我在实际中的体会是先靠Skills把日常查询体验做起来让业务同事意识到数据是可以被问出来的后面再推数据平台时大家的接受度和需求表达都会清晰得多。Skills不是数据中台的敌人反而能成为它最好的前哨站。6.4 顺着这个思路继续扩展的玩法如果你也想试我建议不要一上来就搭全套先选一个你每天重复至少三次的动作把它做成第一个技能。比如你天天要查订单状态就写一个订单查询技能天天要翻合同就写一个合同检索技能。一个技能跑顺之后你会慢慢理解Agent到底怎么理解描述、怎么选择调用这时候再铺开做多系统打通就顺手了。技能也可以延伸到工作流里每周把团队周报的素材聚合、把多个系统的数据汇总成一张简报、把会议纪要归档到知识库并关联相关客户——这些都可以变成一套个人助理技能包。数据孤岛的墙不是一天砌起来的自然也不可能一夜拆完但每多一个能跨系统回答问题的技能那面墙就薄了一分。