Langchain Agent Skills 机制详解:12个案例教你构建可复用技能包
2026/8/31 2:48:48 网站建设 项目流程

Langchain 最近更新的 Agent Skills 机制,值得所有做 Agent 应用的人重新看一遍。它不是又加了一个 API,而是把“写死工具列表 + 写死 Prompt”那套玩法,升级成了“给 Agent 一个技能包,让它自己决定怎么用”。这个转变,对开发方式的冲击比想象中更大。

先说判断:Agent Skills 真正解决的问题,是 Agent 应用里最头疼的“组合爆炸”。以前每增加一个能力,你要改 system prompt、改工具注册表、改任务路由逻辑,功能越多代码越碎。现在官方把这层抽象成了 Skills 架构,Agent 自身负责调用、编排和决策,开发者只需要把“技能”描述清楚。这意味着,写 Agent 的姿势正在从“写程序”变成“写说明书 + 配技能包”。

这篇文章会用 12 个实际案例,带你拆解这套架构到底是什么,能解决什么问题,有哪些坑。内容偏实操,建议边读边试。

1. 为什么 Agent Skills 突然火起来了

先说背景。Langchain 在 Agent 方向已经迭代了很多版本,从最早期单纯的 Chain 串联,到后来引入 ReAct、Plan-and-Execute 等多种 Agent 范式,再到 Langgraph 做图状态编排。能力在变强,但开发者始终面临同一个尴尬:构建一个稍微像样的 Agent,要把 Prompt 工程、工具定义、记忆策略、路由逻辑全部揉在一起。

没有 Agent Skills 时,你想让 Agent 具备“数据库查询”的能力,通常要经历这些步骤:

  1. 在 system prompt 里描述数据库有哪些表、字段含义。
  2. 写几个 Tool 函数,比如query_dbget_schema,注册到 Agent 的工具列表。
  3. 处理 Tool 返回的原始结果,再拼装成自然语言。
  4. 如果数据库类型变了,或者换了业务场景,又得重新调 prompt 和工具参数。

这个过程不难,但非常琐碎。问题在于:Agent 的核心价值是自主决策,但开发者却在替它把每一步都规定死。

Agent Skills 的思路是:把一组相关的指令、工具、模板、校验逻辑打包成一个“技能”。Agent 收到用户请求后,自己判断需要哪些技能,再加载这个技能的上下文和工具来执行。

用生活中的类比来理解:传统开发方式是你请了一个员工,然后给他一本极其详细的 SOP,每一步都写清楚。Agent Skills 的方式是,你告诉员工“你具备数据分析、报告生成、可视化三种能力”,具体怎么组合完成目标,员工自己决定。

这个转变真正解决的是Agent 能力的标准化封装与复用。技能包可以在不同 Agent 之间共享,可以在社区分发,也可以按场景组合。

2. 核心概念:Agent、Tool、Skill 的区别

开始写案例之前,必须先厘清三组概念,否则后面容易混。

2.1 Tool 与 Skill 的关系

Tool(工具)是 Agent 可以直接调用的函数,通常是独立、原子性的,比如“执行 SQL”“调用天气 API”“计算两个日期差值”。

Skill(技能)是一个更高层的抽象,它将多个工具、指令模板、上下文说明、验证逻辑组合在一起。你可以理解为:

Tool = 一个会做某件事的函数 Skill = 一套完成某类任务的能力包(包含工具、规则、步骤、校验和常见错误处理)

一个 Skill 内部可以包含多个 Tool。Skill 不只是工具的集合,还包括如何使用这些工具的知识。比如“生成数据分析报告”这个技能,里面要有数据库查询工具、Markdown 模板、图表生成工具,还要有告诉模型“先了解表结构、再写查询、最后生成结论”的指令。

2.2 Skill 与 Prompt 的关系

很多人会问:这不就是把 Prompt 写长一点吗?

区别在于:Skill 不只是 Prompt 文本,它附带了可执行的工具定义、输入输出约束、验证逻辑、示例数据。Prompt 只影响模型“怎么想”,Skill 还决定了模型“能做什么”。换个角度说,Prompt 是给模型的提示,Skill 是给 Agent 的完整能力模块。

2.3 Langchain 与 Langgraph 的定位差异

Langchain 是构建 Agent 应用的综合框架,提供了模型接入、Prompt 管理、Tool 封装、RAG、记忆等能力。Langgraph 专注于状态化、可编排的 Agent 工作流,适用于需要多轮状态管理、条件跳转、复杂分支的 Agent。

Agent Skills 不是一个独立的框架,而是 Langchain 层面的能力抽象。它和 Langgraph 的关系是:Langgraph 负责编排 Agent 的整体流程,Skills 负责定义 Agent 在某一步调用的具体能力。

做一个简单的对比表:

维度ToolSkillLanggraph 节点
粒度最小可调用单元一组能力的封装工作流中的一个执行步骤
是否包含指令否,只有函数逻辑是,包含指令和使用说明否,包含状态转移逻辑
典型例子查询天气的函数完整的数据分析技能包对话管理、任务分发节点

理解到这层,后面的 12 个案例才看得明白。

3. Agent Skills 的整体架构

先看架构层面。一个完整的 Agent Skills 方案,通常由 5 个层次组成:

  1. 模型层:底层大语言模型,负责理解用户请求、调用技能、生成回复。
  2. 技能注册层:维护一个技能清单,记录每个技能的 ID、名称、描述、所需工具、适用场景。
  3. 技能加载层:根据用户输入动态选择技能,并将技能内的指令模板、工具定义注入模型上下文。
  4. 工具执行层:实际执行技能内部的工具调用,完成数据获取、参数计算等操作。
  5. 校验与反馈层:校验执行结果是否符合预期,出错时负责重试或降级。

在 Langchain 中,一个 Agent Skill 的典型设计包括以下部分:

  • name:技能名称,如data_analysis_skill
  • description:技能描述,Agent 根据描述决定是否使用该技能
  • instructions:如何使用该技能的指令,注入 system prompt
  • tools:技能执行时用到的工具列表
  • templates:输入输出模板
  • validators:参数或输出校验器

用户的请求进来后,Agent 会先判断需要哪些技能,然后按需加载。

3.1 架构上的变化:从“代码驱动”到“声明式驱动”

过去你用 Langchain 构建 Agent,核心代码是:

agent = create_react_agent(llm, tools=[tool1, tool2, tool3])

所有工具对 Agent 来说都是平铺的,Agent 只能根据描述自行选择。一旦工具多了,模型容易选错工具,或者不知道该先用哪个。

有了 Agent Skills 后,架构变成:

agent = create_agent_with_skills(llm, skills=[skill_a, skill_b])

Agent 先选择技能,再在技能范围内选择工具。这相当于把“工具选择空间”先缩小到“技能选择空间”,再在技能内部执行工具,显著降低了模型决策难度。

3.2 为什么说这套架构是分水岭

传统 Agent 是“模型 + 工具 + 提示词”的三明治结构,所有逻辑都暴露在开发者的代码里。而 Skills 架构把任务能力从主流程中抽离,变成了可插拔的模块。

这带来三个直接好处:

  1. 复用性提升:一个“数据分析技能”可以在客服 Agent、运营 Agent、研发辅助 Agent 中复用。
  2. 维护成本下降:修改某个技能内部逻辑时,不需要动主 Agent 代码。
  3. 协作边界清晰:擅长 Prompt 的成员负责写技能指令,擅长工程的同学负责写技能内部工具,互不阻塞。

4. 环境准备与前置条件

进入实操前先准备好环境。以下步骤主要针对 Langchain 的新版本,具体版本号以你实际安装为准。

4.1 创建 Python 虚拟环境

python -m venv agent_skills_env source agent_skills_env/bin/activate # Windows 系统使用 agent_skills_env\Scripts\activate

4.2 安装 Langchain

pip install --upgrade langchain langchain-openai langchain-core

如果你需要用到 Langgraph 来做复杂的 Agent 编排,再安装:

pip install langgraph

4.3 准备模型 API Key

本文中的示例以 OpenAI 兼容接口为例。你可以在环境变量中配置:

export OPENAI_API_KEY="your-api-key"

如果你的模型服务不是 OpenAI,而是国内大模型平台或其他兼容接口,只需要替换 Langchain 中的模型实例即可,案例的 Agent Skills 逻辑是通用的。

4.4 验证环境是否正常

python -c "import langchain; print(langchain.__version__)"

打印出版本号说明安装成功。接下来我们进入案例环节。

5. 12 个案例拆解:从入门到进阶

接下来是全文最核心的部分。12 个案例按难度递增排列,从最简单的最小技能,到复杂的数据分析、多 Agent 协同、工具类技能组合。建议每个案例都自己跑一遍,再修改参数测试效果。

案例 1:定义一个最基础的 Skill

以“代码注释生成器”为例,演示如何定义一个最小可用的 Skill。

from langchain_core.tools import tool from langchain_core.language_models.chat_models import BaseChatModel from langchain_openai import ChatOpenAI from langchain.agents import create_agent @tool def get_function_code(func_name: str) -> str: """根据函数名称获取项目中该函数的源代码。""" # 实际项目中这里会从代码仓库读取 return """ def add(a, b): return a + b """ code_comment_skill = { "name": "code_comment_generator", "description": "为指定函数生成注释,输入为函数名,输出为带注释的代码。", "instructions": """ 当用户要求为函数生成注释时: 1. 使用 get_function_code 获取函数源代码。 2. 分析函数逻辑。 3. 在函数定义的下一行插入功能说明、参数说明、返回值说明。 """, "tools": [get_function_code], } llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) # 将技能中的 tools 平铺给 agent,并将 instructions 注入 system prompt agent = create_agent(llm, tools=[get_function_code], system_prompt=code_comment_skill["instructions"]) response = agent.invoke({"input": "请为 add 函数生成注释"}) print(response["output"])

这个案例有三个关键点:

  1. Skill 是 Python 字典对象,最重要的是descriptioninstructionsdescription用于 Agent 判断何时使用该技能,instructions是技能内部的使用方法。
  2. 本例没有用官方的“技能注册/加载”高级 API,而是先把技能手动平铺到 agent 中。目的是让你理解技能的本质,不是魔法,而是“指令 + 工具 + 逻辑的组合”。
  3. 输出结果时,模型会根据 instructions 中的步骤顺序执行,先拿代码,再写注释。

案例 2:多工具组合技能

单个工具太简单,真实场景往往需要多个工具配合。以“项目周报生成”为例,这个技能需要两个工具:获取 Git 提交记录、获取需求列表。

from langchain_core.tools import tool from datetime import datetime, timedelta @tool def get_git_commits(repo_path: str) -> str: """获取指定仓库最近一个工作日的 git 提交记录。""" # 真实场景中会执行 git log 命令 return "feat: 添加登录功能\nfix: 修复订单超时问题\nrefactor: 重构用户模块" @tool def get_task_list(project_id: str) -> str: """获取指定项目的任务完成情况。""" return "已完成: 3个任务\n进行中: 2个任务\n待开始: 1个任务" week_report_skill = { "name": "weekly_report", "description": "根据 git 提交记录和项目任务列表,生成周报。", "instructions": """ 生成周报时: 1. 先调用 get_git_commits 获取代码提交记录。 2. 再调用 get_task_list 获取任务完成情况。 3. 将两者组织成周报格式:本周完成 / 存在问题 / 下周计划。 """, "tools": [get_git_commits, get_task_list], } agent = create_agent( llm, tools=[get_git_commits, get_task_list], system_prompt=week_report_skill["instructions"], ) response = agent.invoke({"input": "生成项目 PROJ-1001 的本周周报"}) print(response["output"])

这个案例想说明的是:技能内部可以有多个工具,且工具之间通常有执行顺序。在这个设计里,指令模板就是告诉模型“你先查代码,再查需求,最后汇总”。相比让模型自己摸索顺序,这种显式规定成功率更高。

案例 3:带输入校验的 Skill

实际生产中,技能参数经常会被传错。比如用户让 Agent“查询上周的数据”,但技能只支持“按日期查”。如果没有校验机制,Agent 会拿一个模糊的时间范围去调工具,然后返回一堆脏数据。

我们可以在技能中加入参数校验逻辑:

from pydantic import BaseModel, Field class DateQueryInput(BaseModel): start_date: str = Field(description="开始日期,格式 YYYY-MM-DD") end_date: str = Field(description="结束日期,格式 YYYY-MM-DD") @tool(args_schema=DateQueryInput) def query_sales(start_date: str, end_date: str) -> str: """查询指定日期范围内的销售数据。""" # 模拟查询结果 return f"销售数据: {start_date} 至 {end_date}, 总销售额 100000 元" data_query_skill = { "name": "sales_query", "description": "查询销售数据,只支持按日期范围查询。", "instructions": """ 当用户查询销售数据时: 1. 必须先确认开始日期和结束日期。 2. 如果用户没有提供日期,询问用户。 3. 日期格式必须是 YYYY-MM-DD。 """, "tools": [query_sales], }

这个案例的价值点是:args_schema让工具具备结构化的参数约束。模型在调用工具之前,会先按 Pydantic 模型校验参数。参数不对时,Langchain 会要求模型重新生成符合要求的参数。

实际开发中,不要偷懒省掉参数校验。AI 生成的内容再聪明,也可能出现错误格式。

案例 4:使用模板引擎生成结构化输出

很多技能的输出需要固定格式,比如 JSON、Markdown、HTML。只靠模型“自觉”遵守格式会不稳定,比较可靠的做法是给它一个模板,让它“填空式”输出。

下面这个案例是“生成数据库表设计文档”:

table_doc_template = """ ## 表名: {table_name} ### 字段说明 | 字段名 | 类型 | 是否必填 | 说明 | | --- | --- | --- | --- | {field_rows} ### 索引设计 {index_rows} ### 备注 {notes} """ @tool def get_table_meta(table_name: str) -> str: """获取数据库表结构元数据。""" return [ {"field": "id", "type": "bigint", "nullable": "否", "comment": "主键"}, {"field": "name", "type": "varchar(64)", "nullable": "否", "comment": "用户名"}, ] table_doc_skill = { "name": "table_doc_generator", "description": "根据表名生成数据库表结构说明文档。", "instructions": """ 1. 使用 get_table_meta 工具获取表结构元数据。 2. 将元数据填充到 table_doc_template 模板中。 3. 最终输出完整的 Markdown 文档。 """, "tools": [get_table_meta], }

模板方式的核心价值是减少生成式输出的不确定性。只要模板约束了结构,模型输出的部分就只有内容,格式是稳定可控的。如果你正在做报表、合同、代码生成、API 文档等场景,建议都采用模板方案。

案例 5:带记忆的 Skill

Agent 的上下文记忆问题,一直是被问得最多的问题之一。Langchain 中记忆组件五花八门,但在技能架构里,记忆应该如何设计?

推荐的做法是:把记忆设计成技能内部的一个工具,而不是全局的一团状态。

from langchain_core.tools import tool memory_store = {} @tool def save_note(key: str, content: str) -> str: """保存一条笔记到长期记忆。""" memory_store[key] = content return "已保存" @tool def get_note(key: str) -> str: """读取指定键的笔记。""" return memory_store.get(key, "未找到相关笔记") note_skill = { "name": "meeting_memory", "description": "记录会议中的关键结论和待办事项,并在后续对话中调用。", "instructions": """ 当用户提到会议、结论、待办事项时: 1. 如果是第一次提到,使用 save_note 保存。 2. 如果用户后续询问,使用 get_note 查询。 3. 注意区分不同会议,key 建议使用 会议名称_日期。 """, "tools": [save_note, get_note], }

这里的关键是:记忆不再是黑盒,而是显式的“保存”和“读取”工具。这有 3 个好处:

  1. Agent 知道自己在什么时候“记住了东西”,什么时候该“调用记忆”。
  2. 调试容易,你可以直接查看 memory_store 里的内容。
  3. 后续可以无缝替换成 Redis、向量数据库,只需要改工具内部实现。

案例 6:数据分析类技能(多步骤编排)

数据分析是 Agent 场景里最常见的需求之一。一个完整的数据分析技能,至少包含以下步骤:

  1. 获取数据表结构。
  2. 生成 SQL 并执行。
  3. 对结果做聚合计算。
  4. 输出分析结论。

用一个简化示例展示:

from langchain_core.tools import tool @tool def get_schema() -> str: """获取数据库所有表的结构。""" return """ table: orders columns: order_id, customer_id, amount, created_at table: customers columns: customer_id, name, city """ @tool def run_sql(sql: str) -> str: """执行 SQL 查询,只允许 SELECT 语句。""" # 生产环境需要严格校验 SQL,防止注入 return "北京, 1500\n上海, 1200\n广州, 900" analysis_skill = { "name": "sales_analysis", "description": "分析销售数据,输出结论和趋势。", "instructions": """ 数据分析步骤: 1. 先调用 get_schema 了解表结构。 2. 根据用户问题编写 SQL,关键:只允许 SELECT。 3. 调用 run_sql 执行查询。 4. 根据结果总结趋势、指出异常,最后给出建议。 """, "tools": [get_schema, run_sql], }

这个案例真正体现了 Agent 结合技能和执行能力的价值。模型负责拆解问题、编写 SQL、解读结果;工具负责真实的数据访问。你自己看数据可能半天才能得出结论,Agent 在几秒内就能输出一份包含结论的回复。实际项目中,需要注意的地方是 run_sql 的实现必须要做安全过滤,不能让模型拼接出DROP TABLE这类危险语句。

案例 7:RAG 检索问答技能

Langchain 最经典的场景之一就是 RAG。把 RAG 做成技能,好处是可以针对不同知识库配置不同的检索策略。

from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings from langchain_core.tools import tool # 假设已有一个向量数据库 vectorstore = FAISS.load_local("faiss_index", OpenAIEmbeddings(), allow_dangerous_deserialization=True) retriever = vectorstore.as_retriever(search_kwargs={"k": 4}) @tool def search_docs(query: str) -> list: """在知识库中检索与问题相关的内容。""" docs = retriever.invoke(query) return [doc.page_content for doc in docs] rag_skill = { "name": "internal_docs_qa", "description": "基于内部知识库回答员工问题,适用于制度、流程、产品文档。", "instructions": """ 当用户询问内部制度或流程时: 1. 调用 search_docs 检索相关文档片段。 2. 优先基于检索内容回答,不要编造。 3. 如果检索内容不足以回答,告诉用户“该问题暂未找到相关信息”。 """, "tools": [search_docs], }

这个技能值得注意的地方是第 3 条指令。如果不加这条,模型很容易在检索不到信息时强行编造答案。加上了,就引导模型保守回答。做企业知识库问答时,这几乎是必须的设计。

案例 8:代码生成 + 自动执行技能

代码类 Agent 很受欢迎,但实际使用中最怕代码生成错误、运行报错。可以把代码生成、执行、报错修复三个步骤封装在一个技能中。

import subprocess @tool def write_and_run_code(code: str) -> str: """将生成的 Python 代码保存并运行,返回执行结果或报错信息。""" with open("generated_code.py", "w", encoding="utf-8") as f: f.write(code) result = subprocess.run( ["python", "generated_code.py"], capture_output=True, text=True, timeout=30, ) if result.returncode == 0: return f"运行成功:\n{result.stdout}" return f"运行失败:\n{result.stderr}" coding_skill = { "name": "python_coder", "description": "编写并运行 Python 代码,帮助用户解决编程问题。", "instructions": """ 1. 根据用户需求编写完整 Python 代码。 2. 调用 write_and_run_code 执行代码。 3. 如果执行失败,根据报错信息修改代码后再次运行。 4. 最终将运行结果反馈给用户。 """, "tools": [write_and_run_code], }

这个技能模式下,Agent 成为一个简单的“自动编程执行器”。测试环境可以这么玩,但生产环境要非常谨慎,因为让模型直接执行生成的代码有安全风险。只建议在沙箱环境、测试环境中开启。

案例 9:工作流路由技能

一个复杂的 Agent,往往内部有多个技能。技能之间不是相互独立的,而是根据用户意图做路由分发。

用“需求分析助手”举例,它既能写 PRD,也能面 SQL,还能生成原型描述。路由怎样做?

@tool def route_request(query: str) -> str: """判断用户请求属于哪个技能。""" if "prd" in query.lower() or "需求文档" in query: return "write_prd" elif "sql" in query.lower() or "数据库" in query: return "write_sql" else: return "unknown" router_skill = { "name": "request_router", "description": "将用户请求路由到合适的技能。", "instructions": """ 当用户提出需求时: 1. 先调用 route_request 判断属于哪个技能。 2. 如果路由结果是 write_prd,调用 write_prd_skill。 3. 如果路由结果是 write_sql,调用 write_sql_skill。 """, "tools": [route_request], }

这个路由方案在实现上还可以升级为向量相似度匹配。把每个技能的描述向量化,用户输入进来后用余弦相似度找最合适的技能。Langchain 里可以用VectorStoreToolkit做类似的事。

案例 10:组合式技能:一个技能调用另一个技能

高级场景下,技能之间也需要协作。比如“生成数据分析报告”技能内部,要调用“数据查询”技能和“图表生成”技能。

@tool def get_report_data(metric: str) -> str: """获取某个指标的数据序列。""" return f"{metric}: 10, 15, 23, 42, 56" @tool def generate_chart(data: str) -> str: """将数据序列转换为图表 Markdown 代码。""" images = ["![trend](chart1.png)"] return images[0] composite_skill = { "name": "data_report", "description": "生成一份完整的数据分析报告。", "instructions": """ 生成数据分析报告的步骤: 1. 使用 get_report_data 获取原始数据。 2. 使用 generate_chart 生成趋势图。 3. 综合数据和图表,输出 Markdown 格式的报告。 """, "tools": [get_report_data, generate_chart], }

这种设计把“查询数据”和“生成图表”拆成两个可复用的工具,但组合逻辑依然由 Agent 完成。如果你有很多报表需求,可以基于这个思路构建一个报表技能族。

案例 11:多 Agent 协同下的 Skills

规模再大一点,就需要 Langgraph 来编排多个 Agent,每个 Agent 拥有不同的 Skills。比如一个“项目复盘助手”系统:

  • 数据收集 Agent:拥有git_log_skilltask_query_skill
  • 分析 Agent:拥有metrics_calculation_skill
  • 报告生成 Agent:拥有report_template_skill

Langgraph 负责 Flow,每个节点是 Agent,每个 Agent 有自己的 Skills。

下面是一个极简示意:

from langgraph.graph import StateGraph class AgentState(dict): messages: list def collect_node(state): # 调用数据收集 Agent,内部使用 git_log_skill return state def analyze_node(state): # 调用分析 Agent,内部使用 metrics_calculation_skill return state def report_node(state): # 调用报告 Agent,内部使用 report_template_skill return state graph = StateGraph(AgentState) graph.add_node("collect", collect_node) graph.add_node("analyze", analyze_node) graph.add_node("report", report_node) graph.add_edge("collect", "analyze") graph.add_edge("analyze", "report") graph.set_entry_point("collect") graph.set_finish_point("report") app = graph.compile()

这个案例说明了一个重要架构判断:单 Agent + 单技能的思路只能做 Demo;生产中复杂任务,要靠 Langgraph 编排多个 Agent,每个 Agent 拥有专职技能。这样每个 Agent 的上下文更短、决策更准确,调试也更容易。

案例 12:对外发布一个可复用的技能包

最后一个案例,是把自己开发的技能做成可复用的包,分享给团队或社区。

Langchain 支持自定义工具和技能封装。一个典型技能包目录如下:

my_agent_skills/ ├── pyproject.toml ├── my_agent_skills/ │ ├── __init__.py │ ├── analysis_skill.py │ ├── report_skill.py │ └── utils.py └── examples/ └── demo.py

其中pyproject.toml声明依赖:

[project] name = "my-agent-skills" version = "0.1.0" dependencies = [ "langchain-core>=0.2", "langchain-openai>=0.1" ]

技能模块里,把 Skill 定义导出:

# my_agent_skills/analysis_skill.py from langchain_core.tools import tool @tool def analyze_text(text: str) -> dict: """分析文本的情感倾向和关键词。""" return { "sentiment": "positive", "keywords": ["高效", "稳定", "易用"], } analysis_skill = { "name": "text_analysis", "description": "分析用户文本的关键词和情感。", "instructions": "当用户请求分析文本时,使用 analyze_text 工具。", "tools": [analyze_text], }

团队成员可以直接引用这个模块:

from my_agent_skills.analysis_skill import analysis_skill

这个案例的核心价值是工程化。技能的封装和发布,最终会决定团队协作效率。规范接口、版本管理、依赖声明,都是实际落地中会让你少踩很多坑的细节。

6. 运行结果与效果验证

上面 12 个案例,每个都可以独立运行。但运行只是第一步,如何验证 Agent 真的“拥有”了技能,才是关键。

6.1 验证技能是否生效

最简单的验证方式是直接输入一个覆盖技能场景的问题:

response = agent.invoke({"input": "请分析项目 PROJ-1001 的周报"}) print(response["output"])

预期应该看到 Agent 按 Skill 中 instructions 规定的顺序执行工具:先获取 git 记录,再获取任务列表,最后输出周报。

6.2 调试手段

如果 Agent 没有按预期执行技能,建议做这几步检查:

  1. 查看模型原始调用链:Langchain 支持回调回调机制,通过LangSmithTracer或自定义BaseCallbackHandler来看每一步究竟调用了哪个工具。
  2. 检查系统提示词:确认system_prompt确实注入了技能的instructions
  3. 单测每个工具:直接用 Python 调用工具函数,看返回值是否符合预期。工具本身出错,Agent 再聪明也没用。
# 验证工具 print(get_git_commits.invoke({"repo_path": "/tmp/repo"}))

6.3 失败时的第一排查思路

如果技能完全没有被调用,优先检查技能的description是否清晰。description直接决定了模型是否会在正确场景触发该技能。

比如,"查询销售数据,只支持按日期范围查询"这样的描述,模型很容易理解。如果写成"sales_data_query_function",模型大概率不会触发。

7. 常见问题与排查思路

问题现象可能原因排查方式解决方案
Agent 不调用技能description 不清晰,或没有触发场景检查技能描述是否包含用户常见的说法重写 description,加入同义词和典型问法
工具参数传错args_schema 未定义,或定义过于宽泛查看 Langchain 日志中的 tool call 参数用 Pydantic 定义严格的参数模型
技能内部工具执行顺序混乱instructions 步骤不够明确在 instructions 中增加“先…再…最后…”显式规定工具调用顺序
模型回答与工具返回结果不符system prompt 和工具输出之间缺少衔接指令检查 tool 结果是否被截断加长工具返回的上下文,或让模型完整引用工具结果
并发执行时内存溢出技能内部缓存/store 设计不当查看进程内存占用将存储迁移到 Redis 等独立中间件
生产环境技能更新不生效技能代码被缓存检查 Agent 启动方式改为动态加载技能配置,支持热更新
工具执行报错,Agent 无法恢复缺少错误恢复指令观察重试次数在 instructions 中加入“如果工具报错,请尝试修复参数后重试,或告知用户失败原因”
数据泄露风险工具未做权限隔离审核工具对应的数据范围为不同场景配置独立的数据访问控制

8. 最佳实践与工程建议

8.1 技能拆分原则

一个技能不应该太大,也不应该太小。判断标准是:

  • 技能是否具备完整的目标闭环?
  • 技能是否可以被多个场景复用?
  • 技能内部工具是否高度内聚?

比如“生成数据分析报告”可以作为一个技能;但“查询数据库” + “生成图表” + “生成文字结论”如果拆成三个独立技能,会让 Agent 面对不必要的路由压力;如果硬放在一个技能里,复用性又差。

推荐的折中方案是:把“查询数据库”做成底层能力,把“生成图表”做成另一个底层能力,然后再封装一个“数据分析报告”组合技能。

8.2 指令模板设计建议

instructions时要避免模糊表述。看两个对比:

错误示范:

当用户查询数据时,你应该分析数据并给出答案。

正确示范:

当用户查询数据时: 1. 使用 get_schema 获取表结构。 2. 编写 SQL,校验 SQL 只包含 SELECT 关键字。 3. 调用 run_sql 执行查询。 4. 如果结果为空,告知用户“暂无数据”,不要凭空编造。 5. 输出结论时,列出关键数据指标。

Agent 对确定性步骤的执行成功率,远高于模糊指示。把步骤拆细,是成本最低也最有效的提升 Agent 性能的方法。

8.3 安全与权限控制

技能内部工具具有真实的执行能力,必须遵循最小权限原则:

  1. 数据库工具只开放 SELECT 或指定表,禁止 DDL、DML。
  2. 文件操作工具限制在指定目录内,防止路径穿越。
  3. 外部 API 调用需要在网关层限制域名和频次。
  4. 涉及隐私数据查询时,需要接入权限校验,不能让模型权限成为权限后门。

安全边界是 Agent 应用落地中最严肃的部分,不要因为“只是 Demo”而放松。

8.4 监控与日志

日志至少要覆盖:

  • 用户问题原文
  • Agent 选择了哪个技能
  • 技能内部调用了哪些工具
  • 工具执行结果摘要
  • 模型最终输出

这些日志不仅是调试的依据,也是你判断技能是否好用的数据来源。如果某个技能总是触发失败,从日志里能很快看出来。

8.5 多技能时的路由策略

技能数量超过 5 个后,一次把全部技能的描述都塞给模型,会拉长上下文,也会影响决策准确率。两种方案:

  1. 显式路由:先用一个小的分类器或关键词规则判断意图,再加载对应的技能包。
  2. 向量检索路由:将技能描述向量化,用户请求进来后用相似度匹配 TopN 技能。Langchain 的create_retriever_tool可以辅助实现。

在实战场景里,显式路由通常比完全依赖模型做技能选择更稳定。

8.6 版本管理与治理

技能也是代码。团队协作时要纳入版本管理,遵循以下规范:

  1. 一个技能一个目录,目录内包含描述文件、工具代码、测试用例。
  2. 技能变更走 MR 流程,附带变更说明。
  3. 对技能做版本标记,Agent 端固定引用指定版本,防止“昨天还能用,今天不行了”。

9. 对 Langchain 与 Langgraph 架构选型的建议

很多读者纠结:到底应该直接用 Langchain 的 Agent,还是用 Langgraph 自己编排?

谈谈判断标准:

  • 如果你的 Agent 只有 1 到 3 个技能,任务链路短,直接用 Langchain Agent + Skills 完全够用。
  • 如果你的 Agent 需要处理多轮状态、条件分支、人工审核、超时重试,使用 Langgraph 编排,把每个环节做成一个节点,技能放在各节点内部。

还要提一下 Langchain 和 Langgraph 的关系。Langgraph 更底层的定位是“Agent 工作流引擎”,Langchain 提供的是“构建 Agent 的组件库”。两者不是二选一,而是可以并存:Langgraph 做流程控制,Langchain 提供工具、技能、模型接入能力。

从当前 Langchain 的迭代趋势看,Agent Skills 正在成为核心抽象层。它解决的是 Agent 开发中最痛的问题:能力如何标准化?如何复用?如何治理?这也是这篇文章最想让你理解的点:Agent Skills 不是一个新功能,而是一套关于 Agent 能力组织方式的架构设计。沿着这个思路做下去,不只是使用一个框架的某个 API,而是在建立你自己的 Agent 工程化方法论。

10. 总结与后续学习方向

这 12 个案例从最小技能定义、工具组合、参数校验、模板输出,一直讲到多 Agent 协同和技能包发布。核心想传达的判断是:

Agent Skills 把“Agent 的能力”从一个抽象概念,变成了一个可定义、可组合、可复用、可治理的工程对象。有了这套抽象,开发 Agent 的方式会从“写死一切逻辑”变成“定义能力边界,让模型在边界内自主决策”。

建议你的下一步实践路径:

  1. 从案例 1 开始,先定义一个属于自己业务场景的最简技能。
  2. 跑通之后,逐步增加工具、校验、指令模板。
  3. 当你觉得技能变多了,再引入 Langgraph 做流程编排。
  4. 关注 Langchain 官方仓库中关于 Agent Skills 的更新,架构还在快速迭代。

如果想深入,优先看这几个方向:

  • Langchain 官方文档中 Agent 与 Tool 的部分。
  • Langgraph 教程里的多 Agent 协作例子。
  • Pydantic 官方文档,掌握参数校验工具。

收藏这篇文章,找个周末跑通前 5 个案例,你对 Agent Skills 的理解会超过大部分人。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询