
给 AI 发一张“科研上岗证”——这句话最近一直在我脑子里转。很多人看到“163 个技能秒变 AI 科学家”这种标题第一反应是夸大其词第二反应是“是不是又来推销模型”。但如果你自己搭过 scientific agent 就会发现这个说法其实点到了一个很本质的工程转向我们不再指望大模型靠“涌现”自动变成科学家而是直接给它一套可注册、可调用、可审计的 Scientific Agent Skills让它在具体任务里像持证上岗一样按流程操作。K-Dense 这类项目也好类似 SSP 的技能协议也好背后的思路都差不多把“科学家”这个职业抽象成一张岗位说明书把岗位说明书拆成几百个原子操作再让 Agent 根据需要去调用。这篇就来拆一拆为什么“ 163 个技能”比“换一个更大的模型”更靠谱以及如果你想给 AI 实验室里的模型也发一张上岗证具体该怎么办。1. 为什么说“上岗证”比“模型变聪明”更接近真实科研1.1 模型不缺知识缺的是稳定执行先说一个很常见的现象。你用普通对话模型问“Dunnett 检验和 Bonferroni 校正的区别是什么”它能答得头头是道。但你让它“读取这份实验数据判断哪些组别与对照组有显著差异并给出符合期刊要求的报告”它可能吭哧吭哧跑出一段代码却在多重比较、方差齐性、样本量这些问题上突然犯迷糊。这不是模型变笨了是因为科研任务本质上不是“单次问答”而是一长串需要前后衔接的操作。阅读文献、提出假设、设计实验、清理数据、选择统计方法、跑分析、写结果、复现检查任何一个环节都有大量隐性规则。普通对话模型擅长的是“根据上下文生成下一段文本”而不是默认就能稳定执行一套长达几十步的科研流程。技能的作用就是把每一步操作固化成可运行、可校验的最小单元。模型不需要凭记忆猜“这里要不要做正态性检验”因为技能描述里就写着“先做 Shapiro-Wilk”如果数据明显非正态就切到非参数检验。换句话说我们不让模型临场发挥而是让它照着岗位操作手册干活。1.2 技能不是给模型加知识而是给模型加约束有人会问技能库里的内容模型难道不知道吗很多统计方法它确实知道论文里怎么写它也大概知道。但“知道”和“稳定执行”之间的距离非常大。举一个非常小的例子判断两组数据是否有差异。没有技能的模型可能直接给一个 t 检验结果。而一个设计良好的“两样本比较”技能至少要在内部处理四件事每组样本量是否够用太少就拒绝出结果正态性假设是否满足不满足就该换非参数方法方差是否齐性不齐要用 Welch 校正返回结果时是否附带效应量而不是只丢一个 p 值。这四步单独看都不难但让模型在自由对话里每次都做到几乎不可能。技能的价值就是把这个“几乎不可能”变成“必然如此”。因为它不只是提示词背后还有实际执行代码每一层校验都写死在函数逻辑里模型想跳过也跳不过去。所以说“上岗证”这个比喻很准确。证件真正的意义不是告诉别人你有多聪明而是告诉你哪些动作能做、哪些不能做、做了以后要按什么标准交付。1.3 谁最需要这套东西按我自己的观察三类人最需要这种科研技能 Agent第一类是高校和研究所里真正做实验的人。他们每天产出大量数据但是没精力把所有统计细节都学好又不放心把数据直接丢给通用模型。第二类是药企、CRO、检测机构里的数据科学家他们关心的不是模型能不能聊科研而是能不能在合规流程里稳定输出可审计结果。第三类是 AI 应用开发者想给垂直行业的客户交付“科研 Agent”能力但是发现没有一套标准技能库只能从零造轮子。如果你属于这三类里任何一类下面内容应该能直接落地。尤其是第三类你会发现做好一个技能库比调一个“神仙模型”更实在也更可控。2. K-Dense 这类 Agent 技能库内部到底按什么结构组织2.1 163 个技能不可能全塞进提示词很多人第一次听到“163 个技能”的第一反应是模型上下文窗口能装得下这么多内容吗答案很明确装不下也不该装。你不可能在一个系统提示词里把 163 个技能全部写好那会让模型不知道该选哪个。就算硬塞进去真正执行一个任务时也会因为指令太多导致路由混乱甚至出现“这个技能好像是干这个的但另一个技能描述也沾边”的情况。所以 K-Dense 这类技能型 Agent工程上普遍采用一个“注册表 路由 执行 审计”的结构。我把这套结构画成一句话来说技能注册表负责登记所有可用的技能包括名字、版本、输入输出格式、依赖环境、测试用例技能路由负责根据用户问题从注册表里挑出最相关的几个候选技能技能执行器负责真正调用代码或外部工具并在执行前做参数校验审计日志负责记录每次调用、输入、输出和异常方便事后再查。换句话说163 个技能不是放在模型的脑子里而是放在一个外部能力库里。模型每次拿到任务只先加载与任务相关的五六个技能定义剩下的都留在注册表里需要时再取。2.2 一个技能长什么样注册表里的最小单元不管项目名字叫 K-Dense还是封装成 SSP 这类技能协议单个技能的核心结构都差不多。我会用下面这套最小字段来定义{ skill_id: s0037, name: compare_two_groups, version: 1.2.0, description: 对两组连续观测值做假设检验先做正态性检验 不符合正态则使用 Mann-Whitney U否则使用 Welch t 检验。, inputs: { type: object, properties: { group_a: {type: array, items: {type: number}}, group_b: {type: array, items: {type: number}} }, required: [group_a, group_b] }, outputs: { type: object, properties: { method: {type: string}, p_value: {type: number}, effect_size: {type: number} } }, policy: { allow_internet: false, approval_required: false } }这里最关键的不是 JSON Schema而是description字段。因为模型不是靠读代码决定要不要调用这个技能的它读的是自然语言描述。描述里如果只写“比较两组数据”模型可能什么场景都往这里塞但如果写清楚“先做正态性检验、非正态建议切换非参数方法”路由准确率会大幅提升。我自己每次设计技能时都会先写 description再写代码。如果 description 写不清楚一个技能在什么场景下用、什么场景下不用这个技能就还不合格不该进入注册表。2.3 为什么这种结构更能防止翻车科研场景最怕两件事一是不知不觉用了错误方法二是出了问题找不到原因。单体模型直接输出分析结论的时候它不会告诉你“我这一步为什么会选 ANOVA为什么我认为方差齐性满足”因为它压根没有真正检验方差它只是在生成一串看起来合理的文本。而注册表加执行器这种结构能把每一步都变成可以被质疑、被回滚、被审查的对象。比如执行器接收到“比较 A 组与 B 组”的任务后它会先做参数校验发现 A 组只有两个样本直接拒绝执行同时返回“样本量不足至少需要 3 个观测值”。这种硬约束靠提示词很难做到但写成代码就是一行 if 判定的问题。我甚至见过有团队把这种技能库集成到电子实验记录本里每个技能调用的前后状态都会被快照之后论文被审稿人质疑分析过程时团队能直接把当时的审计日志导出来这种可追溯性在真实科研协作里非常重要。3. “163 个技能”到底能从哪些抽屉里抽出来3.1 六个抽屉覆盖完整科研管线如果只是为了凑数量163 这个数字一点也不稀奇。真正有价值的是技能覆盖的边界。我在梳理这类项目时比较认可按科研流程把它们分成六个抽屉。抽屉覆盖环节典型技能示例文献与知识获取阅读、检索、综述、溯源从 PDF 抽取实验表格、识别引用关系、对比不同论文的方法表述数据工程与清洗拿到原始数据后的预处理列名语义识别、缺失值模式提示、单位统一、离群值标记统计推断与建模实验数据分析正态性检验、多组比较、生存分析、回归诊断、时间序列建模实验设计与仿真没做实验前先算清楚样本量估算、随机分组方案生成、功效分析、敏感性分析科学写作与可视化把结果变成论文或报告图表主题统一、方法段落生成、图片说明重写、参考文献格式化质量与伦理审计最容易被忽视的一环p 值多重比较检查、数据造假模式提示、可复现性检查、结论边界提示这个分类方法不是唯一标准但它能回答一个重要问题为什么需要 163 个技能而不是 20 个大功能。因为科研不像写一个软件只要把少数几个 API 做得够深刻就行。科研的复杂性在于分支条件非常多数据类型不一样样本量不一样实验设计不一样期刊要求不一样。一个“多组比较”的技能可能要根据方差是否齐性、样本是否配对、是否需要校正等多种分支选择不同的路径。如果把这些分支都混在一个 300 行的函数里维护成本会高到没人敢动。3.2 为什么“小技能”比“大工作流”更好用我看到不少团队刚做 Agent 时喜欢先搭一个很大的流水线检索文献、归纳结论、生成研究方案、生成代码、跑数据、写报告一次全部跑完。这种做法乍一看很专业实际用起来特别脆。因为只要某一步出错后面整个流程都白费。比如前端检索回来的文献标准不可控输入到方案生成阶段模型就可能生成一个基于错误前提的假设。相比之下小技能组成的大流程更容易调试。如果你发现“数据清洗”这一步里没有处理缺失值你只需要改进那一个技能而不需要推翻整个管线。技能可以像零件一样组合先跑“缺失值检查”再根据结果决定走“完整数据回归”还是“多重插补”。坏了哪个零件就换哪个零件这是大而全的设计给不了的灵活性。3.3 数量只是第一步核心是技能之间的“互认协议”163 个技能真正麻烦的地方不在开发而在接口统一。如果每个技能输入输出格式各写各的模型在技能之间做切换时会非常痛苦。举个例子数据清洗技能如果跑完输出的是 DataFrame而统计建模技能默认接收 CSV 文件路径那模型就要自己在中间做一次格式转换。这种转换一旦交给模型自由发挥错误率会非常高。所以成熟的技能库一定会有统一的数据中间格式。我一向建议不同技能之间尽量通过文件、标准 JSON 或统一的表格对象传递数据而不是靠在参数里传递一个大对象。这就像工厂里的传送带每个工位只需要知道原料和标准包装长什么样不关心前一个工位内部怎么运作。4. 手把手造一个“能上岗”的科学技能4.1 第一步先写好输入输出契约空谈概念没有意义直接动手写一个最小技能最有用。我选择“两组连续数据比较”作为例子因为这个场景既有统计判断又有异常处理非常适合展示一个技能该有的严谨度。动手前先定义输入输出契约输入group_a、group_b两个数值数组每组至少 3 个样本过程先做 Shapiro-Wilk 正态性检验若任一组的 p 值小于 alpha就改用 Mann-Whitney U 检验否则使用 Welch t 检验输出方法名、统计量、p 值、效应量 Cohens d边界样本量不足 3 或 scipy 未安装时不返回空结果而是返回明确错误码。这个契约看着简单但已经把“模型自由发挥”的空间压到很小了。4.2 第二步把技能写成可执行函数下面是这个技能的核心实现。为了看清楚逻辑我故意没有做太多工程魔法只保留了最重要的分层判断。import statistics try: from scipy import stats except ImportError: stats None def compare_two_groups(group_a: list[float], group_b: list[float], alpha: float 0.05) - dict: 对两组连续观测值做假设检验。 流程 1. 校验样本量 2. Shapiro-Wilk 正态性检验 3. 满足正态性 - Welch t 检验 4. 不满足正态性 - Mann-Whitney U 检验。 if stats is None: return {error: scipy is not installed} if len(group_a) 3 or len(group_b) 3: return {error: 每组样本量至少为 3拒绝执行统计推断} # 正态性检验 _, p_a stats.shapiro(group_a) _, p_b stats.shapiro(group_b) if p_a alpha or p_b alpha: stat, p_value stats.mannwhitneyu(group_a, group_b, alternativetwo-sided) method Mann-Whitney U else: stat, p_value stats.ttest_ind(group_a, group_b, equal_varFalse) method Welch t-test # 计算 Cohens d n1, n2 len(group_a), len(group_b) mean1, mean2 statistics.mean(group_a), statistics.mean(group_b) sd1, sd2 statistics.stdev(group_a), statistics.stdev(group_b) pooled_sd (((n1 - 1) * sd1 ** 2 (n2 - 1) * sd2 ** 2) / (n1 n2 - 2)) ** 0.5 cohens_d abs(mean1 - mean2) / pooled_sd if pooled_sd 0 else None return { method: method, statistic: float(stat), p_value: float(p_value), effect_size: cohens_d, normal: p_a alpha and p_b alpha, }这里有一个特别容易踩的细节就是 Cohens d 计算。如果两组标准差都极小pooled_sd可能接近 0直接除会产生无穷大。所以我在返回前判断了分母如果它太小就不给效应量防止 Agent 拿到一个 Inf 后还煞有介事地写进报告。4.3 第三步让 Agent 学会在需要时调用它有了函数还要把它注册成模型可以感知的技能。不同 Agent 框架做法不一样但思路都是把函数签名、参数说明、返回值结构转成模型能读的格式。我在实际项目里的注册方式大致是把 JSON 描述放进候选工具列表然后由路由层决定是否把当前问题的相关工具传给模型。def route_and_call(user_query: str, available_skills: list[dict]): # 1. 用一个简单的关键词召回候选技能 if 两组 in user_query or 差异 in user_query or compare in user_query.lower(): candidates [skill for skill in available_skills if skill[name] compare_two_groups] else: candidates [] if not candidates: return { error: 没有找到合适的技能请明确你要比较的数据类型 } # 正常流程里这里应该把 candidates 和参数结构交给模型 # 由模型解析用户数据并生成调用参数。 # 本文为演示直接手动传入参数。 result compare_two_groups( group_a[1.2, 1.4, 1.3, 1.5], group_b[2.2, 2.1, 2.4, 2.0] ) return result为了让这类技能真正在 Agent 里跑起来我强烈建议你在本地把调用过程完整跑一遍。自己先扮演“调度模型”用不同的测试数据反复调用这个函数观察它会不会在某些边界条件下返回不理想结果。只有当你对技能的行为模式熟悉到一定程度才能把它放心交给 AI 去自动调用。5. 常见问题与踩坑记录5.1 五个最常见的“技能上岗”问题我把过去实操中遇到的高频问题整理成了一张排查表。这些问题大部分都不是模型笨导致的而是技能库工程化不足导致的。现象可能原因处置方式Agent 选了技能但迟迟不调用技能描述和用户问题表述不一致检查 description 是否太短或太 API 化改成说人话技能返回结果被 Agent 无视模型直接把代码写在对话里没走工具链路加强输出格式约束禁止模型直接给出代码小数据能跑通换真实数据就报错技能内部缺少异常捕获和类型检查调用前增加 schema 校验拒绝非预期输入技能之间数据格式对不上每个技能各自为政没有统一中间格式统一表格或 JSON 传输规范避免传 DataFrame多跑几次结果不稳定随机数种子没固定或随机采样没指定参数在技能里固定随机种子并记录版本号5.2 一个有争议的问题163 个技能为什么也会越权技能越多Agent 可做的操作越多这句话既是优势也是风险。我见过一个比较激进的团队把所有和“数据处理”相关的技能都给了 Agent 完整权限。结果模型在处理一个 CSV 时直接把原文件覆盖了因为负责写入的技能没有做“是否允许覆盖原文件”的权限校验。对科研数据来说这种事故非常要命。所以我做技能库时的原则是技能默认最小权限只有明确需要外部读写的技能才开放文件权限涉及到删除、覆盖、发送外部请求的操作一律要求人审。哪怕这样会让自动化程度下降一点我也愿意换确定性。还有个有意思的问题是技能库越大模型在路由时越容易出幺蛾子。比如用户说“帮我看看这些数据行不行”模型可能同时选中了“缺失值检查”“离群值识别”“正态性检验”三个技能结果每个都跑了一遍最后输出互相矛盾。这时候需要在路由层加入“互斥规则”比如如果一个技能已经返回了数据不可信的结果另一个技能就不应该继续执行。5.3 科学技能评测不能只看“模型自评”给技能库做评测我觉得最忌讳的是用“模型觉得自己做得好不好”来当标准。模型在绝大多数情况下都会觉得自己每一步都很正确你要做的是准备一批有确定答案的数据集。比如我上面写的compare_two_groups至少要准备几组测试数据一组符合正态分布的数据期望输出 Welch t 检验一组明显右偏的数据期望输出 Mann-Whitney U一组只有两个样本的数据期望直接拒绝执行一组两组均值几乎相等的数据期望 p 值很大效应量接近 0。把这些用例自动化之后每次往技能库新增内容都要跑一遍完整回归测试。技能函数和代码库一样非常容易“改一个地方坏另一处”。没有回归测试你根本不敢在 163 个技能上放心做持续迭代。6. 直接落地的话我会建议你从哪一步开始6.1 先不要急着造 163 个技能如果只是看到“163 个技能”就觉得自己也要做一个大型技能库大概率会陷入一个很尴尬的局面技能写了一大堆但没有一个在真实任务里被稳定使用过。我的建议正好相反。先找一两个自己每天都会做的重复分析任务比如“临床数据基线表生成”“两组结果比较”“异常值检测”把它们做成三五个高质量技能先在实际项目里跑两个月。这两个月里你一定会不断修复 bug、补边界条件、重写 description。等这几个技能的调用成功率达到 95% 以上你再照着同一个流程去扩展其他技能。经验是第一批技能的质量决定了后续整个技能库的底气。第一批做糙了后面全在还债。6.2 给技能写“上岗考题”比写技能本身更重要我会给每一个新技能配套至少三个测试用例一个用来验证主路径一个用来验证边界另外一个用来验证异常输入。这些测试其实就是“上岗考题”。只有通过这些考题技能才允许被 Agent 正式调用。听起来很像考试但科研 Agent 确实应该这样。毕竟真正的科研人员要拿学位、拿资质才能做实验、出报告AI 要为科研负责也应该先通过一关一关的能力验证。这也是我一直觉得“上岗证”这个比喻特别贴切的原因。最后分享一个实际体会你不需要一次性搞定所有科研方向但如果你能把某个细分领域里高频、重复、容易出错的分析步骤都固化成经得起测试的技能这个 Agent 在真实用户眼里就已经比一个只会空谈方法学的通用大模型靠谱得多。技能库真正值钱的不是那份长长的清单而是清单背后每一道经过检验的标准动作和约束边界。