LangChain DeepAgents 使用入门(自定义Skill)
LangChain DeepAgents 使用入门(自定义 Skill)
环境安装
确保 Python 版本 >= 3.12,然后安装 deepagents:
pip install deepagents
快速开始
create_deep_agent 的用法与 LangChain 原生的 create_agent 类似:
from deepagents import create_deep_agent
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
api_key="your-api-key",
model="minimax-m2.7",
base_url="https://api.example.com/v1",
)
agent = create_deep_agent(
model=model,
system_prompt="你是我的 AI 助手"
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "你好,你是谁?"}]}
)
print(result["messages"][-1].content)
运行效果:

自定义 Skill
目录结构
skills/
└── get-weather/ # Skill 名称
└── SKILL.md # Skill 定义文件

子文件夹名称即 Skill 名称,SKILL.md 是对应的 Skill 文档。
SKILL.md 格式
---
name: get-weather
description: 用户需要获取天气、气温时使用。
license: MIT
---
## 何时使用
- 用户要求获取天气、询问气温等情况
## 输出格式
- 直接输出以下格式:
[城市]气温26摄氏度,天气晴朗
创建 Agent 并加载 Skill
from deepagents import create_deep_agent
from deepagents.backends.utils import create_file_data
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver
from pathlib import Path
checkpointer = MemorySaver()
def load_skills_from_disk():
"""从本地加载 skills"""
all_files = {}
skills_root = Path(__file__).parent / "skills"
for skill_file in skills_root.rglob("SKILL.md"):
relative_path = skill_file.relative_to(skills_root)
virtual_path = "/skills/" + "/".join(relative_path.parts)
with open(skill_file, "r", encoding="utf-8") as f:
content = f.read()
all_files[virtual_path] = create_file_data(content)
return all_files
def create_agent():
"""创建 Deep Agent"""
model = ChatOpenAI(
api_key="your-api-key",
model="minimax-m2.7",
base_url="https://api.example.com/v1",
)
agent = create_deep_agent(
model=model,
skills=["/skills/"],
checkpointer=checkpointer,
)
return agent
if __name__ == "__main__":
agent = create_agent()
skills_files = load_skills_from_disk()
messages = []
print("=" * 50)
print("Deep Agent 连续对话模式(输入 q 退出)")
print("=" * 50)
while True:
user_input = input("\n你: ").strip()
if user_input.lower() in ("q", "quit", "exit"):
print("再见!")
break
if not user_input:
continue
messages.append({"role": "user", "content": user_input})
# files 和 messages 必须放在同一个字典里
result = agent.invoke(
{
"messages": messages,
"files": skills_files
},
config={"configurable": {"thread_id": "12345"}},
)
messages = result["messages"]
latest_message = messages[-1]
content = getattr(latest_message, "content", None)
if content:
print(f"\n助手: {content}")
关键点说明
-
Skill 路径:通过
skills=["/skills/"]指定,Agent 会自动扫描目录下所有SKILL.md -
files 参数:
files必须与messages放在同一个字典里,作为 Agent 的输入 -
checkpointer:
MemorySaver()将对话历史保存在内存中,支持同一线程内的多轮对话
运行效果
运行结果如Skill中的描述一致

Skill进阶(调用脚本)
要让 Agent能够执行调用脚本的任务,首先需要让Agent拥有脚本执行能力,也就是控制台执行命令
那么需要为Agent构建一个本地的Shell后端LocalShellBackend,同时,将技能和对应技能的脚本导入如后端,即可实现在skill中调用脚本
这里创建了一个获取当前时间的Skill

SKILL.md内容:
---
name: time-query
description: 获取当前日期和时间。当用户询问现在几点、今天日期、当前时间、或需要时间相关信息时使用。
---
# 时间查询技能
## 何时使用
- 用户问"现在几点"、"现在时间"、"几点几分"
- 用户问"今天是几号"、"今天星期几"、"今天日期"
- 需要返回精确时间信息的任何场景
## 执行流程
### 步骤 1:定位脚本
脚本路径:`/skills/time-query/scripts/get_time.py`
### 步骤 2:执行脚本
使用 `execute` 工具运行脚本(Windows 环境):
python /skills/time-query/scripts/get_time.py
### 步骤 3:返回结果
将脚本输出的时间信息以清晰格式返回给用户
## 注意事项
- 必须使用 execute 工具执行脚本,不要自己编造时间
- 如果 execute 失败,告知用户无法获取时间
完整代码:
"""
LangChain DeepAgents 调用自定义 Skill 示例
使用 LocalShellBackend 支持脚本执行。
"""
import sys
from pathlib import Path
# 设置编码
sys.stdout.reconfigure(encoding='utf-8')
from deepagents import create_deep_agent
from deepagents.backends.local_shell import LocalShellBackend
from deepagents.backends.utils import create_file_data
from langchain_openai import ChatOpenAI
from langgraph.checkpoint.memory import MemorySaver
checkpointer = MemorySaver()
def create_agent():
"""创建 Deep Agent,使用 LocalShellBackend 支持脚本执行"""
model = ChatOpenAI(
api_key="",
model="minimax-m2.7",
base_url="",
timeout=120,
)
# 使用 LocalShellBackend,支持 execute 工具运行脚本
# virtual_mode=True: 启用虚拟路径模式,阻止路径遍历
backend = LocalShellBackend(virtual_mode=True)
agent = create_deep_agent(
model=model,
backend=backend,
skills=["/skills/"],
checkpointer=checkpointer,
)
return agent, backend
def load_skills_with_backend(backend):
"""加载 skills 到指定后端"""
skills_root = Path(__file__).parent / "skills"
# 加载 SKILL.md
for skill_file in skills_root.rglob("SKILL.md"):
relative_path = skill_file.relative_to(skills_root)
virtual_path = "/skills/" + "/".join(relative_path.parts)
with open(skill_file, "r", encoding="utf-8") as f:
content = f.read()
backend.write(virtual_path, content)
# 加载脚本文件
for skill_dir in skills_root.iterdir():
if skill_dir.is_dir():
for file_path in skill_dir.rglob("*"):
if file_path.is_file() and file_path.name != "SKILL.md":
relative_path = file_path.relative_to(skills_root)
virtual_path = "/skills/" + "/".join(relative_path.parts)
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
backend.write(virtual_path, content)
if __name__ == "__main__":
agent, backend = create_agent()
# 将 skills 加载到后端
load_skills_with_backend(backend)
# 初始化对话
messages = []
print("=" * 50)
print("Deep Agent 连续对话(输入 q 退出)")
print("=" * 50)
while True:
user_input = input("\n你: ").strip()
if user_input.lower() in ("q", "quit", "exit"):
print("再见!")
break
if not user_input:
continue
messages.append({"role": "user", "content": user_input})
result = agent.invoke(
{"messages": messages},
config={"backend": backend, "configurable": {"thread_id": "12345"}},
)
# 更新消息历史
messages = result["messages"]
# 打印助手回复
latest_message = messages[-1]
content = getattr(latest_message, "content", None)
token_cost = result["messages"][-1].response_metadata["token_usage"]["total_tokens"]
if content:
print(f"\n助手: {content} -- token_cost: {token_cost}")
运行效果


浙公网安备 33010602011771号