Skill(Agent 技能)
→ 返回 AI Agent
Agent 技能(Skill)是 Agent 可调用的原子能力单元,对应 LLM Tool Use 中的 function/tool。Agent 通过 Skill 与外部世界交互——检索数据、执行代码、操作文件、调用 API。
技能类型
| 类型 | 说明 | 示例 |
|---|
| 数据检索 | 查询知识库、数据库、搜索引擎 | RAG 检索、SQL 查询、网页搜索 |
| 代码执行 | 运行代码、调用计算工具 | Python REPL、数学计算器 |
| 文件操作 | 读写本地或云端文件 | 读 CSV、写 Markdown、上传图片 |
| 外部 API | 调用第三方服务 | 发邮件、查天气、操作 GitHub |
| UI 交互 | 操作浏览器或桌面界面 | 网页爬虫、表单填写 |
| 子 Agent | 委托另一个 Agent 完成子任务 | A2A 协议调用 |
{
"type": "function",
"function": {
"name": "search_knowledge_base",
"description": "在知识库中检索与问题最相关的文档片段,返回 Top-K 结果",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "检索查询词"
},
"top_k": {
"type": "integer",
"description": "返回结果数量,默认 5",
"default": 5
}
},
"required": ["query"]
}
}
}
from langchain_core.tools import tool
@tool
def search_knowledge_base(query: str, top_k: int = 5) -> str:
"""在知识库中检索与问题最相关的文档片段,返回 Top-K 结果。"""
results = vectorstore.similarity_search(query, k=top_k)
return "\n\n".join([doc.page_content for doc in results])
@tool
def run_python_code(code: str) -> str:
"""执行 Python 代码并返回输出结果。仅用于数学计算和数据处理。"""
import subprocess
result = subprocess.run(["python", "-c", code], capture_output=True, text=True, timeout=10)
return result.stdout or result.stderr
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
query: str = Field(description="检索查询词")
top_k: int = Field(default=5, description="返回结果数量")
class KnowledgeSearchTool(BaseTool):
name: str = "search_knowledge_base"
description: str = "在知识库中检索相关文档"
args_schema: type[BaseModel] = SearchInput
def _run(self, query: str, top_k: int = 5) -> str:
results = vectorstore.similarity_search(query, k=top_k)
return "\n\n".join([doc.page_content for doc in results])
绑定到 Agent
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
tools = [search_knowledge_base, run_python_code]
llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个助手,可以检索知识库并执行代码来回答问题。"),
("human", "{input}"),
("placeholder", "{agent_scratchpad}")
])
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = executor.invoke({"input": "Redis 的 Sorted Set 底层数据结构是什么?"})
工具调用流程
用户输入
↓
LLM 决策:是否需要调用工具?
├── 否 → 直接生成回答
└── 是 → 生成 tool_call(工具名 + 参数)
↓
执行工具(本地函数 / MCP Server / API)
↓
将工具返回结果追加到消息历史
↓
LLM 再次推理(可能触发多轮工具调用)
↓
生成最终回答
多工具并发调用
# GPT-4o / Claude 支持在单次响应中并发调用多个工具
# 例如同时查询知识库和执行代码,再综合结果
设计原则
| 原则 | 说明 |
|---|
| 描述要精确 | description 是 LLM 判断何时调用的唯一依据,模糊描述导致误调用 |
| 参数要最小化 | 只暴露必要参数,减少 LLM 生成错误参数的概率 |
| 错误要返回文本 | 工具抛异常应 catch 后返回错误描述字符串,而非让 Agent 崩溃 |
| 幂等优先 | 查询类工具应幂等;写操作需明确提示后果 |
| 超时保护 | 外部 API 调用加 timeout,避免 Agent 无限等待 |
@tool
def safe_api_call(endpoint: str) -> str:
"""调用指定 REST API 端点,返回 JSON 响应。"""
try:
resp = requests.get(endpoint, timeout=5)
resp.raise_for_status()
return resp.text
except requests.Timeout:
return "错误:请求超时(5s),请检查端点是否可用"
except requests.HTTPError as e:
return f"错误:HTTP {e.response.status_code}"
except Exception as e:
return f"错误:{str(e)}"
通过 MCP 暴露技能
将本地 Tool 包装为 MCP Server 后,任意 MCP 客户端(Claude Desktop、IDE 插件等)均可调用:
# 把上面的 search_knowledge_base 包装成 MCP Server
@app.list_tools()
async def list_tools():
return [Tool(
name="search_knowledge_base",
description="在知识库中检索相关文档片段",
inputSchema={
"type": "object",
"properties": {
"query": {"type": "string"},
"top_k": {"type": "integer", "default": 5}
},
"required": ["query"]
}
)]
Skill vs Memory
| 维度 | Skill(技能) | Memory(记忆) |
|---|
| 本质 | 动作,Agent 主动触发 | 状态,存储历史信息 |
| 方向 | 输入 → 外部系统 → 输出 | 写入 → 存储 → 检索 |
| 时效 | 即时执行,无持久化 | 跨会话持久 |
| 典型内容 | 搜索、计算、写文件 | 用户偏好、历史对话、项目状态 |
| 关系 | Skill 的执行结果可写入 Memory | Memory 检索结果作为 Skill 的上下文 |
相关文档
- MCP — 通过 MCP 协议暴露 Skill 给模型
- A2A — 子 Agent 作为一种特殊 Skill
- Memory — 技能执行结果的持久化存储
- RAG — 检索技能的底层实现