Skills实现方案-LangChain1.0.md
10.2 KB
Skills 渐进式展开实现方案(LangChain 1.0+)
一、需求概述
用 Skills 替代零散的工具调用,实现渐进式展开(Progressive Disclosure):
Agent 在 system prompt 中只看到技能摘要,按需加载详细技能内容,减少 token 消耗、提升扩展性。
| 技能 | 英文标识 | 职责 |
|---|---|---|
| 查找相关商品 | lookup_related | 基于文本/图片查找相似或相关商品 |
| 搜索商品 | search_products | 按自然语言描述搜索商品 |
| 检验商品 | check_product | 检验商品是否符合用户要求 |
| 结果包装 | result_packaging | 格式化、排序、筛选并呈现结果 |
| 售后相关 | after_sales | 退换货、物流、保修等售后问题 |
二、LangChain 1.0 中的 Skills 实现方式
2.1 两种实现路线
| 方式 | 适用场景 | 依赖 |
|---|---|---|
| 方式 A:create_agent + 自定义 Skill 中间件 | 购物导购等业务 Agent | langchain>=1.0、langgraph>=1.0 |
| 方式 B:Deep Agents + SKILL.md | 依赖文件系统、多技能目录 | deepagents |
购物导购场景推荐方式 A,更易与现有 Milvus、CLIP 等服务集成。
2.2 核心思路:Progressive Disclosure
用户请求 → Agent 看轻量描述 → 判断需要的技能 → load_skill → 拿到完整说明 → 执行工具 → 回复
- 启动时:只注入技能名称 + 简短描述(1–2 句)
- 按需加载:Agent 调用
load_skill(skill_name)获取完整指令 - 执行:按技能说明调用对应工具
三、实现架构
3.1 技能定义结构
from typing import TypedDict
class Skill(TypedDict):
"""可渐进式展开的技能"""
name: str # 唯一标识
description: str # 1-2 句,展示在 system prompt
content: str # 完整指令,仅在 load_skill 时返回
3.2 五个技能定义示例
SKILLS: list[Skill] = [
{
"name": "lookup_related",
"description": "查找与某商品相关的其他商品,支持以图搜图、文本相似、同品类推荐。",
"content": """# 查找相关商品
## 适用场景
- 用户上传图片要求「找类似的」
- 用户说「和这个差不多」「搭配的裤子」
- 用户已有一件商品,想找相关款
## 操作步骤
1. **有图片**:先调用 `analyze_image_style` 理解风格,再调用 `search_by_image` 或 `search_products`
2. **无图片**:用 `search_products` 描述品类+风格+颜色
3. 可结合上下文中的商品 ID、品类做同品类推荐
## 可用工具
- `search_by_image(image_path, limit)`:以图搜图
- `search_products(query, limit)`:文本搜索
- `analyze_image_style(image_path)`:分析图片风格""",
},
{
"name": "search_products",
"description": "按自然语言描述搜索商品,如「红色连衣裙」「运动鞋」等。",
"content": """# 搜索商品
## 适用场景
- 用户用文字描述想要什么
- 如「冬天穿的外套」「正装衬衫」「跑步鞋」
## 操作步骤
1. 将用户描述整理成结构化 query(品类+颜色+风格+场景)
2. 调用 `search_products(query, limit)`,limit 默认 5–10
3. 如有图片,可先 `analyze_image_style` 提炼关键词再搜索
## 可用工具
- `search_products(query, limit)`:自然语言搜索""",
},
{
"name": "check_product",
"description": "检验商品是否符合用户要求,如尺寸、材质、场合、价格区间等。",
"content": """# 检验商品是否符合要求
## 适用场景
- 用户问「这款适合我吗」「有没有 XX 材质的」
- 用户提出约束:尺寸、价格、场合、材质
## 操作步骤
1. 从对话中提取约束条件(尺寸、材质、场合、价格等)
2. 对已召回商品做筛选或二次搜索
3. 调用 `search_products` 时在 query 中带上约束
4. 回复时明确说明哪些符合、哪些不符合
## 注意
- 无专门工具时,用 search_products 的 query 表达约束
- 可结合商品元数据(baseColour, season, usage 等)做简单筛选""",
},
{
"name": "result_packaging",
"description": "对搜索结果进行格式化、排序、筛选并呈现给用户。",
"content": """# 结果包装
## 适用场景
- 工具返回多条商品后需要整理呈现
- 用户要求「按价格排序」「只要前 3 个」
## 操作步骤
1. 按相关性/相似度排序
2. 限制展示数量(通常 3–5 个)
3. **必须使用以下格式**呈现每个商品:
- [Product Name] ID: [Product ID Number] Category: [Category] Color: [Color] Gender: [Gender] Season: [Season] Usage: [Usage] Relevance: [XX%] ```
- ID 字段不可省略,用于前端展示图片""", }, { "name": "after_sales", "description": "处理退换货、物流、保修、尺码建议等售后问题。", "content": """# 售后相关
适用场景
- 退换货政策、运费、签收时间
- 尺码建议、洗涤说明
- 保修、客服联系方式
操作步骤
- 此类问题无需调用商品搜索工具
- 按平台统一售后政策回答
- 涉及具体商品时,可结合商品 ID 查询详情后再回答
- 复杂问题引导用户联系客服""", }, ] ```
四、核心代码实现
4.1 load_skill 工具
from langchain.tools import tool
@tool
def load_skill(skill_name: str) -> str:
"""加载技能的完整内容到 Agent 上下文中。
当需要处理特定类型请求时,调用此工具获取该技能的详细说明和操作步骤。
Args:
skill_name: 技能名称,可选值:lookup_related, search_products, check_product, result_packaging, after_sales
"""
for skill in SKILLS:
if skill["name"] == skill_name:
return f"Loaded skill: {skill_name}\n\n{skill['content']}"
available = ", ".join(s["name"] for s in SKILLS)
return f"Skill '{skill_name}' not found. Available: {available}"
4.2 SkillMiddleware(注入技能描述)
from langchain.agents.middleware import AgentMiddleware, ModelRequest, ModelResponse
from langchain.messages import SystemMessage
from typing import Callable
class ShoppingSkillMiddleware(AgentMiddleware):
"""将技能描述注入 system prompt,使 Agent 能发现并按需加载技能"""
tools = [load_skill]
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"\n\n## 可用技能(按需加载)\n\n{self.skills_prompt}\n\n"
"在需要详细说明时,使用 load_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)
4.3 创建带 Skills 的 Agent
from langchain.agents import create_agent
from langgraph.checkpoint.memory import MemorySaver
# 基础工具(搜索、以图搜图、风格分析等)
from app.tools.search_tools import search_products, search_by_image, analyze_image_style
agent = create_agent(
model="gpt-4o-mini",
tools=[
load_skill, # 技能加载
search_products,
search_by_image,
analyze_image_style,
],
system_prompt="""你是智能时尚购物助手。根据用户需求,先判断使用哪个技能,必要时用 load_skill 加载技能详情。
处理商品结果时,必须遵守 result_packaging 技能中的格式要求。""",
middleware=[ShoppingSkillMiddleware()],
checkpointer=MemorySaver(),
)
五、与工具的关系
| 能力 | 技能 | 工具 |
|---|---|---|
| 查找相关 | lookup_related | search_by_image, search_products, analyze_image_style |
| 搜索商品 | search_products | search_products |
| 检验商品 | check_product | search_products(用 query 表达约束) |
| 结果包装 | result_packaging | 无(纯 prompt 约束) |
| 售后 | after_sales | 无(或对接客服 API) |
- 技能:提供「何时用、怎么用」的说明,支持渐进式加载。
- 工具:实际执行搜索、分析等操作。
六、可选:技能约束(进阶)
若希望「先加载技能再使用工具」,可结合 ToolRuntime 和 state 做约束:
from langchain.tools import tool, ToolRuntime
from langgraph.types import Command
from langchain.messages import ToolMessage
from typing_extensions import NotRequired
class CustomState(AgentState):
skills_loaded: NotRequired[list[str]]
@tool
def load_skill(skill_name: str, runtime: ToolRuntime) -> Command:
"""..."""
for skill in SKILLS:
if skill["name"] == skill_name:
content = f"Loaded skill: {skill_name}\n\n{skill['content']}"
return Command(update={
"messages": [ToolMessage(content=content, tool_call_id=runtime.tool_call_id)],
"skills_loaded": [skill_name],
})
# ...
# 在 check_product 等工具中检查 skills_loaded
七、依赖与版本
# requirements.txt
langchain>=1.0.0
langchain-openai>=0.2.0
langchain-core>=0.3.0
langgraph>=1.0.0
- Python 3.10+
- 若使用 Deep Agents 的 SKILL.md,需额外安装
deepagents
八、总结
| 项目 | 说明 |
|---|---|
| 效果 | 系统 prompt 只放简短技能描述,按需加载完整内容,减少 token、便于扩展 |
| 流程 | 轻量描述 → load_skill → 完整说明 → 调用工具 → 回复 |
| 实现 | SkillMiddleware + load_skill + create_agent |
| 技能 | lookup_related, search_products, check_product, result_packaging, after_sales |
完整示例可参考官方教程:Build a SQL assistant with on-demand skills。