LangChain Agent Skills 实战指南:12个案例玩转智能体技能封装与编排

发布时间:2026/8/31 15:54:21
LangChain Agent Skills 实战指南:12个案例玩转智能体技能封装与编排 最近在落地智能体项目时最深的感受是模型能力再强如果 Agent 只能靠堆 prompt、堆临时函数来扩展能力项目很快就会失控。尤其当工具函数从几个涨到几十个之后改一个工具影响另一个场景的情况非常常见排错成本直线上升。LangChain 新版本围绕 Agent Skills 的架构设计正好把“给 Agent 加能力”这件事变成了一套可以标准化交付的工程方案一个技能一个目录有说明、有代码、有依赖能被 Agent 自动发现、自动调度、重复复用。这篇文章不聊虚的直接用 12 个递进案例从最简单的单文件 Skill 开始一步步写到多 Skill 组合编排、记忆保持、RAG 知识库、MCP 接入和多模型切换。任何一段示例都可以复制到自己项目里改造成可用能力。无论你刚接触 LangChain还是已经在做生产级 Agent这篇文章都值得收藏。1. 背景与核心概念1.1 什么是 Agent SkillsAgent Skills 直译过来就是“智能体技能”。你可以把它理解成一个打包好的能力单元一个 Skill 就代表 Agent 会的一项具体技能比如“查当前时间”“解析简历 PDF”“清洗 Excel 数据”“查企业知识库”。在工程实现上一个 Skill 通常是一个标准目录里面包含SKILL.md技能说明文件告诉 Agent 这个技能是干什么的、什么时候该用、怎么用。scripts/真正执行的代码比如 Python 脚本。requirements.txt该技能运行所需的依赖。assets/技能附带的资源文件比如模板、词典、参考文档。Agent 启动时扫描 skills 目录把每个 Skill 都转成自己“会做的事情”再根据用户问题选择调用。换句话说以前我们是在代码里写死“Agent 能做什么”现在变成了在目录里声明“Agent 会什么”。1.2 Agent、Skill、Tool、MCP 的区别很多初学者会把 Agent Skills、Tool、MCP 混为一谈。这里用一个表格区分概念本质角色定位Agent决策者和执行者负责理解目标、规划步骤、调用能力、处理结果Tool单个可执行函数Agent 手里的一把螺丝刀只管执行不带说明Skill一组打包好的能力单元相当于一个装满工具的“工具箱”自带说明书MCP统一接入外部工具的协议相当于标准插座让不同系统的能力可以被统一插拔对比之后能看出来Tool 太“碎”MCP 解决的是“怎么连”而 Agent Skills 解决的是“怎么组织、怎么描述、怎么让模型正确使用”。Skill 内部可以调用 Tool也可以通过 MCP 协议连接外部服务。1.3 如何理解 LangChain、LangGraph 与 Agent Skills 的关系先说一个常被问的问题LangChain 过时了吗答案是并没有。LangChain 在早期是一个偏“链式调用”的库后来把重心和能力逐步迁移到了 LangGraph、LangSmith 这一套新生态上。LangGraph 负责有状态的图编排LangSmith 负责链路观测Agent Skills 则成为智能体能力封装层。三者关系可以这样看LangChain提供模型接入、Prompt 管理、解析输出等基础能力。LangGraph提供状态机式的编排能力让 Agent 可以走分支、循环、条件跳转。Agent Skills定义“Agent 能做什么”以标准目录格式交付给上层编排使用。这也解释了为什么搜索里总有人问 LangGraph 和 LangChain 的区别LangGraph 是编排框架LangChain 是基础工具库两者在不同层级不是二选一的关系。Agent Skills 在这个体系里更像是“插在编排层和能力层之间的标准接口”。2. 环境准备与版本说明2.1 运行环境本文示例以 Python 环境为主建议使用 Python 3.10 及以上版本。操作系统方面Windows、macOS、Linux 都可以正常运行但如果你用到了zoneinfo等时区库Linux 服务器上要注意系统时区数据是否完整。需要说明的是LangChain 生态迭代非常快尤其是 Agent Skills 这类新功能不同版本的 API 名称可能有差异。本文代码以常见稳定用法为示例重点演示架构思路。如果你安装的版本报错优先去官方文档或当前版本的 changelog 中确认最新 API 名称。2.2 安装依赖建议先创建一个独立虚拟环境python -m venv .venv source .venv/bin/activate # Windows 下使用 .venv\Scripts\activate然后安装基础依赖pip install -U langchain langchain-openai langgraph后面案例中需要用到的其他库比如pandas、faiss-cpu在对应案例里单独安装即可。如果你所在网络环境无法正常安装也可以换成国内镜像源pip install -U langchain langchain-openai langgraph -i https://pypi.tuna.tsinghua.edu.cn/simple2.3 项目结构规划为了让后面的 12 个案例都能直接复用建议先建一个统一的目录结构agent-skills-demo/ ├── skills/ │ └── current_time/ │ ├── SKILL.md │ └── scripts/ │ └── current_time.py ├── agent.py ├── .env └── requirements.txt本文后面所有 Skill 都会放在skills/目录下每个子目录就是一个独立技能。这种结构也方便你后续接入 CI/CD把技能作为一个独立模块测试和发布。3. 核心原理拆解3.1 Skill 的标准目录规范先看一个最简单的SKILL.md注意文件格式采用 Markdown 头部 YAML frontmatter--- name: current_time description: 获取当前日期和时间也支持获取指定时区的当前时间。 when_to_use: 当用户询问“现在几点”“今天几号”“某个时区的当前时间”时使用。 --- # 当前时间查询技能 调用 scripts/current_time.py可以获取当前时间。 用法 bash python scripts/current_time.py --timezone Asia/Shanghai不传 timezone 参数时默认使用 UTC。这段内容里面最关键的不是那几行使用说明而是 frontmatter 里的 name、description、when_to_use。因为 Agent 本身不会“看”代码它只能通过 description 和 when_to_use 来判断当前问题该不该调用这个技能。一个写得好、边界清晰、触发条件明确的说明能大幅提高模型选对技能的概率反过来写得含糊就会导致误调用或完全不调用。 ### 3.2 Agent 使用 Skill 的完整链路 一个 Skill 从被加载到被调用大致经历 5 个步骤 1. 启动扫描Agent 启动时扫描 skills 目录读取每个 Skill 的 SKILL.md。 2. 构建化身把 Skill 转成 Agent 可见的工具描述通常是 JSON Schema 或结构化说明。 3. 意图匹配模型根据用户问题对比每个 Skill 的描述选出一个或多个候选技能。 4. 参数填充模型按照 Skill 使用说明生成调用参数。 5. 执行回传系统执行 Skill 脚本把结果返回给模型模型再做二次加工后回复用户。 这个过程说白了就是 ReAct 循环的工程化实现Reason模型想选哪个技能→ Act系统执行技能→ Observe把结果回传。Agent Skills 做的事情就是让这个循环里的“动作集合”变得更加清晰、稳定、可维护。 ### 3.3 任务规划能力是怎么实现的 搜索热词里经常有人问“LangChain 中 Agent 的任务规划能力是如何实现的”这里顺便讲透。在 LangChain 生态里任务规划通常有两条路线 第一条是纯 Tool Calling 路线模型直接输出“调用哪个工具 传什么参数”系统负责执行适合单步或少量步骤的任务。 第二条是 LangGraph 图编排路线把任务拆成多个节点每个节点可以做判断、可以调用模型、可以执行技能节点之间通过 State 传递数据适合复杂多步任务。 Agent Skills 在两条路线里都能发挥作用在 Tool Calling 路线里Skill 就是高质量的工具描述在 LangGraph 路线里Skill 是节点内实际执行的能力单元。任务规划仍然由模型完成但模型做规划时的“候选动作集合”来自 Skills这就保证了规划不是凭空来的而是建立在明确可执行的能力清单之上。 ### 3.4 Skill、Tool、LangGraph 如何协作 举一个协作场景用户问“帮我查一下上海现在的天气然后和北京对比一下”。 - LangGraph 负责把任务拆成“查询天气”和“对比结果”两个节点。 - 每个节点内部调用一个技能query_weather Skill。 - 模型根据用户问题把“上海”和“北京”分别填入参数。 - 两个节点执行完成后LangGraph 汇总结果再让模型做对比输出。 在这个场景里Skill 是能力层LangGraph 是编排层模型是决策层。层级清晰了后续加新能力只需要加新 Skill不需要动编排逻辑这也是 Agent Skills 架构最大的工程价值。 ## 4. 第一组案例Skill 定义基础案例 1-4 ### 4.1 案例 1单文件 Skill最小可用单元 首先创建 skills/current_time/SKILL.md内容直接用前面 3.1 节的示例。这个 Skill 的精髓在于它的“最小化”不需要任何外部依赖只要一个说明文件就能被 Agent 识别。 在真正的项目中单文件 Skill 适合那些“只需要告诉模型怎么做不需要真写代码”的场景。比如给 Agent 教一个公司内部的代码规范或者教一个固定的回答话术都可以只写一个 SKILL.md让模型把规则当成记忆来用。 ### 4.2 案例 2脚本型 Skill让技能真正执行代码 只靠说明文件的技能是“纸上的技能”真正干活还需要脚本。为同一个 current_time Skill 添加脚本 skills/current_time/scripts/current_time.py python import argparse from datetime import datetime from zoneinfo import ZoneInfo def main(): parser argparse.ArgumentParser(description获取指定时区的当前时间) parser.add_argument(--timezone, defaultUTC, help时区名称例如 Asia/Shanghai) args parser.parse_args() now datetime.now(ZoneInfo(args.timezone)) print(now.isoformat()) if __name__ __main__: main()这段代码本身不难重点是它体现了一个原则Skill 脚本应该尽量做成“独立可执行的小工具”输入输出都通过命令行参数和标准输出传递。Agent 调用 Skill 时本质上就是执行这个命令行程序再把输出喂回模型。保持脚本独立、接口简单是 Agent Skills 架构里非常关键的设计约束。4.3 案例 3带依赖的 Skill用 requirements.txt 管理环境当 Skill 需要第三方库时就可以在 Skill 目录里加一个requirements.txt。假设我们做一个 PDF 文本提取技能# skills/pdf_extract/requirements.txt pypdf4.2.0SKILL.md里的使用说明也相应更新--- name: pdf_extract description: 从 PDF 文件中提取纯文本内容。 when_to_use: 用户提供 PDF 文件路径并要求提取文本、做摘要或搜索内容时使用。 --- # PDF 文本提取 先确认依赖 bash pip install -r requirements.txt然后执行python scripts/extract.py --file_path /path/to/file.pdf输出为纯文本按页分隔。这里要提醒一个工程细节不要把项目主环境的依赖和 Skill 的依赖混为一谈。Skill 是独立交付单元它的依赖应该在自己的目录里声明。生产环境通常会给 Skill 建立独立虚拟环境或容器防止多个 Skill 之间出现依赖冲突。 ### 4.4 案例 4把 Skill 注册进 LangChain Agent 前面 3 个案例都在做 Skill 本身现在让 Agent 真正用起来。下面这段代码是核心的加载与注册逻辑以直观的流程演示为主API 名称以你实际安装版本为准 python from langchain.agents import create_agent from langchain_openai import ChatOpenAI # 假设这是 Agent Skills 扩展包提供的加载函数 from langchain_agent_skills import load_skills # 1. 配置模型 model ChatOpenAI(modelgpt-4o-mini, temperature0) # 2. 扫描 skills 目录 skills load_skills(./skills) print(已加载技能) for skill in skills: print(f- {skill.name}: {skill.description}) # 3. 创建 Agent 并绑定技能 agent create_agent( modelmodel, skillsskills, ) result agent.invoke({input: 现在上海几点}) print(result[output])如果你的版本中create_agent不可用也可以使用 LangGraph 的create_react_agentfrom langgraph.prebuilt import create_react_agent agent create_react_agent( modelmodel, toolsskills_to_tools(skills), # 把 Skill 转换成工具列表 )运行后Agent 会根据用户问题自动匹配current_time技能并执行对应脚本。这一步成功意味着你已经跑通了“扫描 Skill → 注册到 Agent → 模型自主调用”的完整闭环。5. 第二组案例Skill 组合与编排案例 5-85.1 案例 5多 Skill 自动路由实际项目中不可能只有一个技能。假设系统里同时存在current_time和weather_query两个技能Agent 该如何决定调用哪一个答案就在SKILL.md的description和when_to_use里。模型拿到用户问题后会把问题语义和所有技能的描述做匹配。我们来对比两组描述写得模糊的description: 查询时间和天气相关的内容。写得清晰的description: 根据城市名查询实时天气、温度、湿度。 when_to_use: 用户询问“天气”“温度”“下雨”“出门要不要带伞”时使用。同一句话第二种描述能让模型做路由时的准确率显著提升。很多新手以为 Agent 不调用 Skill 是模型问题其实大多数时候是技能描述写得太差模型根本不知道这个技能是干什么的。把描述写清楚等于给模型画了一张“能力地图”。5.2 案例 6Skill 与内置 Tool 混用Agent 不一定只能使用 Skill也可以同时挂载 LangChain 内置的工具。比如一个支持联网搜索的工具和一个公司内部查询技能共存from langchain_community.tools.tavily_search import TavilySearchResults search_tool TavilySearchResults(max_results3) agent create_agent( modelmodel, skillsload_skills(./skills), additional_tools[search_tool], )这里需要注意优先级边界Skill 更适合“流程稳定、输入输出明确”的内部能力比如查数据库、跑报表、执行固定脚本Tool 更适合“通用性高、结果不可控”的外部能力比如联网搜索、调用开放 API。建议在 Skill 的描述里显式说明“什么时候不要用本技能”引导模型优先使用其他更合适的工具避免内部查询技能被网络检索能力抢走流量或者反过来让模型在应该查内部数据时去网上乱搜。5.3 案例 7带记忆的 Skill多轮对话中的状态保持默认情况下Agent 是无状态的每次调用 Skill 都是一次独立执行。如果希望 Agent 在多轮对话中记住“用户刚才的城市是上海”就需要引入记忆能力。在 LangGraph 生态中最推荐的方案是使用 Checkpointer 保存每轮状态from langgraph.checkpoint.memory import MemorySaver from langgraph.prebuilt import create_react_agent memory MemorySaver() agent create_react_agent( modelmodel, toolsskills_to_tools(load_skills(./skills)), checkpointermemory, ) config {configurable: {thread_id: user-session-001}} result agent.invoke( {messages: [{role: user, content: 查一下上海明天的天气}]}, configconfig, )用户下一轮说“那后天呢”Agent 会从thread_id对应的会话状态里读取出“城市是上海”这一上下文继续调用同一个天气技能而不需要用户重新说明城市。对于需要多轮追问、分步执行的业务场景把 Skill 的状态类变量放入 LangGraph 的 State比在 Skill 脚本内部维护全局变量可靠得多。5.4 案例 8Skill 嵌套编排复杂任务拆成子技能当任务足够复杂时可以让一个“编排型 Skill”去调度多个“执行型 Skill”。举个实际例子做一个“竞品分析报表”技能它内部可以拆成三个子技能fetch_competitor_info抓取竞品公开信息。analyze_price分析价格区间。generate_report生成 Markdown 报表。编排型 Skill 的SKILL.md这样描述--- name: competitor_report description: 生成竞品分析日报需要依次调用抓取、分析和生成三个子流程。 when_to_use: 用户要求生成竞品分析、价格对比报告时使用。 --- 执行流程 1. 调用 fetch_competitor_info 获取竞品列表。 2. 调用 analyze_price 分析价格。 3. 调用 generate_report 汇总输出。这种嵌套结构对应的是“分层式 Agent 架构”上层 Skill 负责流程编排下层 Skill 负责单点执行。好处是每个子技能都可以单独测试、单独复用坏处是调用链变长调试时要从顶层往下逐层排查。建议嵌套层级不要超过三层否则延迟和失败率都会明显上升日志追踪也会变得复杂。6. 第三组案例工程化与业务落地案例 9-126.1 案例 9知识库问答 Skill把 RAG 封装成技能RAG检索增强生成是企业落地最常用的方案。可以把整套 RAG 流程封装成一个 Skill让 Agent 对外表现为“懂公司内部知识”的助手。Skill 目录结构这样设计skills/company_qa/ ├── SKILL.md ├── requirements.txt └── scripts/ ├── build_index.py └── query_index.pySKILL.md的关键内容是--- name: company_qa description: 基于公司内部知识库回答员工问题。 when_to_use: 用户询问公司制度、内部流程、产品文档相关问题时使用。 --- 1. 若向量索引不存在先运行 build_index.py 构建索引。 2. 执行 query_index.py传入 question 参数。 bash python scripts/query_index.py --question 年假怎么申请这里有一个容易踩的坑不要让每个用户问题都触发一次全量建索引。正确做法是把索引构建做成独立任务定时在后台运行query_index.py 只负责检索。技能脚本应该尽量“无状态化”把耗时操作前置把查询操作做得轻量。 ### 6.2 案例 10数据清洗 Skill让 Agent 处理表格数据 业务人员经常希望 Agent 能直接处理 Excel、CSV。可以把 Pandas 清洗逻辑封装成技能 python # skills/data_clean/scripts/clean.py import argparse import pandas as pd def main(): parser argparse.ArgumentParser() parser.add_argument(--input, requiredTrue, help输入文件路径) parser.add_argument(--output, requiredTrue, help输出文件路径) args parser.parse_args() df pd.read_csv(args.input) # 去除完全重复的行 df df.drop_duplicates() # 去掉全空列 df df.dropna(axis1, howall) # 日期列标准化 if date in df.columns: df[date] pd.to_datetime(df[date], errorscoerce) df.to_csv(args.output, indexFalse) print(f清洗完成输出行数: {len(df)}) if __name__ __main__: main()这里必须强调一个安全红线涉及数据修改和数据落盘的操作应该在测试环境先验证备份原始文件后再执行并且只授予该 Skill 最小必要权限。不要让 Agent 直接对生产库执行没有 WHERE 条件的更新或删除语句。如果业务确实需要写数据库建议 Skill 内部只允许调用封装好的、带审计的写入接口。6.3 案例 11Skill 封装 MCP 工具连接外部系统MCPModel Context Protocol已经逐渐成为连接 AI 应用和外部系统的标准协议。Skill 可以作为一个“适配层”把 MCP 服务的能力封装成更符合业务语义的技能。比如公司内部有一个通过 MCP 暴露的“工单系统”你可以写一个create_ticket技能在SKILL.md中说明“当用户需要提交工单时调用”脚本内部再去调用 MCP 客户端完成工单创建。Skill 是骨架MCP 是插头。这句话的意思是MCP 解决了“连接标准”的问题但模型并不知道什么时候该连哪个服务。Skill 补上的正是这一层语义判断它告诉模型“什么场景下该用这个接口”并把 MCP 返回的结果整理成模型容易理解的格式。接口对接工作被收敛到 Skill 内部上层 Agent 的复杂度不会随着接入系统数量增加而膨胀。6.4 案例 12多模型、多供应商切换生产环境经常需要根据成本、延迟、效果切换模型。Agent Skills 架构下可以在 Skill 的配置里声明“推荐模型”或“对模型能力的要求”再由运行时统一路由。下面是一个示意配置# skills/doc_generator/SKILL.yaml name: doc_generator description: 生成技术方案文档 preferred_model: gpt-4o fallback_model: gpt-4o-mini运行时可以设计一个简单的路由策略根据 Skill 配置的preferred_model选择模型如果该模型服务不可用或超时再切换到fallback_model。多模型切换的关键不是“在代码里写死模型名”而是把模型选择变成一种配置驱动策略。这样业务上线时可以针对不同技能快速做 A/B 测试根据效果和成本动态调整。7. 常见问题与排查思路问题现象常见原因解决思路Agent 始终不调用某个 SkillSKILL.md 描述不明确模型无法匹配重写 description 和 when_to_use明确输入触发条件Skill 被误调用多个技能职责重叠、边界模糊收敛职责范围在描述中补充“什么时候不要用”Skill 脚本报错导致对话中断脚本缺少异常处理输出非结构化在脚本中捕获异常输出统一错误格式多轮对话中 Skill 记忆丢失未配置 Checkpointer会话状态没保存接入 memory并在调用时传 thread_id多个 Skill 依赖版本冲突依赖混在主环境里为 Skill 建立独立虚拟环境或容器隔离升级 LangChain 后代码报错版本迭代API 变更查看 changelog 和官方文档按新 API 调整模型调用 Skill 时参数传错SKILL.md 使用说明不够详细在使用说明中给出完整命令示例和参数解释再展开说一个最常见的问题Agent 不调用 Skill。排查时可以按下面这个顺序走一遍确认 Skill 是否真的被加载启动日志里有没有打印出 Skill 列表。打印模型实际拿到的工具或技能描述看格式是否完整。用最简单的用户问题测试排除复杂意图干扰。逐步调整SKILL.md的description观察调用命中率变化。很多时候问题不在 agent 本身而是技能描述还不够“直白”。模型是概率推理描述写得越接近用户习惯的提问方式命中率越高。8. 最佳实践与工程建议8.1 描述即调度先花时间写 SKILL.md一个 Skill 的价值有一半在SKILL.md里。写的时候把用户可能怎么问、在什么场景下触发、参数怎么填、输出怎么解析都写清楚模型才能正确调度。不要给两个技能写相似的描述职责边界越清晰调度准确率越高。8.2 输出结构化让结果可被二次加工Skill 脚本的输出不要只是打印一堆人话尽量输出 JSON让模型可以直接读取关键字段二次加工import json result {city: 上海, temperature: 28, unit: celsius} print(json.dumps(result, ensure_asciiFalse))结构化输出能显著减少模型“翻译”脚本结果的误差也方便在 LangSmith 里追踪结构化数据。8.3 安全与权限最小化这是生产落地最不能省的一步SKILL.md 和脚本里不要硬编码 API Key、数据库密码一律通过环境变量或密钥管理服务注入。Skill 如果涉及执行 Shell 命令必须做命令白名单禁止拼接未过滤的用户输入直接执行。涉及数据库写操作、文件删除、生产环境变更时必须先在小范围测试环境验证做好备份并保留操作审计日志。给不同 Skill 分配不同的服务账号遵循最小权限原则避免一个技能越权访问其他系统。8.4 可观测性建设生产环境一定要把 Skill 的调用过程记录下来哪个用户的问题触发了哪个 Skill、调用耗时多少、传了什么参数、返回了什么结果、消耗了多少 token。用 LangSmith 或者自定义日志都能实现。只有数据可回溯你才能持续优化技能描述和调度策略而不是靠感觉调参。8.5 按场景选择 Agent 架构简单单步任务用工具调用式的 Agent直接绑定 Skill 列表够用且快。复杂多步任务用 LangGraph 分层编排把流程节点和 Skill 组合起来。多专家协作场景可以考虑“黑板模型”思想多个 Skill 分别处理不同类型的信息共享一个会话状态由主 Agent 汇总决策。架构没有银弹选择标准只有一个当前任务的复杂度和失败成本。能用简单方案解决的不要一上来就上重型图编排否则维护成本会反过来吃掉开发效率。9. 总结与学习路线9.1 本文核心收获读到这里你应该已经掌握了几件事Agent Skills 到底是什么、它和 Tool、MCP、LangGraph 有什么区别与联系、一个标准 Skill 目录应该怎么组织、12 个递进案例分别解决了什么场景问题。这些都是可以直接迁移到实际项目里的架构经验。9.2 后续学习路线如果你是从零开始建议按下面的路线继续深入先把案例 1 到 4 抄一遍把 Skill 加载流程跑通。再结合 LangGraph 的 State 和 Checkpointer理解有状态编排。然后引入 RAG 和 MCP把企业知识库、外部系统接进来。最后完善可观测性和安全治理把项目推到生产环境。9.3 动手建议不要只看不练。建议直接拿一个你手头最痛的业务场景练手比如“把周报生成流程封装成一个 Skill”或者“把内部文档问答封装成技能”。遇到问题优先看官方文档和 changelog因为 Agent Skills 相关能力还在快速演进网上资料很容易过时。这篇内容如果对你有帮助建议收藏备用。后续我也会持续关注 LangChain 生态的更新把新特性、新坑点和大家同步。