ARTICLE · 1208660
技能系统:怎么让 AI 学会你的业务
老师傅的笔记本
工具是现成的扳手,技能是老师傅的笔记——AI 不仅要有工具,还要有使用工具的"经验"。把老师傅的手艺写成 AI 能执行的步骤,这才叫教会它
工厂里最有价值的不是设备,是老师傅脑子里的经验。"这批 SECC 板材要先预热到 60°C 再冲压""CNC-03 的主轴振动超过 5mm/s 就该换了""SPC CpK 低于 1.2 就要停线排查"……
这些经验不是写在 SOP 里的,而是老师傅几十年积累的"手感"。技能系统就是把这些"手感"变成 AI 可以学习和执行的东西。
两种技能:认知 vs 行动
BYOE 引擎把技能分为两类:
| 认知技能 | ~/.byoe/skills/<name>.json | ||
| 行动技能 | ~/.byoe/skills/<name>.py |
认知技能教 AI 怎么想,行动技能教 AI 怎么做。
认知技能:JSON 触发式 Prompt
# skills.py:1-16"""Server-side skill persistence.Skills are stored as JSON files in ~/.byoe/skills/<name>.json.Schema of each skill file: { "name": "my-skill", "description": "...", "instructions": "...", "trigger": "optional trigger phrase", "created_at": "2026-04-17T12:00:00", "builtin": false }"""认知技能的核心是 instructions——一段告诉 AI "遇到这种情况该怎么处理"的提示词。trigger 是触发短语,当用户输入包含这个短语时,自动激活这个技能。
比如一个"设备故障诊断"技能:
{ "name": "device-diagnosis", "description": "设备故障诊断技能", "instructions": "当用户报告设备故障时:1) 先查 query_machine_health 获取健康评分;2) 再查 query_telemetry 获取实时遥测;3) 对比历史数据判断是突发故障还是渐进退化;4) 给出维修建议和优先级。", "trigger": "设备故障 机器异常 报警"}这段 instructions 就是老师傅的"诊断思路"——先看健康评分,再看实时数据,对比判断,给建议。AI 读了这段话,就知道遇到设备故障时该怎么处理。
行动技能:Python 脚本
认知技能是"纸上谈兵",行动技能是"真刀真枪":
# skills_runtime.py:13-67(节选)class DynamicSkillTool(Tool): def __init__(self, skill_name, skill_file, description=""): self.name = f"skill_{skill_name}" self.skill_file = skill_file # parameters 声明单个字符串入参 args_json(此处省略) def execute(self, args_json="{}"): allowed = (Path.home() / ".byoe" / "skills").resolve() self.skill_file.resolve().relative_to(allowed) # 安全沙箱 args = json.loads(args_json) if args_json else {} spec = importlib.util.spec_from_file_location(self.name, str(self.skill_file)) mod = importlib.util.module_from_spec(spec); spec.loader.exec_module(mod) return str(getattr(mod, "run", None)(**args))这段代码是整个技能系统的运行时核心:把一个 .py 文件包装成 Agent 能调用的工具。
有三件事必须看懂:
relative_to(allowed)是安全沙箱——它确保技能文件解析后的真实路径仍在 ~/.byoe/skills/目录下。LLM 生成的参数里如果塞了../../etc/passwd,这里会直接抛异常。- 统一接口
run(**kwargs) -> str——不管技能脚本里写了什么,对 Agent 来说永远只有这一个入口,返回值一律转字符串。参数从 args_json(一个 JSON 字符串)透传进来,所以 LLM 生成的参数不需要额外解析成结构体。 importlib.util运行时加载——技能不是启动时打包进来的,而是调用那一刻才用文件路径动态 import。
省略的部分是 __init__ 里 description 的默认值推导、execute 里模块对象和 run 的存在性检查、以及异常包装。之所以能省:这些逻辑对"技能怎么跑起来"这个理解没有贡献,真正要记住的是路径必须锁死在 skills 目录这一条——那是安全和功能能同时成立的前提。
技能的创建:CreateSkillTool
AI 可以自己创建技能——这就是"学习":
# skills_runtime.py:70-136(节选)class CreateSkillTool(Tool): name = "create_skill" # parameters 声明 skill_name / python_code 两个必填入参(此处省略) def execute(self, skill_name, python_code, description=""): safe = "".join(c for c in skill_name if c.isalnum() or c in ("_", "-")) code = python_code.strip() if "def run(" not in code: # ← 自动包装 code = "def run(**kwargs):\n" + \ "\n".join(f" {ln}" for ln in code.splitlines()) (self._skills_dir / f"{safe}.py").write_text(header + code, "utf-8")这是"AI 学习"的入口:LLM 生成一段 Python,系统把它存成技能文件,之后就能反复调用。
入参只有两个必填项:skill_name(技能标识)和 python_code(代码正文),另有一个可选的 description。入参 schema 里唯一有信息量的约束是"代码里必须有 def run(**kwargs)"——下面那行自动包装就是为它准备的兜底。
两个细节值得单独说:
safe_name是文件名净化。LLM 可能生成 "../../../etc/cron.d/xxx"这样的技能名,过滤成只保留字母数字和_ -之后,路径穿越就断了。这和上一段DynamicSkillTool里的路径检查是两道独立的防线——一道管写入、一道管执行。if "def run(" not in code是那个很贴心的自动包装。让 LLM 少写一层函数签名,代价是它对"什么算合法技能"的判断退化成了字符串包含。
省略的是 parameters 里那个 description 字段的完整描述文本、execute 里写文件后同步写入记忆系统的部分,以及 header(文件头注释)的具体内容。
注意 Auto-wrapped 逻辑:如果用户(或 AI)提供的代码没有 def run(),系统会自动包装一个。这让技能创建更友好——你只需要写核心逻辑,不用关心接口。
创建后,技能还会被写入记忆系统:
# skills_runtime.py:122-134from ..light_memory import get_memoryget_memory().write( path=f"/skills/{safe_name}", content=f"skill_file={skill_file}\n\n{description}", layer="knowledge", tags=["skill", safe_name], summary=description or f"Dynamic skill {safe_name}", source="agent",)技能的加载:LoadSkillTool
创建好的技能需要"加载"才能被 LLM 调用:
# skills_runtime.py:139-185class LoadSkillTool(Tool): name = "load_skill" description = "Load a previously created skill as a callable runtime tool." def execute(self, skill_name, description=""): skill_file = self._skills_dir / f"{safe_name}.py" tool = DynamicSkillTool(safe_name, skill_file, description=description) register_tool(tool) if self._parent_agent is not None: self._parent_agent.add_runtime_tool(tool) return f"Skill loaded as tool '{tool.name}'"加载做了两件事:
- 全局注册
: register_tool(tool)让新 Agent 也能用 - 当前会话注册
: add_runtime_tool(tool)让当前 Agent 立即可用
LRU 裁剪:最多 50 个技能
技能不能无限增长。BYOE 用 LRU(最近最少使用)策略裁剪:
# skills.py:24MAX_SKILLS = 50 # hard cap — oldest (by name sort) pruned when exceeded# skills.py:27-48def _prune_skills(): files = list(SKILLS_DIR.glob("*.json")) if len(files) <= MAX_SKILLS: return files.sort(key=_last_used_ts) for f in files[: len(files) - MAX_SKILLS]: f.unlink()每次创建新技能后检查总数,超过 50 个就删最久没用的。get_skill() 会更新 use_count 和 last_used,确保常用技能不被误删。
技能的生命周期
一个技能从诞生到被裁剪,一共经过六站:
create_skill | run() | |
~/.byoe/skills/<name>.py,同步记进知识层记忆 | ||
load_skill | DynamicSkillTool | |
register_tool()add_runtime_tool() 本会话可用 | ||
execute() | ||
注意第 ② 步会同时写文件、写记忆。这不是冗余——文件是"能执行的代码",记忆是"这个技能为什么存在、什么时候该用"。后者是语义检索能命中它的原因。
王班长不肯把经验交出去
技能系统最难的部分不是技术,是让老师傅愿意把经验写下来。
李工所在的机修车间有个用了十几年的规矩:压铸机停机后,必须先排料再拆模。顺序反了,铝液在模腔里冷凝,整套模具要重新清。
李工试过让 AI 记这条。他跟质检主管老陈演示:"你问它压铸机停机怎么处理,看它说得对不对。"
AI 说得头头是道,而且错。它给的是标准流程:断电 → 冷却 → 开模 → 清腔 → 复检。完全正确,也完全没用——那是手册上的流程,李工知道手册,他想知道的是手册上没写的那个"先"字。
李工的评价是:"它答的是考试题,我想的是实操题。"
这就是认知技能和行动技能都必须存在的理由。老陈后来做了件事:把李工那套排查逻辑整理成一个 JSON 认知技能,trigger 设成"压铸机停机""停机处理"——从那以后,AI 一听到这几个字就先调李工的流程,而不是背手册。
技能系统的价值不在于让 AI 变聪明,而在于让某个人的经验能覆盖到他不在场的那些班次。 李工明年退休,这个技能还在。
一个补充提醒:技能会过期。如果李工那套规则三个月后改了工艺,但没人去改那个 JSON 文件,AI 会自信地教错人。所以技能库必须有人负责定期复核——这跟 SOP 文件要定期评审是一个道理。
认知技能 vs 行动技能:什么时候用哪个
判断标准:如果需要调用外部系统或做复杂计算,用行动技能;如果是"思路引导"或"模板填充",用认知技能。
技能的分享
技能存储在 ~/.byoe/skills/ 目录下,天然支持分享:
- 文件复制
:把 .json或.py文件发给同事,放到他的 skills 目录即可 - 版本控制
:把 skills 目录纳入 Git,团队共享一套技能库 - 导入导出
: list_skills()返回所有技能,可以序列化为 JSON 传输
两个系统的对比
小结
技能系统的本质是 给 AI 一个"老师傅的笔记本":
- 认知技能
:用 JSON 存储的 Prompt 模板,教 AI "遇到这种情况怎么想" - 行动技能
:用 Python 存储的可执行脚本,教 AI "遇到这种情况怎么做" - 创建
:AI 可以自己创建技能(CreateSkillTool),实现"学习" - 加载
:加载后变成 Agent 的动态工具,LLM 可以直接调用 - 裁剪
:LRU 策略确保技能库不超过 50 个
工具是"手",技能是"经验"。有了技能系统,AI 不再是一个"什么都会但什么都不精"的通才——它可以变成某个领域的专家。
但别忘了王班长那次演示:AI 答对了手册,不等于答对了现场。 技能系统的上限,取决于有没有人愿意把真正管用的那部分经验写下来。
下篇预告:Agent 能调工具、能记事、能学技能——但它怎么和其他 Agent 协作?下一篇我们看多 Agent 编排:Swarm 模式和任务分发是怎么让多个 AI 一起干活的。
留言话题
你车间里有没有哪条经验,是"手册上没写、但每次都得先做"的那种?
比如"必须先断电再拆"、"这批料要过夜回火"、"这个孔要先钻后攻"。一条就够,我想收集一批看看能不能做成技能。
随时可以体验 Aethon 智能体:https://aethon.zhinengti.online(AI原生智造智能体) 了解 Aethon 与整体方案:https://www.zhinengti.online(智能体在线)
本文是「AI 原生智造·进阶」系列第 11 篇,共 26 篇。《智造进化论》系列从应用场景讲起,本季深入技术实现。















































































