
昨晚有个朋友跟我吐槽:
“我用 LangChain 搭了个 AI 智能体,结果搭完发现它像个傻子——只会重复我说的话,稍微复杂点的任务就歇菜。”
我跟他说,你的问题不在于 LangChain 框架本身,而在于你搭的那个玩意儿,可能根本就不是真正意义上的智能体。
大多数教程教你的,是如何造一把只会抡锤子的手。
而今天我想跟你聊的,是一个完全不同的思路——
如何让你的 AI 智能体学会‘扫描技能目录’的能力,实现真正的按需加载,并且不用动一行核心代码。
一个真实的故事:当AI变成“祖宗”
三个月前,我想让 AI 帮我做竞品分析。
正常操作是什么?写提示词、调参数、加工具定义……折腾了两天,AI 终于“看起来”能用了。
然后第三天我想让它顺手写个营销文案——得,一切推倒重来。
第四天我想让它做用户调研——继续重复造轮子。
我当时就在想:这玩意儿到底是我的工具,还是我需要伺候的祖宗?
直到我摸索到了 SKILL.md 模式。
什么是 SKILL.md 模式?
一句话概括:一种让 AI 智能体在运行时动态加载和执行技能的方法。
-
传统做法:
定义工具 → 绑定模型 → 构建图 → 完成
你提前告诉 AI 它能做什么,AI 照做。这更像一个“浅层指令执行器”。
-
SKILL.md 做法:
放一个文件夹 → AI 自动扫描 → 按需加载 → 完工
你不需要在代码里明确定义 AI “能做什么”。你只需要把一堆技能说明书(SKILL.md文件)扔进一个目录,AI 自己会判断:该用哪个、什么时候用、怎么用。
更妙的是——
第二天你想加个代码审查功能?再创建一个新的技能文件夹丢进去就行。
AI 智能体会自动发现:“哦,目录里多了个新技能,我学会了。”
你的核心 agent.py 文件,一行代码都不用改。
核心架构:它到底是如何工作的?
我直接给你看它的核心流程全貌:
用户输入
↓
编排器(Orchestrator)←→ 技能库(skills/)
↓ ↕ 按需加载
子智能体(Subagent)──→ 工作区(workspace/)
这个架构围绕四个关键设计原则展开:
-
规划先行(Planning):编排器拿到任务,第一件事不是盲目执行——而是拆解。例如,把“帮我做竞品分析”拆成“搜索信息→整理数据→写报告”这样的子步骤。
-
通用委托(Generic Delegation):编排器自己不干具体活,它有一个“通用打工人”——子智能体。这个子智能体跟你一样,看着技能目录的说明书干活。
-
按需智能(On-Demand Intelligence):启动时,AI 只看到技能的名字和简短描述。只有在真正需要执行某个具体任务时,才会去加载该技能的完整详细文档。这被称为渐进式披露(Progressive Disclosure)。就像你查菜谱——先看目录决定做什么菜,真要做的时候才翻到具体的那一页去看步骤。
-
强制工作区(Enforced Workspace):所有输出都必须存放在 ./workspace/ 目录下。这不是限制,而是规范。AI 的输出必须有明确的归属,不能到处乱放,这极大方便了结果管理和后续处理。
手把手代码实现
整个项目的核心,其实就三个主要文件。
第一步:环境与依赖
首先在 pyproject.toml 或 requirements.txt 中定义依赖:
# pyproject.toml
[project]
name = "deep-agents-langchain"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"deepagents>=0.4.12",
"langchain-anthropic>=1.4.0",
"langchain-openai>=1.1.12",
"python-dotenv>=1.2.2",
"streamlit>=1.55.0",
"tavily-python>=0.7.23",
]
核心是 deepagents——一个基于 LangChain 的开源库,它正是“深度智能体”这套理念的产品化实现。
第二步:定义基础工具
import os
from typing import Literal
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain_openai import ChatOpenAI
from tavily import TavilyClient
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
load_dotenv()
# 通用工具:网络搜索
tavily = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
def internet_search(
query: str,
max_results: int = 5,
topic: Literal["general", "news", "finance"] = "general",
):
"""Search the web for current information."""
return tavily.search(query, max_results=max_results, topic=topic)
注意,这里我们只显式定义了一个自定义工具——Tavily 搜索。
其他所有复杂功能(任务规划、文件读写、调用子智能体、技能加载),全部由 deepagents 库内置提供。少即是多,这避免了工具的过度绑定。
第三步:构建智能体工厂
这是最核心的部分:
def get_deep_agent():
model = ChatAnthropic(
model="claude-3-5-sonnet-20240620",
temperature=0,
)
return create_deep_agent(
model=model,
system_prompt="""You are a generic Deep Agent orchestrator.
1. Use `write_todos` to plan complex requests.
2. You have access to skills in the `skills/` directory.
- You ONLY see names and descriptions initially.
- For specialized tasks, load the matching SKILL.md first.
3. Use the `task` tool to delegate to subagents.
4. ALL outputs go to `./workspace/` exclusively.""",
tools=[internet_search],
skills=["./skills"], # 关键一行:指定技能目录
memory=["./AGENTS.md"],
backend=FilesystemBackend(root_dir="."),
name="generic_deep_agent",
)
重点看这一行:skills=["./skills"]
AI 启动时,会自动扫描 ./skills/ 目录,读取所有 SKILL.md 文件的元数据部分(即YAML Frontmatter)。此时它看到的不是冗长的文档,而是一个简洁的技能菜单:
Available Skills:
- research: "Conducts comprehensive web research..."
- writer: "Specialized in writing high-quality content..."
可能两个技能的描述只占200个Token。
然后呢?没有然后了。 AI 将基于这个菜单和你的用户请求,自己决定何时调用哪个技能。
第四步:编写技能文档(SKILL.md)
技能文档遵循特定结构,分为“菜单”和“菜谱”两部分:
---
name: research
description: >
Conducts comprehensive web research on any topic using search APIs
and web scraping. Use when the user asks for research, information
gathering, competitive analysis, or needs current data from the web.
license: MIT
compatibility: Requires internet access and Tavily API key
allowed-tools: internet_search read_file write_to_file
---
# Web Research Skill
## Instructions
1. Parse the research query to identify key topics.
2. Use the `internet_search` tool to gather initial results.
3. If results are insufficient, try alternative search queries.
4. Synthesize findings into a structured summary.
5. Save detailed findings to `./workspace/` as a markdown file.
- YAML Frontmatter(菜单):这是AI的“第一眼”,决定了它是否考虑使用这个技能。包含名称、简短描述、许可、兼容性和允许使用的工具列表。
- Markdown正文(菜谱):这是“详细说明书”。只有AI决定使用这个技能后,才会读取这部分内容来指导具体执行步骤。
就像餐厅:前面是菜名和简介(Frontmatter),你点了菜(AI决定用这个技能),服务员才去后厨看具体做法(Markdown正文)。
技能路由的奥秘:LLM即路由器
这是最令人惊讶的部分——系统中没有独立的路由器或分类器。大语言模型(LLM)本身就是路由器。
系统提示词里明确写道:
You have access to a library of skills in the `skills/` directory.
You ONLY see names and descriptions initially.
For any specialized task, look for matching skills and use
`read_file` to load the SKILL.md before executing.
AI 读取用户消息 → 对照内存中的技能描述列表 → 自主判断并决定是否调用 read_file(“skills/research/SKILL.md”) 来加载完整技能。
整个决策过程,完全发生在大模型 Transformer 的一次前向传播推理中。
没有任何外部硬编码逻辑,没有 if-else 规则链。
这就是 SKILL.md 模式的精髓:技能描述本身就是路由引擎。撰写清晰、准确的技能描述,就等于设计了一个高效的路由逻辑。
扩展新技能:一行核心代码都不用改
假设你现在需要增加一个“代码审查”技能。
- 在
skills/ 目录下新建文件夹 code-reviewer/。
- 在该文件夹内创建
SKILL.md 文件。
目录结构变为:
skills/
├── research/
│ └── SKILL.md
├── writer/
│ └── SKILL.md
└── code-reviewer/ # 新加的技能文件夹
└── SKILL.md
SKILL.md 内容如下:
---
name: code-reviewer
description: >
Reviews code for bugs, security issues, and best practices.
Use when the user asks for a code review, security audit,
or wants feedback on code quality. Do NOT use for writing
new code or debugging runtime errors.
license: MIT
allowed-tools: read_file write_to_file
---
# Code Review Skill
## Instructions
1. Read the target file using `read_file`.
2. Analyze for: bugs, security issues, performance, readability.
3. Write a structured review to `./workspace/review.md`.
- 重启你的应用。
完事。
你没有修改 agent.py,没有调整系统提示词,更没有重新训练模型。
你所做的,仅仅是放入了一个符合规范的文件夹。
总结与思考
说实话,第一次理解这个模式时,我愣了几秒。
不是因为它有多复杂,恰恰是因为它太简单了。
没有炫技的算法,没有黑科技。其核心就是将软件工程中经典的“按需加载”和“关注点分离”思想,优雅地应用到了 AI 智能体架构上。
但这个“简单”背后,蕴含着一个深刻的认知转变:
不要让 AI 在启动时就‘记住’所有事情(这会导致上下文臃肿且僵化)。而应该让它在需要的时候,自己去‘查阅’详细的说明书。
这难道不更像人类的学习和工作方式吗?
我们不需要背诵整本字典才能查字,也不需要记住所有菜谱的细节才会做菜。
按需加载、动态扩展,才是通向更通用、更实用智能体的关键路径。
最后,如果你对这种能直观展示 AI 思维链的技术实现感兴趣,可以尝试运行项目自带的 Streamlit UI。它能实时展示工具调用、技能加载、计划更新的全过程,让你清晰地看到你的智能体究竟是“怎么想”的。欢迎将你的实践和心得在云栈社区这样的开发者社区进行分享和讨论。
| 传统智能体构建方式 |
SKILL.md 模式 |
| 预设工具,能力固定 |
动态扫描,按需加载 |
| 添加功能 = 修改代码 |
添加功能 = 放入文件夹 |
| AI 启动时“全知” |
AI 运行时“边查边用” |
| 工具越多,系统越复杂 |
技能越多,系统越灵活 |
如果你也在使用 LangChain 或类似框架构建智能体,强烈建议你尝试一下这个思路。
也许你会发现——你的 AI 智能体,终于不再是那个需要你精心伺候的“祖宗”,而真正成为了一个得力助手。