当前位置: 首页
AI教程
LangChain技能框架开发实战指南

LangChain技能框架开发实战指南

热心网友 时间:2026-05-28
转载

在开发智能体(Agent)应用的过程中,一个关键挑战是如何让AI不仅具备调用工具的能力,更能掌握一套融合了专业领域知识的工作方法论。这正是“技能”(Skill)概念的价值所在。它超越了单一的工具函数,是一个集成了专业流程、知识指引和必要资源的完整能力包,旨在将零散信息转化为可执行的智能决策。

LangChain 实现 Skill 框架

一个设计良好的Skill通常包含以下几个核心组成部分,它们协同工作,确保专业知识的有效传递与执行:

  • SKILL.md文件:作为技能的核心文档与“大脑”,它包含两部分:
    • 头部元数据(YAML格式):其中name(技能名称)和description(技能描述)字段尤为关键。description相当于技能的“搜索引擎优化关键词”,智能体依赖它进行自动路由与匹配,因此描述必须精准且符合业务语境。
    • 主体内容(Markdown格式):详细阐述技能的使用方法、步骤和注意事项。其优势在于“按需加载”机制——仅在技能被触发时才会载入智能体上下文,有效避免了无关信息对核心推理过程的干扰。
  • 脚本目录 (scripts/):用于存放可执行的Python或Bash代码。这里适合放置对可靠性要求高或需要频繁复用的任务逻辑。最佳实践是采用“无状态+纯函数”的设计模式,这有助于提升代码的可测试性和复用性。
  • 参考资料目录 (references/):作为领域知识库,可存放标准操作流程(SOP)、数据架构图、合规性文档或历史案例分析等。这些资料在需要时被动态注入上下文,为智能体的推理和决策提供权威指导。
  • 资源文件目录 (assets/):用于存储静态资源,例如报告模板、UI组件或配置文件,通常服务于最终结果的生成与呈现。

综上所述,一个成熟的Skill框架主要实现四大核心功能:

  1. 专业工作流封装:定义并封装特定业务领域内一系列标准化的操作步骤。
  2. 工具集成指南:提供调用特定API、处理特定文件格式的详细操作指引。
  3. 领域知识承载:沉淀企业私有的业务规则、数据逻辑与行业专有知识。
  4. 资源打包管理:为处理复杂、重复性任务,预先打包好所需的脚本、文档和素材资源。

Skill、MCP 与 Tools:核心区别与应用场景选择

在AI应用开发中,Skill(技能)、Tool(工具)和MCP(模型上下文协议)这三个概念常令开发者困惑。它们定位不同,适用于不同的技术场景。

对比维度 Tools(工具) Skills(技能) MCP(Model Context Protocol)
本质定位 原子化动作执行与工具调用 专业化工作流与知识封装 标准化的通信连接协议
核心职责 调用API、执行函数、操作外部系统 加载领域Prompt、编排多步骤流程、整合参考资料 统一模型与外部数据源/工具服务的连接标准
触发方式 显式声明或函数调用(Function Calling) 基于上下文语义匹配 → 自动发现 → 按需加载 客户端与服务端通过JSON-RPC协议动态协商
上下文占用 低(仅注入schema与执行结果) 中/高(加载完整的操作指引与参考文档) 极低(仅定义接口规范,不承载具体业务逻辑)

在实际项目开发中,如何正确选择?可参考以下决策思路:

场景特征 推荐方案 典型示例
需要调用单一外部API、查询数据库、对接第三方服务 ✅ 使用 Tool 查询实时天气、发送电子邮件、调用支付网关接口
涉及多步骤SOP、合规审查、行业专有逻辑等复杂流程 ✅ 使用 Skill 合同法律风险审查、财务报表智能分析、客服工单自动分类与派发
团队多人协作、能力需频繁迭代更新、需要系统化知识沉淀 ✅ 使用 Skill + MCP Server 企业内部知识库智能问答系统、跨多个业务系统的数据聚合分析平台

简而言之,Tool 解决“做什么”的问题Skill 解决“如何做”的问题,而 MCP 则解决了“如何高效、标准化地连接”的问题。对于需要沉淀和复用复杂专业知识与流程的场景,Skill框架通常是更优的选择。

实战指南:基于LangChain中间件实现Skill渐进式加载

理解了核心概念后,我们来看具体实现。一个高效的Skill框架应支持“渐进式加载”:智能体先感知可用技能的简要描述,再根据任务需求动态加载详细内容,从而避免初始上下文信息过载。

整体框架设计思路

本实现方案的核心分为两个步骤:

  1. 技能发现:自动扫描Skills根目录下所有技能的名称(name)和描述(description),并将其封装到系统提示词中,使智能体知晓当前可用的技能库。
  2. 按需加载:智能体根据当前任务语义,选定特定技能并调用load_skill工具,从而获取该技能的完整详细内容。

具体实现步骤详解

第一步:创建标准的Skill目录结构

首先,在项目Skills目录下创建一个新的技能文件夹。文件夹名称即为技能名,其中必须包含SKILL.md文件,也可根据需要创建scriptsreferences等子目录。

一个典型的SKILL.md文件头部示例如下:

---
name: food-calorie
description: 精准计算各类食物卡路里,支持按食材、重量、烹饪方式拆分核算总热量
metadata:
  author: nobody
  version: 2.0.0
---

第二步:定义Skill数据结构模型

我们需要一个强类型的数据结构来承载技能信息。考虑到部分技能包含脚本等文件,定义如下类型:

class Skill(TypedDict):
    """文件夹型技能:支持 scripts / references / assets"""
    name: str          # 技能名 = 文件夹名
    description: str   # 简短描述(来自 SKILL.md 第一行)
    content: str       # SKILL.md 完整内容
    path: Path         # 技能根目录
    scripts: list[Path]    # scripts/ 下所有文件
    references: list[Path] # references/ 下所有文件
    assets: list[Path]     # assets/ 下所有文件

第三步:扫描并加载技能基础信息

接下来,从skills根目录中读取所有Skill的基础信息。关键点在于正确解析YAML头部的description字段。

def load_skills_from_dir(skills_root_dir: Path) -> list[Skill]:
    skills = []
    for skill_dir in sorted(skills_root_dir.iterdir()):
        if not skill_dir.is_dir():
            continue
        skill_md = skill_dir / "SKILL.md"
        if not skill_md.exists():
            continue

        text = skill_md.read_text(encoding="utf-8")
        # ======================
        # 修复点:从 YAML 头读取 description
        # ======================
        lines = text.splitlines()
        description = "No description"
        # 解析 --- 包裹的 YAML 头部
        if len(lines) > 2 and lines[0].strip() == "---":
            try:
                # 找到下一个 ---
                end_idx = lines[1:].index("---") + 1
                header_lines = lines[1:end_idx]
                # 读取 description 字段
                for line in header_lines:
                    if line.strip().startswith("description:"):
                        description = line.split(":", 1)[1].strip()
                        break
            except ValueError:
                pass

        skills.append(Skill(
            name=skill_dir.name,
            description=description,
            content=text,
            path=skill_dir,
            scripts=(list((skill_dir / "scripts").glob("*"))
                     if (skill_dir / "scripts").exists()
                     else []),
            references=(list((skill_dir / "references").rglob("*"))
                        if (skill_dir / "references").exists()
                        else []),
            assets=(list((skill_dir / "assets").glob("*"))
                    if (skill_dir / "assets").exists()
                    else []),
        ))
    return skills

SKILLS = load_skills_from_dir(Path(__file__).parent)

第四步:定义技能加载工具函数

我们需要提供一个工具函数,供智能体在运行时动态加载指定技能的完整内容。

@tool
def load_skill(skill_name: str) -> str:
    """Load the full content of a skill into the agent's context."""
    for skill in SKILLS:
        if skill["name"] == skill_name:
            return f"Loaded skill: {skill_name}nn{skill['content']}"
    a vailable = ", ".join(s["name"] for s in SKILLS)
    return f"Skill '{skill_name}' not found. A vailable skills: {a vailable}"

第五步:实现中间件,自动注入技能列表

最后,通过自定义的AgentMiddleware中间件,实现技能列表的自动注入和渐进式信息披露机制。

class SkillMiddleware(AgentMiddleware):
    """自动把所有【文件夹技能】注入系统提示"""
    tools = [load_skill, list_skill_files, read_skill_file]

    def __init__(self):
        skills_list = []
        for skill in SKILLS:
            skills_list.append(f"- **{skill['name']}**: {skill['description']}")
        self.skills_prompt = "n".join(skills_list)

    def wrap_model_call(
        self,
        request: ModelRequest,
        handler: Callable[[ModelRequest], ModelResponse],
    ) -> ModelResponse:
        skills_addendum = (
            f"nn## A vailable Skillsnn{self.skills_prompt}nn"
            "Use load_skill to get full instructions.n"
            "Use list_skill_files to list files in a skill.n"
            "Use read_skill_file to read any file in a skill."
        )
        new_content = list(request.system_message.content_blocks) + [{"type": "text", "text": skills_addendum}]
        new_system_message = SystemMessage(content=new_content)
        modified_request = request.override(system_message=new_system_message)
        return handler(modified_request)

第六步:运行测试与效果验证

现在,让我们测试这个框架。创建一个运动营养学专家智能体,并向其提出一个关于食物卡路里计算的问题。

def test_skill_middleware():
    llm = ChatOpenAI(model="qwen-flash", temperature=0.3)
    agent = create_agent(
        model=llm,
        middleware=[SkillMiddleware()],
        checkpointer=InMemorySa ver(),
        system_prompt="你是一位运动与营养学的专家",
    )
    config = {"configurable": {"thread_id": "1"}}
    result = agent.invoke(
        input={
            "messages": [{
                "role": "user",
                "content": "我今天吃了10碗米饭,而且还用青椒肉丝的汤汁浇在米饭上,摄入的卡路里是多少?",
            },]
        },
        config=config,
    )
    # Print the conversation
    for message in result["messages"]:
        if hasattr(message, 'pretty_print'):
            message.pretty_print()
        else:
            print(f"{message.type}: {message.content}")

运行测试后,可以观察到智能体成功识别并加载了food-calorie技能来精准回答问题:

================================== Ai Message ==================================
Tool Calls:
  load_skill (call_c790c732842245a98dc85c)
 Call ID: call_c790c732842245a98dc85c
 Args:
    skill_name: food-calorie
================================= Tool Message =================================
Name: load_skill
Loaded skill: food-calorie

---
name: food-calorie
description: 精准计算各类食物卡路里,支持按食材、重量、烹饪方式拆分核算总热量
metadata:
  author: DevTeam
  version: 2.0.0
---
# 食物卡路里计算专家指南
## 角色定位
你是专业营养学计算助手,擅长拆解混合食材、区分原生食材/加工烹饪方式、按国标营养热量标准,精准核算单种或多种食物总卡路里。
......
......
================================= Ai Message ===================================
Tool Calls:
  read_skill_file (call_76edf6d96c894868b889aa)
 Call ID: call_76edf6d96c894868b889aa
 Args:
    skill_name: food-calorie
    file_path: references/standard_calories.md
================================= Tool Message =================================
Name: read_skill_file

从日志可见,智能体首先通过load_skill工具获取了“食物卡路里计算”技能的完整指南,随后为进一步获取精确数据,又读取了技能包内的参考资料(standard_calories.md),从而完成了精准的卡路里核算。这正是Skill框架的核心价值:它将复杂的专业知识封装成可被智能体按需调用、分步加载的模块化能力。

通过上述设计,我们不仅实现了领域知识的有效封装与复用,还通过渐进式加载机制,在保证智能体运行效率的同时,维持了上下文的清洁度与专注度。

来源:https://juejin.cn/post/7629246556789784614

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
多智能体架构入门指南与核心概念解析

多智能体架构入门指南与核心概念解析

单个大语言模型处理复杂任务时存在上下文有限、无法并行等局限。多智能体系统通过组建协作团队应对,核心架构包括并行任务的编排者-工作者模式与串行依赖的流水线模式。实际应用中常混合使用两种模式,并通过子智能体实现递归扩展,可利用LangGraphSupervisor等技术进行动态任务路由与协调。

时间:2026-05-28 10:16
创作者必备 Loudly AI快速生成免版权音乐教程

创作者必备 Loudly AI快速生成免版权音乐教程

Loudly AI音乐生成器:创作者必备的免版权背景音乐解决方案 对于视频博主、自媒体运营者和数字内容创作者而言,寻找合适的背景音乐一直是个痛点:既耗时耗力,又时刻面临音乐版权侵权的风险。如今,AI音乐生成平台Loudly正通过人工智能技术彻底革新这一流程。它致力于为短视频创作者、独立制作人、中小型

时间:2026-05-28 10:15
年终总结汇报怎么写?详细范文模板与写作技巧分享

年终总结汇报怎么写?详细范文模板与写作技巧分享

年终总结需梳理年度工作成果。过去一年,在团队协作支持下,各项任务稳步推进落实,其中三项核心成果尤为突出。整体工作取得预期进展,为后续发展奠定基础。

时间:2026-05-28 10:15
PMToolsAI:AI驱动的项目管理工具使用指南与技巧

PMToolsAI:AI驱动的项目管理工具使用指南与技巧

PMToolsAI是什么 在追求极致效率的数字化工作时代,产品经理亟需能够应对复杂挑战的智能解决方案。PMToolsAI正是为此而生的专业级AI产品管理平台。它集成了前沿人工智能技术,旨在通过自动化与智能分析,系统性提升产品规划、开发与迭代全流程的效率,是赋能产品团队的核心生产力工具。 该平台深度融

时间:2026-05-28 10:14
免费AI诗歌生成器在线创作押韵诗

免费AI诗歌生成器在线创作押韵诗

AI Poem Generator产品介绍:免费智能诗歌创作工具 你是否曾想写一首诗,却面对空白屏幕毫无灵感?或者急需为婚礼、生日、毕业等特殊场合创作一首贴合主题的诗歌,但时间紧迫?现在,一款智能工具能为你提供高效的创作支持。 AI Poem Generator,是一款专业的在线AI诗歌生成器。其核

时间:2026-05-28 10:13
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜
热门教程
更多
  • 游戏攻略
  • 安卓教程
  • 苹果教程
  • 电脑教程