跳转到内容

Agent 与 Skill 运行指南

写完 Skill 和 Agent 代码之后,怎么让它真正跑起来?这篇笔记回答三个核心问题:在哪运行怎么运行运行需要什么

整体架构:本地代码 + 云端大脑

Agent 系统由两部分组成,运行在不同位置:

部分运行位置作用
你的 Python 代码(Agent 循环 + Skill 函数)本地电脑接收输入、调度工具、执行逻辑
LLM 大模型(GPT-4o / Claude / DeepSeek 等)云端 API理解意图、决定调用什么工具、生成回复

运行流程:

本地 Python 发送消息 → 云端 LLM 返回"我要调用 list_pods"
→ 本地执行 list_pods() 函数 → 结果发回云端 LLM
→ LLM 生成最终回复 → 本地打印输出

::: important 关键理解 Skill 的执行逻辑在你本地,LLM 只负责决定调用哪个 Skill 和传什么参数。LLM 不会替你执行 Python 函数,它只是告诉你"该执行什么"。 :::

运行环境准备

1. 安装 Python

需要 Python 3.10+,推荐用 uv 管理项目:

bash
# 安装 uv(如果还没装)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows 用 pip 安装 uv
pip install uv

2. 创建项目

bash
mkdir my-agent && cd my-agent
uv init

3. 安装依赖

根据你选择的 LLM SDK 安装对应包:

bash
# OpenAI SDK(兼容 DeepSeek / 通义千问 / Ollama / GLM)
uv add openai

# Anthropic SDK(Claude 专用)
uv add anthropic

# 如果用 K8s Skill 示例,还需要
uv add kubernetes

4. 配置 API Key

LLM API 需要密钥才能调用。选择一个提供商,按照 从零构建 Agent 和 Skill → LLM 选择指南 中的完整步骤操作。

各方案快速设置:

DeepSeek(推荐入门):

bash
$env:DEEPSEEK_API_KEY="sk-你的密钥"
python
from openai import OpenAI
import os
client = OpenAI(base_url="https://api.deepseek.com", api_key=os.environ.get("DEEPSEEK_API_KEY"))
# model 用 "deepseek-chat"

OpenAI:

bash
$env:OPENAI_API_KEY="sk-你的密钥"
python
from openai import OpenAI
import os
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
# model 用 "gpt-4o-mini"(便宜)或 "gpt-4o"(效果好)

通义千问:

bash
$env:DASHSCOPE_API_KEY="sk-你的密钥"
python
from openai import OpenAI
import os
client = OpenAI(base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key=os.environ.get("DASHSCOPE_API_KEY"))
# model 用 "qwen-plus"

Ollama 本地(免费,无需 API Key):

python
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
# model 用 "qwen2.5"(先 ollama pull qwen2.5)

Anthropic Claude:

bash
$env:ANTHROPIC_API_KEY="sk-ant-你的密钥"
python
import anthropic, os
client = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
# model 用 "claude-sonnet-4-6"(注意:用 anthropic SDK,不是 openai SDK)

Windows 设置环境变量

Windows PowerShell 中用 $env:变量名="值" 临时设置,关闭终端后失效。如需永久设置:系统属性 → 高级 → 环境变量。也可以在代码中直接传入,但不建议提交到 Git。

项目文件结构

my-agent/
├── skills/
│   ├── __init__.py       # 空文件,让 Python 识别为包
│   ├── tools.py          # Skill 的 Python 函数实现
│   ├── schemas.py        # JSON Schema 描述
│   └── registry.py       # 函数和 Schema 的注册绑定
├── agent.py              # Agent 主程序(while 循环)
└── pyproject.toml        # 项目配置

运行方式

方式一:手写 while 循环(推荐入门)

这是 从零构建 Agent 和 Skill 中第二步的实现方式,直接 python 运行:

bash
python agent.py

完整可运行的示例(使用 OpenAI SDK + DeepSeek):

python
# agent.py
import json
import os
from openai import OpenAI

# ============ Skill 定义 ============

def get_current_time(timezone: str = "Asia/Shanghai") -> str:
    """获取指定时区的当前时间"""
    from datetime import datetime
    from zoneinfo import ZoneInfo
    tz = ZoneInfo(timezone)
    return datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")

def calculate(expression: str) -> str:
    """计算数学表达式"""
    try:
        result = eval(expression)  # 仅用于学习,生产环境不要用 eval
        return str(result)
    except Exception as e:
        return f"计算错误: {e}"

# ============ Schema 描述 ============

get_current_time_schema = {
    "type": "function",
    "function": {
        "name": "get_current_time",
        "description": "获取指定时区的当前时间",
        "parameters": {
            "type": "object",
            "properties": {
                "timezone": {
                    "type": "string",
                    "description": "时区名称,如 Asia/Shanghai, America/New_York, Europe/London"
                }
            },
            "required": []
        }
    }
}

calculate_schema = {
    "type": "function",
    "function": {
        "name": "calculate",
        "description": "计算数学表达式的结果,支持加减乘除和幂运算",
        "parameters": {
            "type": "object",
            "properties": {
                "expression": {
                    "type": "string",
                    "description": "数学表达式,如 '2 + 3 * 4' 或 '10 / 3'"
                }
            },
            "required": ["expression"]
        }
    }
}

# ============ 注册表 ============

TOOL_REGISTRY = {
    "get_current_time": get_current_time,
    "calculate": calculate,
}

TOOLS_SCHEMAS = [get_current_time_schema, calculate_schema]

# ============ Agent 循环 ============

# 使用 DeepSeek(兼容 OpenAI SDK)
client = OpenAI(
    base_url="https://api.deepseek.com/v1",
    api_key=os.environ.get("OPENAI_API_KEY")
)

def run_agent(user_message: str):
    messages = [
        {
            "role": "system",
            "content": "你是一个智能助手,可以查询时间和进行数学计算。用中文回复。"
        },
        {
            "role": "user",
            "content": user_message
        }
    ]

    while True:
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=messages,
            tools=TOOLS_SCHEMAS
        )

        message = response.choices[0].message

        # LLM 不调用工具,说明完成了
        if not message.tool_calls:
            print("🤖 Agent:", message.content)
            break

        # 把 LLM 的回复加入历史
        messages.append(message)

        # 执行工具调用
        for tool_call in message.tool_calls:
            function_name = tool_call.function.name
            function_args = json.loads(tool_call.function.arguments)

            print(f"🔧 调用工具: {function_name}({function_args})")

            result = TOOL_REGISTRY[function_name](**function_args)

            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": str(result)
            })

# ============ 运行 ============

if __name__ == "__main__":
    print("Agent 已启动!输入问题开始对话(输入 q 退出)\n")

    while True:
        user_input = input("你: ")
        if user_input.strip().lower() == "q":
            break
        if user_input.strip():
            run_agent(user_input)
            print()

运行效果:

$ python agent.py
Agent 已启动!输入问题开始对话(输入 q 退出)

你: 现在几点了?纽约呢?
🔧 调用工具: get_current_time({"timezone": "Asia/Shanghai"})
🔧 调用工具: get_current_time({"timezone": "America/New_York"})
🤖 Agent: 现在是北京时间 2025-06-25 14:30:00,纽约时间是 2025-06-25 02:30:00。

你: 123 * 456 + 789 等于多少?
🔧 调用工具: calculate({"expression": "123 * 456 + 789"})
🤖 Agent: 123 × 456 + 789 = 56,877。

你: q

方式二:LangChain 框架

用框架可以省去手写 while 循环和 Schema 的重复代码:

bash
uv add langchain langchain-openai
python
# agent_langchain.py
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
from datetime import datetime
from zoneinfo import ZoneInfo

@tool
def get_current_time(timezone: str = "Asia/Shanghai") -> str:
    """获取指定时区的当前时间"""
    tz = ZoneInfo(timezone)
    return datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")

@tool
def calculate(expression: str) -> str:
    """计算数学表达式的结果"""
    try:
        return str(eval(expression))
    except Exception as e:
        return f"计算错误: {e}"

llm = ChatOpenAI(
    model="deepseek-chat",
    base_url="https://api.deepseek.com/v1"
)
tools = [get_current_time, calculate]

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个智能助手,可以查询时间和进行数学计算。用中文回复。"),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

result = agent_executor.invoke({"input": "现在几点了?"})
print(result["output"])

运行:

bash
python agent_langchain.py

方式三:MCP 服务

把 Skill 封装成独立服务,供 Claude Desktop、Cursor 等支持 MCP 的客户端调用:

bash
uv add mcp
python
# mcp_server.py
from mcp.server.fastmcp import FastMCP
from datetime import datetime
from zoneinfo import ZoneInfo

mcp = FastMCP("my-tools")

@mcp.tool()
def get_current_time(timezone: str = "Asia/Shanghai") -> str:
    """获取指定时区的当前时间"""
    tz = ZoneInfo(timezone)
    return datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")

@mcp.tool()
def calculate(expression: str) -> str:
    """计算数学表达式的结果"""
    try:
        return str(eval(expression))
    except Exception as e:
        return f"计算错误: {e}"

mcp.run()

运行 MCP 服务:

bash
python mcp_server.py

然后在 Claude Desktop 的配置文件中添加:

json
{
  "mcpServers": {
    "my-tools": {
      "command": "uv",
      "args": ["--directory", "C:/path/to/my-agent", "run", "mcp_server.py"]
    }
  }
}

配置后重启 Claude Desktop,就可以在对话中直接使用你的 Skill 了。

三种方式对比

手写 while 循环LangChainMCP 服务
运行方式python agent.pypython agent_langchain.pypython mcp_server.py + 客户端连接
运行位置本地终端本地终端本地后台服务
适合场景学习原理、简单脚本快速开发、生产应用可复用工具、跨客户端共享
复杂度⭐⭐⭐⭐⭐
灵活性最高中等受客户端支持限制
需要 LLM API❌(客户端自带 LLM)

常见问题

没有显卡能跑吗?

可以。 你的代码在本地运行,但"思考"是云端 LLM 完成的,不需要本地 GPU。如果用 Ollama 跑本地模型,则需要显卡(或用小模型如 Qwen2.5-0.5B 勉强跑在 CPU 上)。

没有 K8s 集群怎么办?

笔记中的 K8s Skill 示例需要真实的集群。学习阶段建议先用不需要外部依赖的 Skill(如获取时间、计算器、文件读取),跑通 Agent 循环后再接入 K8s。

API 调用要花钱吗?

  • OpenAI / Anthropic / DeepSeek / 通义千问:按 token 计费,学习阶段花费很少(几毛到几块钱)
  • Ollama 本地模型:免费,但效果取决于模型大小
  • 推荐学习用 DeepSeek,便宜且 Function Calling 支持好

报错 openai.AuthenticationError 怎么办?

API Key 没设置或无效。检查:

  1. 环境变量是否设置:echo $OPENAI_API_KEY
  2. Key 是否正确、是否过期
  3. 余额是否充足

报错 kubernetes.config.ConfigException 怎么办?

K8s Skill 找不到集群配置。要么配置 ~/.kube/config 连接真实集群,要么先不用 K8s Skill。

报错 ModuleNotFoundError 怎么办?

依赖没装。运行 uv add <包名>pip install <包名>

学习路径建议

第一步:跑通最简 Agent
├── 安装 Python + openai 包
├── 申请 LLM API Key(推荐 DeepSeek)
├── 用获取时间 / 计算器等简单 Skill
└── python agent.py 跑通 while 循环

第二步:添加更多 Skill
├── 文件读写 Skill
├── 网页搜索 Skill
└── 逐步替换为 K8s Skill(有集群的话)

第三步:用框架重构
├── LangChain @tool 装饰器
└── 理解框架帮你做了什么

第四步:MCP 服务化
├── 封装为 MCP Server
└── 接入 Claude Desktop / Cursor

参考资料

基于 MIT 许可发布