把开源 Skills 集成到 LangGraph 项目

把开源 Skills 集成到 LangGraph 项目中,核心是先将开源 Skill 标准化封装为 LangGraph 可识别的"工具/子图",再通过状态机编排调用逻辑。下面我会给你一套通用、可落地的完整流程,包含具体代码示例和适配不同类型开源 Skill 的方法。


一、集成前的核心准备

1. 明确开源 Skill 的类型(先分类,再适配)

不同开源 Skill 的实现形式不同,对应集成方式也不同,先做分类:

Skill 类型 典型示例 集成形式
原子函数型 Anthropic 官方技能库中的"文档解析""代码生成" 封装为 LangChain Tool
流程任务型 Superpowers 中的"TDD 开发流程""Git 工作流" 封装为 LangGraph 子图(Subgraph)
浏览器自动化型 Vercel Agent Browser、Qoder 的 /browser 技能 封装为带外部依赖的 Tool
数据处理型 Awesome Agent Skills 中的"结构化数据汇总" 封装为 Tool + 状态处理函数

2. 环境依赖安装

先安装 LangGraph 及技能集成所需的核心依赖:

bash 复制代码
# 核心依赖
pip install langgraph langchain langchain-core langchain-community
# 可选:浏览器自动化/工具调用依赖
pip install playwright python-dotenv  # 浏览器操作
playwright install chrome  # 安装浏览器驱动

二、通用集成流程(以 Anthropic 开源 Skill 为例)

步骤 1:下载并解析开源 Skill

以 Anthropic 技能库中的 browser-test-skill 为例,先克隆仓库并提取核心逻辑:

bash 复制代码
# 克隆开源技能库
git clone https://github.com/anthropics/skills.git
cd skills

打开技能目录下的 SKILL.md(技能元数据)和 main.py(核心逻辑),提取关键功能(比如"浏览器自动化测试")。

步骤 2:封装开源 Skill 为 LangChain Tool

这是最基础、最通用的集成方式,把开源 Skill 的核心函数包装成 LangGraph 可调用的 Tool:

python 复制代码
from langchain.tools import tool
from typing import Optional

# 1. 引入开源 Skill 的核心逻辑(这里模拟 Anthropic 的浏览器测试 Skill)
# 实际使用时替换为你下载的开源 Skill 代码
def run_browser_test(task: str, screenshot: bool = True) -> str:
    """
    开源 Skill 核心逻辑:执行浏览器自动化测试
    :param task: 自然语言测试指令(如"添加2个商品到购物车并验证数量")
    :param screenshot: 是否生成截图
    :return: 测试结果 + 截图路径(如有)
    """
    from playwright.sync_api import sync_playwright
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.goto("https://你的测试网站.com")
        # 这里是开源 Skill 的核心操作逻辑(省略具体步骤)
        result = f"测试完成:{task},截图已保存至 ./test-screenshot.png"
        browser.close()
        return result

# 2. 封装为 LangChain Tool(LangGraph 可直接调用)
@tool
def anthropic_browser_test_skill(
    task: str,
    screenshot: Optional[bool] = True
) -> str:
    """
    封装后的开源 Skill:浏览器自动化测试
    参数说明:
    - task: 自然语言测试指令(必填)
    - screenshot: 是否生成测试截图(默认True)
    """
    try:
        return run_browser_test(task, screenshot)
    except Exception as e:
        return f"技能执行失败:{str(e)}"

步骤 3:定义 LangGraph 状态与智能体节点

状态是 LangGraph 的核心,所有 Skill 的输入/输出都通过状态传递:

python 复制代码
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import ToolNode
from langchain_core.messages import HumanMessage, AIMessage, ToolMessage
from typing import List, TypedDict

# 1. 定义智能体状态(必须包含 messages,其他字段按需扩展)
class AgentState(TypedDict):
    messages: List[HumanMessage | AIMessage | ToolMessage]  # 消息流(核心)
    skill_output: Optional[str]  # 存储 Skill 执行结果
    next_node: str  # 控制流程跳转

# 2. 定义智能体决策节点(决定是否调用 Skill)
def agent_decision_node(state: AgentState) -> AgentState:
    """
    智能体决策逻辑:根据用户输入判断是否调用开源 Skill
    """
    # 获取最后一条用户消息
    last_message = state["messages"][-1]
    user_input = last_message.content.lower()

    # 触发条件:包含"浏览器测试""购物车测试"等关键词时调用 Skill
    if any(keyword in user_input for keyword in ["浏览器测试", "购物车测试", "e2e测试"]):
        # 告诉智能体下一步调用 Tool 节点
        state["next_node"] = "tool_node"
        # 追加调用指令到消息流
        state["messages"].append(
            AIMessage(content="将调用浏览器测试技能执行你的指令")
        )
    else:
        # 不调用 Skill,直接结束
        state["next_node"] = END
        state["messages"].append(
            AIMessage(content="你的指令无需调用技能,任务完成")
        )
    return state

# 3. 注册封装好的开源 Skill 为 ToolNode
# 把所有封装的开源 Skill 放入工具列表
tools = [anthropic_browser_test_skill]
# 创建 LangGraph 工具节点(自动处理 Tool 调用)
tool_node = ToolNode(tools)

# 4. 定义 Tool 执行后的结果处理节点
def tool_result_node(state: AgentState) -> AgentState:
    """
    处理 Skill 执行结果,更新状态
    """
    # 获取 Tool 执行结果
    tool_result = state["messages"][-1].content
    # 保存结果到状态
    state["skill_output"] = tool_result
    # 处理完成后返回给智能体,结束流程
    state["next_node"] = END
    state["messages"].append(
        AIMessage(content=f"技能执行结果:{tool_result}")
    )
    return state

步骤 4:编排 LangGraph 并运行

将决策节点、Tool 节点、结果节点串联成图,完成集成:

python 复制代码
# 1. 创建状态机图
graph = StateGraph(AgentState)

# 2. 添加节点
graph.add_node("agent_decision", agent_decision_node)  # 决策节点
graph.add_node("tool_node", tool_node)  # Skill 执行节点
graph.add_node("tool_result", tool_result_node)  # 结果处理节点

# 3. 定义边(流程跳转规则)
# 起始节点 → 决策节点
graph.set_entry_point("agent_decision")
# 决策节点 → Tool 节点(需要调用 Skill 时)
graph.add_conditional_edges(
    "agent_decision",
    lambda x: x["next_node"],  # 根据 next_node 决定跳转
    {
        "tool_node": "tool_node",
        END: END
    }
)
# Tool 节点 → 结果处理节点
graph.add_edge("tool_node", "tool_result")
# 结果处理节点 → 结束
graph.add_edge("tool_result", END)

# 4. 编译图(核心步骤)
app = graph.compile()

# 5. 测试运行(调用集成的开源 Skill)
if __name__ == "__main__":
    # 输入:触发开源 Skill 的用户指令
    initial_state = AgentState(
        messages=[HumanMessage(content="用浏览器测试购物车流程:添加2个商品并验证数量")],
        skill_output=None,
        next_node=""
    )

    # 运行图
    result = app.invoke(initial_state)

    # 输出结果
    print("=== 最终结果 ===")
    print(result["skill_output"])
    print("=== 消息流 ===")
    for msg in result["messages"]:
        print(f"{msg.type}: {msg.content}")

三、进阶:集成流程型开源 Skill 为子图

对于多步骤的开源 Skill(如 Superpowers 的"TDD 开发流程"),需要封装为子图再嵌入主图:

python 复制代码
from langgraph.graph import StateGraph

# 1. 定义子图(封装流程型开源 Skill)
def create_tdd_skill_subgraph():
    """
    封装 Superpowers 的 TDD 开发流程 Skill 为子图
    流程:需求分析 → 编写测试用例 → 编写代码 → 运行测试 → 总结
    """
    subgraph = StateGraph(AgentState)

    # 子图节点:对应开源 Skill 的每一步
    def tdd_analysis_node(state: AgentState) -> AgentState:
        # 开源 Skill 逻辑:需求分析
        state["messages"].append(AIMessage(content="TDD 第一步:需求分析完成"))
        state["next_node"] = "tdd_write_test"
        return state

    def tdd_write_test_node(state: AgentState) -> AgentState:
        # 开源 Skill 逻辑:编写测试用例
        state["messages"].append(AIMessage(content="TDD 第二步:测试用例编写完成"))
        state["next_node"] = "tdd_write_code"
        return state

    # 省略其他节点(编写代码、运行测试)...

    # 添加子图节点并编排流程
    subgraph.add_node("tdd_analysis", tdd_analysis_node)
    subgraph.add_node("tdd_write_test", tdd_write_test_node)
    # ... 其他节点
    subgraph.set_entry_point("tdd_analysis")
    subgraph.add_edge("tdd_analysis", "tdd_write_test")
    # ... 其他边
    subgraph.add_edge("tdd_run_test", END)

    return subgraph.compile()

# 2. 在主图中集成子图
if __name__ == "__main__":
    # 创建主图
    main_graph = StateGraph(AgentState)
    # 注册子图(流程型开源 Skill)
    tdd_subgraph = create_tdd_skill_subgraph()
    main_graph.add_node("tdd_skill", tdd_subgraph)

    # 主图决策节点:触发子图
    def main_decision_node(state: AgentState) -> AgentState:
        if "TDD 开发" in state["messages"][-1].content:
            state["next_node"] = "tdd_skill"
        else:
            state["next_node"] = END
        return state

    # 编排主图
    main_graph.add_node("main_decision", main_decision_node)
    main_graph.set_entry_point("main_decision")
    main_graph.add_conditional_edges(
        "main_decision",
        lambda x: x["next_node"],
        {"tdd_skill": "tdd_skill", END: END}
    )
    main_graph.add_edge("tdd_skill", END)

    # 编译并运行
    main_app = main_graph.compile()
    initial_state = AgentState(
        messages=[HumanMessage(content="用 TDD 流程开发一个加法函数")],
        skill_output=None,
        next_node=""
    )
    result = main_app.invoke(initial_state)
    print(result["messages"])

四、关键避坑与优化技巧

  1. 状态传递要规范 :所有 Skill 的输入/输出必须通过 AgentState 传递,禁止使用全局变量,否则多轮调用会出错。
  2. 异常处理不可少 :在 Tool 封装时加入 try-except,避免单个开源 Skill 崩溃导致整个智能体挂掉。
  3. 技能触发条件要明确:通过关键词、意图识别(如用 LLM 解析用户输入)触发 Skill,避免误调用。
  4. 依赖隔离:不同开源 Skill 的依赖可能冲突,建议用虚拟环境(venv)或 Docker 隔离。
  5. 调试用 LangSmith:开启 LangSmith 跟踪 Skill 调用链路,定位执行中的问题:
python 复制代码
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "你的 LangSmith API 密钥"

总结

  1. 开源 Skill 集成到 LangGraph 的核心是分类封装:原子技能→Tool,流程技能→子图。
  2. 所有 Skill 的输入/输出必须通过 LangGraph 的 State 传递,确保流程可追溯。
  3. 关键步骤:下载解析 Skill → 封装为 Tool/子图 → 编排状态机 → 测试运行。
相关推荐
AI英德西牛仔2 小时前
deepseek导出word排版
人工智能·ai·chatgpt·deepseek·ds随心转
(; ̄ェ ̄)。2 小时前
深度学习入门(十)RNN、LSTM、GRU
人工智能·rnn·深度学习
谁在黄金彼岸2 小时前
构建一个多Agent系统(Multi-Agent System, MAS)方法论
人工智能
pandafeeder2 小时前
Agent工具调用范式:ReAct 和Function Calling
人工智能
jinanwuhuaguo2 小时前
OpenClaw字节跳动的三只不同的claw龙虾飞书妙搭 OpenClaw、ArkClaw、扣子 OpenClaw 核心区别深度解析
人工智能·语言模型·自然语言处理·visual studio code·openclaw
咚咚王者2 小时前
人工智能之语言领域 自然语言处理 第十八章 Python NLP生态
人工智能·python·自然语言处理
yeflx2 小时前
三维空间坐标转换早期笔记
人工智能·算法·机器学习
zzh940772 小时前
Gemini 3.1 Pro 2026年国内使用指南:技术解析与镜像站实测
人工智能
初学大模型2 小时前
基于三层架构的自动驾驶系统设计:环境建模、标准驾驶与风险调制
人工智能