首页 / 文章

教授Deep Agents新技能:规划、子智能体与SKILL.md文件

LangChain的DeepAgents如何将规划、子智能体、文件系统内存与渐进式技能加载功能相结合,并附上构建计划、测试建议及部署说明。

发布者:REACTAPP.TOP阅读约 12 分钟2809 词

来源: Learning Skills with Deep Agents in Agentic AI

代理型人工智能指的是由多个协同工作的智能体构成的系统,它们能够将复杂棘手的问题分解开来,互相交流信息,像一支小型专家团队一样共同完成任务。单个聊天机器人只能回答一个问题,而代理型系统则需要具备规划能力、记忆功能以及工具使用能力,这样才能分多步完成一项任务。强化学习是让智能体通过试错学习的经典方法:深度网络会观察环境,选择诸如调用工具或执行代码之类的行动,并根据获得的奖励来调整自身的策略。深度强化学习已在围棋和国际象棋领域展现出超越人类的水平,在机器人技术方面也取得了优异成果,这一切都是通过最大化预期累积奖励实现的。将这些理念应用到基于大语言模型的智能体上,便出现了一个有趣的可能性,即智能体能够掌握可重复使用的流程或技能,从而以更少的精力进行规划与执行。

什么让智能体变得“深度”?

深度智能体为大型语言模型助手增添了四项功能:

  1. 一种可将复杂任务分解为多个步骤的规划工具。
  2. 用于并行处理及上下文隔离的子智能体。
  3. 兼具内存功能的持久化文件系统。
  4. 包含目标与约束条件的详细系统提示词。

这些功能共同使得智能体能够进行规划、保持状态,并执行复杂的任务流程,而不会受限于提示词中的上下文信息。浅层聊天机器人只会回答一次,而深度智能体则会循环操作:它规划、搜索、保存结果、综合分析并不断优化。当被要求撰写报告时,它可能会先列出待办事项、进行网络搜索或分析、将笔记存储在文件中,然后再起草并修改,整个过程均由模型驱动,无需人工干预。

强化学习与技能的来源

强化学习是那些通过行动来学习的智能体的基础。智能体观察当前状态,采取某种行动,随后会获得奖励或惩罚,它通过最大化未来奖励的期望值来优化自身的策略。它不同于有标签的监督学习,也不同于旨在发现隐藏结构的无监督学习,因为它处理的是在不确定性下的序列决策问题。深度强化学习则使用神经网络作为函数近似器,从而能够处理图像、文本以及原始传感器数据。著名的里程碑包括用于Atari游戏的深度Q网络,以及用于连续控制与策略游戏的PPO和A2C等策略梯度方法。最新的研究则着眼于分层技能学习,即智能体能够发现各种选项——也就是那些能够解决子目标、具有时间延续性的行动,这有助于探索与知识迁移。

对于大语言模型智能体而言,强化学习发挥着双重作用。其一是通过反馈信号对模型本身进行微调。例如,RLHF通过此类方法让模型更加安全且更贴合主题。DeepSeek-R1的实验表明,即便没有标注数据,仅依靠强化学习也能训练出在数学和编程领域性能可与顶尖系统相媲美的推理模型:该模型会生成多个答案,自动评分系统会对正确答案给予奖励,对错误答案予以惩罚,经过多轮训练后,PPO之类的算法会不断优化模型的策略。在实际应用中,为提升可读性和安全性,还可能会加入监督微调和拒绝采样等技术。

另一种角色位于智能体框架层面,此处可借助受强化学习启发的方法来帮助智能体获取技能。智能体能够记录其操作轨迹(使用了哪些工具、得到了什么结果),并将这些数据输入离线强化学习或模仿学习系统中,从而提炼出可重复执行的流程。通过分析过去的成功与失败案例,它可以将频繁出现的工具使用序列整合为更高级别的常规操作。这些以脚本文件或指令 Markdown 形式记录下来的常规操作,可以在后续任务中逐步向智能体展示。这样一来,系统便具备了持续学习的能力:面对新情况时,它能即时学习相关技能并将其存储为独立模块。

DeepAgents 库的构建方式

LangChain 的 DeepAgents 库将这些理念转化为适用于实际应用的工具框架,其架构是参照 Claude Code 和 Manus 等多步骤智能体的设计思路构建的。

  • 使用 write_todos 进行规划。该内置工具可让智能体在采取行动前先拟定逐步执行的清单。这份清单能指导工作流程,且会随着新信息的出现而调整。
  • 文件系统与内存。文件操作工具(ls、read_file、write_file、edit_file)允许智能体将相关上下文保存到文件或数据库中。通过存储中间结果和笔记,可以避免上下文窗口溢出,同时让智能体能够重新审视之前的步骤。无论是内存、本地磁盘、云存储还是隔离的沙箱环境,均可作为可插拔的后端来处理数据的持久化存储及安全的代码执行。
  • 子代理。内置的task工具可以生成专门的辅助工具,比如研究子代理或评审子代理。每个子代理都在独立的上下文中运行,这样就不会让主代理过于复杂,而且它们还可以拥有自己的系统提示和工具。主代理可以将网页搜索或代码分析任务交给这些子代理,并获取相应的总结结果。如果只需要隔离功能,通用型子代理只需复制主代理的配置即可。
  • 技能。技能是一个文件夹,其中包含一个SKILL.md文件,以及可选的脚本或文档。技能与工具的不同之处在于它们不会被完整加载到提示词中。只有YAML格式的元数据(名称、描述、标签)会进入上下文,而完整的指令则会在智能体认为其相关时逐步显示出来。这大大减少了令牌的使用量。一个PDF技能文件可能包含冗长的教程,智能体仅会在用户的任务涉及PDF时才会读取这些内容。技能能够将领域知识和操作流程传播到不同的智能体之间,而且智能体在面对新任务时甚至可以自行编写新的技能定义。
  • 由于这种设计,深度智能体在处理长流程的多步骤问题时表现远优于浅层智能体。它们能够提前规划、利用记忆、从经验中学习,并处理大量上下文信息。行业报告指出,智能体任务正变得越来越复杂,任务长度大约每几个月就会翻一番,而这正是这些特性发挥作用的关键所在。目前的趋势是从回答孤立查询转向自主解决问题。

    逐步构建方法

    以下方案将智能体架构与适用时的强化学习理念相结合,使用Python和DeepAgents SDK实现。首先需要安装相关库并配置环境:

    # Install deepagents and necessary tools
    !pip install --upgrade deepagents langchain tavily-python
    
    # Import libraries and set API keys (e.g., for LLM and search tool)
    import os
    from getpass import getpass
    os.environ["OPENAI_API_KEY"] = getpass("OpenAI API Key: ")
    os.environ["TAVILY_API_KEY"] = getpass("Tavily API Key: ")
    
    from deepagents import create_deep_agent
    from deepagents.backends import FilesystemBackend
    from deepagents.middleware.filesystem import FileData
    from langchain.chat_models import init_chat_model
    from tavily import TavilyClient
    

    定义智能体及其技能

    接下来是带有工具及预定义技能的深度智能体。在实际应用中,相比临时内存,使用本地磁盘或LangGraph等持久化后端更为合适。该版本采用以当前目录为根的FilesystemBackend,并加载技能文件夹:

    from deepagents import create_deep_agent
    
    # Assume we have local skill directories under "./skills"
    skill_dirs = ["./skills/pdf_processing", "./skills/data_analysis"]
    
    agent = create_deep_agent(
        model=model,
        system_prompt="""
    You are a highly capable AI assistant. Your objectives:
    1. Break tasks into steps using write_todos().
    2. Use internet_search and file tools to gather and store information.
    3. When given a task, plan and execute it step-by-step, writing to files as needed.
    4. Load skills from the filesystem to handle specialized tasks when relevant.
    5. Summarize results and refine final output before returning.
    """,
        tools=[internet_search],             # Web search tool
        backend=FilesystemBackend(root_dir="./workspace"),  # Persistent file storage
        skills=skill_dirs,                  # Load skills from local directories
    )
    

    系统提示强调规划与技能运用。skills参数指向那些子文件夹中每个都包含SKILL.md及配套文件的目录。例如./skills/pdf_processing/SKILL.md就可以教会智能体如何解析PDF文件。以这种方式加载技能后,智能体最初只能看到技能的名称和描述;当用户的任务涉及PDF文件时,它才会读取相应的SKILL.md及所有引用文件来学习处理流程。

    示例结构如下:

    skills/
    ├── pdf_processing/
    │   └── SKILL.md
    └── data_analysis/
        ├── SKILL.md
        └── analysis_script.py
    

    还有一个可能的 pdf_processing/SKILL.md 内容:

    ---
    name: pdf-processing
    description: Skill to extract and analyze content from PDF documents.
    ---
    # PDF Processing Skill
    
    To use this skill, follow these steps:
    1. Use `pdf-tools` to read PDF content.
    2. Summarize key findings from the PDF text.
    
    ...
    

    只有当智能体判断当前请求与PDF相关时,才会显示完整说明。这就是渐进式披露的体现:庞大的技能文件不会让每个提示都变得冗长。

    任务执行过程是怎样的

    现在给智能体一个复杂的任务。初始提示会引导它先制定计划。

    from langchain.schema import HumanMessage
    
    query = "Organize the latest quarterly sales data and write a summary report."
    response = agent.invoke({
        "messages": [HumanMessage(content=query)]
    })
    print(response["messages"][-1]["content"])
    

    从概念上讲,该智能体很可能会执行以下操作:

    1. 调用 write_todos() 生成清单,例如加载销售数据文件、制作图表、计算总计并撰写报告。
    2. 通过 internet_search 或内置的文件读取功能来调用工具,以收集现有数据。
    3. 当任务需要特殊处理流程时,可能会将数据清洗或分析工作交由子智能体处理。
    4. 运用相关技能。如果存在数据分析技能,它可能会从 ./skills/data_analysis 中读取 SKILL.md 并按照其中说明执行操作。
    5. 将清洗后的数据集或图表等中间结果保存到文件系统中。
    6. 撰写并润色最终的总结报告。

    完整运行会调用远程大语言模型,因此此处的验证主要在于确保结构正确。代码会选择可靠的后端,将高风险操作用try/except包裹(完整版本还应能捕获API和文件错误),并且还可以通过添加日志中间件进行扩展。通过对每个工具进行单元测试,并用模拟数据替代大语言模型的响应,即可对其进行验证。

    测试与评估

    智能体工作流的评估主要依靠人工判断。重点在于检查智能体是否正确完成任务并遵循既定计划。一种方法是使用已有答案的合成任务:给它一个简单的数学题,然后将最终结果与标准解进行对比。自动化的指标也有帮助,比如任务完成率(每一步是否都完成)或由大语言模型评估员给出的与参考答案的相似度得分。对于自由文本,可能仍需要人工审核或基于模型的分析才能做出最终判断。

    如果将强化学习用于技能学习,可以通过奖励曲线来衡量进展。构建一个完成子任务即可获得奖励的环境,并绘制每轮的总奖励值,可使用 OpenAI Gym 或自定义环境来实现。重要的评估指标包括样本效率(学习收敛的速度)、最终性能以及不同随机种子下的稳定性。在实际应用中,还需在研究、编程和分析等不同任务上展开测试,记录每项任务的成功率及Token使用量。

    在生产环境中,可观测性至关重要。应为代理程序添加追踪与日志功能,因为LangSmith能够捕获每一次工具调用及大语言模型的响应。在已部署的系统中,日志可被发送至CloudWatch或Prometheus,其中包含调用步数、每次调用的延迟以及错误信息。对于强化学习组件,则需记录奖励历史、损失曲线以及超参数。通过大规模批量处理、长时间运行以及异常输入进行压力测试,有助于确认系统的稳定性。

    作为服务进行部署

    在实际部署中,该代理程序会以微服务的形式运行。其可扩展的架构如下所示:

    +------------------+      +--------------+
    |  Client/User     | <--> | API Gateway  | <---> [HTTP requests]
    +------------------+      +------+-------+
                                  |
                                  v
                           +-------------+
                           |  AgentCore  |   <-- AWS Bedrock AgentCore (managed runtime)
                           +-------------+
                                  |
                    +-------------+-------------+
                    |                           |
          +-------------------+       +-------------------+
          | Deep Agent Service |       | Storage (S3/DB)   |  <-- File/memory backend, logs
          +-------------------+       +-------------------+
                    |                           |
                    +-------------+-------------+
                                  |
                          +---------------+
                          |   LLM Models  |  <-- e.g., OpenAI, Anthropic, local LLMs
                          +---------------+
    

    AWS AgentCore或类似平台上的代理服务负责接收指令、协调子代理并调用工具,所有交互都会被记录在持久化存储中,以便进行监控和记忆保留。其中有一些设计要点尤为突出。

    • 可扩展性与可靠性。可将代理运行在无服务器或容器化运行时环境中,如AWS Bedrock AgentCore、Azure AI Agent Service或Kubernetes。该系统能根据负载自动扩展,每次请求都会启动新的实例,且每个会话可运行在独立的微虚拟机中。持久化后端(如S3、数据库或LangGraph存储)可在重启后保持状态和记忆不丢失。
  • 可观测性。可追踪每一次调用。在 AWS 上,Bedrock AgentCore 启动套件会连接 CloudWatch 和 X-Ray,用于监控延迟与故障情况。通过记录提示词和响应的哈希值而非原始敏感数据,依然能够追踪性能表现,同时还能了解令牌使用情况、API 调用次数及成功率。
  • 安全性。限制智能体可访问的范围。文件系统工具应仅在指定目录内运行,而基于 sandbox 后端的代码执行则应在 Modal 或 Daytona 等加固过的环境中进行。为智能体访问的任何云资源分配最小权限的 IAM 角色,并通过大语言模型安全检查功能对输入内容进行验证和过滤,以防止恶意提示词的出现。
  • 成本。需在模型与后端方案之间取得平衡。价格较低的 Anthropic 模型可处理常规任务,而像 GPT-4o 这样的高级模型则用于关键规划步骤。将上下文存储在内存中并重复使用工具输出结果,可减少重复的提示词数量。
  • 完整示例

    该 Python 示例实现了规划流程,并包含错误处理与注释。它仅为概念性示例,实际运行需要真实的 API 密钥及相应的运行环境。

    from deepagents import create_deep_agent
    from deepagents.backends import FilesystemBackend
    from deepagents.middleware.filesystem import FileData
    from langchain.chat_models import init_chat_model
    from tavily import TavilyClient
    import os
    
    def setup_agent():
        """Initialize the Deep Agent with tools, skills, and system prompt."""
        # Model and tools initialization
        model = init_chat_model(model="openai:gpt-4o")
        tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
        def web_search(query: str, max_results: int = 3) -> str:
            results = tavily_client.search(query, max_results=max_results)
            return "\n".join(f"{r.title}: {r.summary}" for r in results)
    
        # Create the deep agent with planning, files, and skills
        try:
            agent = create_deep_agent(
                model=model,
                tools=[web_search],
                system_prompt="""You are an expert agent. Your workflow:
                1. Create a plan with write_todos().
                2. Use tools (e.g. web_search) and file system to research and work.
                3. If specialized tasks arise, load relevant skills from the 'skills' directory.
                4. Save results and refine the output at each step.
                """,
                backend=FilesystemBackend(root_dir="./workspace"),
                skills=["./skills/pdf_processing", "./skills/data_analysis"]
            )
            return agent
        except Exception as e:
            print(f"Error initializing agent: {e}")
            raise
    
    def invoke_agent(agent, user_query):
        """Invoke the agent on a user query and return the final answer."""
        try:
            messages = [{"role": "user", "content": user_query}]
            result = agent.invoke({"messages": messages})
            return result["messages"][-1]["content"]
        except Exception as e:
            print(f"Agent invocation failed: {e}")
            return None
    
    # Example usage
    if __name__ == "__main__":
        agent = setup_agent()
        task = "Analyze the recent research on climate change and summarize key findings."
        answer = invoke_agent(agent, task)
        print("Agent response:", answer)
    

    智能体的创建与调用都通过带有文档字符串和 try/except 块的函数来实现。web_search 工具会使用 Tavily 获取外部数据,系统提示则指导智能体进行规划、运用相应技能并优化输出结果。在正式版本中,需要处理诸如搜索结果为空或 API 超时之类的边缘情况,并且应记录异常详情而非直接打印出来。敏感信息应存储在安全的环境中,而非放在源代码中。随着更多工具或子智能体的加入,该结构可以自然扩展。

    要对其进行充分验证,需编写单元测试。通过模拟 LLM 返回固定的规划结果,检查智能体是否按预期生成文件或以正确的顺序调用工具。同时还需在基准测试任务中测量推理延迟和token成本。

    需考虑的权衡因素

    高级智能体结合规划、记忆、子智能体委托以及可加载的技能,能够处理简单聊天机器人无法完成的多步骤任务。清晰的系统提示、以规划为先的工作流程以及丰富的工具集为自主助手提供了坚实的基础。这些技能包含模块化的知识,例如pdf-processing或deploy-to-prod,可根据需求加载,从而保持上下文简洁,让智能体持续学习。

    • 在准确性与成本之间的平衡。像GPT-4o或Claude Sonnet这样的强大模型加上大规模搜索虽能提高准确性,但也会增加令牌费用和API成本。通过混合使用不同规模的模型并采用缓存机制,有助于在质量与成本之间取得平衡。
    • 在可扩展性与复杂性之间的平衡。像AWS AgentCore这样的无服务器智能体运行时具备自动扩展和可观测性功能,但需要做相应的集成工作:将智能体代码容器化并配置网络设置。
  • 安全性与灵活性之间的平衡。通过模态框或类似机制实现沙箱式执行,可降低代码注入风险,但会限制诸如任意网络调用之类的操作。需为所需功能定义清晰的工具接口。
  • 可靠性。应对LLM超时等短暂性错误时需进行重试,并在关键步骤设置人工检查点,因为某些智能体框架支持中断功能。
  • 可观测性。可使用LangSmith或自定义日志功能来追踪每一项规划步骤及工具调用情况。同时需监控CPU、GPU使用情况与延迟,并持续检查输出质量。
  • 展望未来,技能获取本身也可能实现自动化:通过基于历史轨迹的强化学习或无监督学习,可以生成新的技能定义。诸如 Microsoft AutoGen 或 Salesforce AgentForce 这样的多智能体框架,能够通过 LangGraph 协议协调多个专业智能体之间的协作。

    要构建一个能够学习技能的智能体,需要两样东西:合适的软件栈,以及可选的、能随着时间提升其性能的强化学习技术。借助 DeepAgents 与严谨的工程方法,就可以打造出能够独立解决复杂问题、学习新流程,并在大规模环境中稳定运行的助手。