这次我们来看一个关于 AI Agent 与 Skill 开发的实战教程。这个教程的核心目标非常明确: 手把手教你从零开始,掌握 AI Agent 技能(Skill)的开发与集成,并通过代码实战将理论落地 。它不空谈概念,而是聚焦于如何构建一个真正能执行具体任务的智能体,比如调用 API、处理数据、自动化工作流。

对于开发者而言,最关心的莫过于: 需要什么技术栈?环境配置复杂吗?有没有现成的框架和代码示例? 这篇文章将直接切入这些核心问题。我们将围绕一个典型的 Agent 开发流程展开,涵盖环境搭建、核心概念理解、Skill 开发实战、与大型模型(如 Claude、GPT)的集成,以及最终的项目部署与测试。无论你是想为现有产品添加 AI 能力,还是探索自动化智能体开发,这篇文章都能提供一条清晰的实践路径。

1. 核心能力速览:AI Agent 开发教程能带给你什么?

在深入代码之前,我们先快速了解通过本教程你将掌握的核心能力与所需条件。

能力项 说明与目标
教程定位 面向开发者的 AI Agent 与 Skill 实战开发指南,侧重代码实现与集成。
核心输出 能够独立开发、测试并集成一个具备特定功能的 AI Agent Skill。
技术栈涉及 Python(主)、API 调用(如 OpenAI/Claude)、可能涉及 LangChain/AutoGen 等框架基础、Web 服务(FastAPI/Flask)。
硬件/环境门槛 无特殊 GPU 要求 。主要依赖 CPU、网络(用于调用云端大模型 API)和标准的 Python 开发环境。本地运行对内存有一定要求(建议 8GB+)。
关键概念覆盖 Agent(智能体)、Skill(技能)、Planning(规划)、Tool Calling(工具调用)、Prompt Engineering(提示词工程)。
实战环节 从零创建 Skill、定义工具、集成 Agent 框架、处理大模型返回、构建测试用例。
适合人群 有一定 Python 基础的开发者、对 AI 应用落地感兴趣的工程师、希望自动化工作流的技术人员。
不适合场景 纯理论研究、无需代码的 AI 工具使用、本地大模型微调训练。

简单来说,这是一个**“动手做”**的教程。你将得到的不是一个黑盒工具,而是一套可扩展的开发方法和代码库。

2. 适用场景与使用边界

在投入开发前,明确 Agent 和 Skill 能做什么、不能做什么至关重要。

适用场景:

  1. 自动化工作流 :将重复性的、规则明确的数字任务交给 Agent 执行,如数据抓取与清洗、报告生成、内容摘要、跨系统信息同步。
  2. 智能客服与问答增强 :让 Agent 在回答用户问题时,不仅能基于知识库,还能实时查询天气、股价、订单状态等外部信息。
  3. 代码辅助与生成 :开发类似 Cursor 或 Codex 的智能编程助手,Agent 可以理解需求、调用代码解释器、执行单元测试。
  4. 企业内部工具 :构建审批流程机器人、会议纪要整理助手、项目进度自动追踪器等,提升运营效率。
  5. 探索性原型开发 :快速验证一个 AI 赋能的产品想法,例如智能旅行规划器、个性化学习导师等。

使用边界与注意事项:

  1. 依赖外部大模型 :大多数 Agent 的核心“大脑”是云端大模型(如 GPT-4、Claude 3)。其效果、成本、响应速度受 API 服务制约。
  2. 确定性有限 :大模型的输出具有概率性,Agent 执行复杂链式任务时可能出错,需要设计严谨的错误处理和验证机制。
  3. 安全与权限 :Agent 被授予调用工具(Skill)的权限,必须严格控制其可访问的数据和系统范围,防止越权操作。
  4. 不适合高实时、高精度控制 :如工业控制、自动驾驶等对实时性和确定性要求极高的场景,目前仍非 AI Agent 的主流应用领域。
  5. 合规与版权 :如果 Skill 涉及处理用户数据、生成内容或访问受版权保护的资料,必须确保符合相关法律法规和平台政策。

3. 环境准备与前置条件

让我们开始搭建开发环境。整个过程在普通笔记本电脑上即可完成,无需高端显卡。

基础软件清单:

  • 操作系统 :Windows 10/11, macOS, 或 Linux (如 Ubuntu 22.04)。推荐使用 Windows 或 macOS 进行开发。
  • Python 环境 :Python 3.8 - 3.11 版本。推荐使用 3.9 或 3.10,稳定性最好。请务必确认安装。
  • 包管理工具 pip (通常随 Python 安装)。建议升级到最新版: pip install --upgrade pip
  • 代码编辑器 :Visual Studio Code (VSCode) 或 PyCharm。VSCode 轻量且插件丰富,是首选。
  • 版本控制 :Git(可选,但强烈推荐)。用于管理代码版本。

核心 Python 包准备: 我们将使用一个虚拟环境来隔离项目依赖。打开终端(Windows 用 PowerShell 或 CMD,macOS/Linux 用 Terminal),执行以下步骤:

# 1. 创建项目目录并进入
mkdir ai-agent-tutorial && cd ai-agent-tutorial

# 2. 创建 Python 虚拟环境 (Windows)
python -m venv venv
# 激活虚拟环境 (Windows PowerShell)
.\venv\Scripts\Activate.ps1
# 如果提示执行策略限制,请先以管理员身份运行 PowerShell,执行:Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# 激活虚拟环境 (Windows CMD)
.\venv\Scripts\activate.bat

# 创建 Python 虚拟环境 (macOS/Linux)
python3 -m venv venv
# 激活虚拟环境
source venv/bin/activate

# 激活后,终端提示符前会出现 (venv) 标识。

安装基础依赖: 在激活的虚拟环境中,安装以下核心包。我们以 openai langchain 为例,它们是构建 Agent 的常见选择。

# 安装核心AI与Web开发库
pip install openai langchain langchain-openai langchain-community
# 安装Web框架,用于构建Skill的API服务
pip install fastapi uvicorn
# 安装HTTP客户端,用于Skill调用外部API
pip install requests
# 安装环境变量管理
pip install python-dotenv

获取大模型 API 密钥: 本教程需要调用大模型 API。你需要准备一个有效的 API 密钥。

  • OpenAI :访问 platform.openai.com 注册并获取 API Key。
  • Anthropic (Claude) :访问 console.anthropic.com 注册并获取 API Key。
  • 国内可选 :智谱AI、DeepSeek、通义千问等,根据其官方文档获取。

创建环境变量文件: 在项目根目录创建 .env 文件,用于安全存储密钥, 切记不要提交到 Git

# .env 文件内容示例
OPENAI_API_KEY=sk-your-openai-api-key-here
ANTHROPIC_API_KEY=your-claude-api-key-here
# 其他API密钥...

至此,最基本的环境就准备好了。

4. 核心概念解析:Agent、Skill 与框架

动手编码前,必须厘清几个关键概念,这是后续所有开发的基础。

Agent (智能体) : 一个能够感知环境、进行决策并执行动作以实现目标的程序实体。在本文语境下,特指 能够理解用户自然语言指令,并通过调用一系列工具(Skills)来完成复杂任务的 AI 系统 。它通常由一个大语言模型(LLM)驱动,负责规划和推理。

Skill / Tool (技能/工具) : Agent 可以调用的具体功能单元。一个 Skill 就是一个函数,它封装了特定的能力,例如:

  • search_web(query) : 执行网络搜索。
  • get_weather(city) : 获取城市天气。
  • calculate(expression) : 计算数学表达式。
  • send_email(to, subject, body) : 发送邮件。 Agent 的核心能力取决于其拥有的 Skills 数量和质量。

Planning (规划) : Agent 接收到复杂任务后,将其分解为一系列可执行的子任务(即调用哪些 Skills,以及调用的顺序和参数)的过程。例如,任务“帮我订一张明天北京飞上海的最便宜机票”可能被规划为: [search_flights(“北京”, “上海”, “明天”), compare_prices(flight_list), book_ticket(selected_flight)]

Tool Calling (工具调用) : 大模型(如 GPT-4)根据对话上下文和可用工具列表,主动生成一个结构化的请求来调用特定工具的能力。这是 Agent 能够“动手操作”的关键技术。

主流开发框架选择:

  1. LangChain :生态最丰富,模块化程度高,提供了大量现成的工具链和 Agent 模板,学习曲线稍陡但功能强大。
  2. AutoGen :由微软推出,擅长构建多智能体对话和协作场景,适合复杂工作流。
  3. Semantic Kernel (SK) :微软出品,与 .NET 生态结合紧密,概念清晰。
  4. 自定义框架 :对于简单需求,直接使用 OpenAI 的 Function Calling 或 Anthropic 的 Tool Use 功能,搭配 FastAPI 构建 Skill 服务,是更轻量、可控的选择。

本教程将采用 “自定义框架 + OpenAI Function Calling” 的路径,以确保你能透彻理解底层原理。掌握后,迁移到 LangChain 等框架将非常容易。

5. 实战第一步:开发你的第一个 Skill

我们从创建一个最简单的 Skill 开始:一个获取指定城市天气的接口。这个 Skill 本身是一个 HTTP API。

项目结构初始化: 在项目根目录创建如下文件和文件夹:

ai-agent-tutorial/
├── .env                    # 环境变量
├── requirements.txt        # 依赖列表 (可通过 `pip freeze > requirements.txt` 生成)
├── skills/                 # 存放所有Skill模块
│   ├── __init__.py
│   └── weather_skill.py   # 天气Skill
├── agent/                  # 存放Agent核心逻辑
│   ├── __init__.py
│   └── core.py
├── main.py                 # 主入口,启动Agent服务
└── test_skill.py          # Skill测试脚本

编写 Weather Skill: skills/weather_skill.py 文件内容如下。这里我们使用一个模拟的天气 API。

# skills/weather_skill.py
import requests
import os
from typing import Dict, Any

def get_weather(city: str) -> Dict[str, Any]:
    """
    获取指定城市的天气信息。
    
    Args:
        city (str): 城市名称,例如 "北京"。
    
    Returns:
        Dict: 包含天气信息的字典。如果失败,返回错误信息。
    """
    # 注意:此处为示例,实际应使用真实的天气API,如和风天气、OpenWeatherMap等。
    # 你需要注册并获取自己的API密钥。
    api_key = os.getenv("WEATHER_API_KEY", "demo_key")
    
    # 模拟API响应 - 在实际开发中替换为真实的API调用
    # 示例: response = requests.get(f"https://api.weatherapi.com/v1/current.json?key={api_key}&q={city}&aqi=no")
    print(f"[Weather Skill] 正在查询{city}的天气...")
    
    # 模拟数据
    mock_data = {
        "city": city,
        "temperature": 22,
        "condition": "晴朗",
        "humidity": 65,
        "wind_speed": 10,
        "unit": "摄氏度"
    }
    
    # 模拟API调用延迟
    import time
    time.sleep(0.5)
    
    return {
        "success": True,
        "data": mock_data,
        "message": f"已获取{city}的天气信息。"
    }

# 为了让Agent框架能发现此Skill,我们提供一个描述字典。
# 这个描述会被传递给大模型,使其知道如何调用这个工具。
WEATHER_SKILL_DESCRIPTION = {
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "获取指定城市的当前天气信息,包括温度、天气状况、湿度和风速。",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "城市名称,例如:北京、上海、纽约。"
                }
            },
            "required": ["city"]
        }
    }
}

测试 Skill: 创建 test_skill.py 来验证我们的 Skill 是否能独立工作。

# test_skill.py
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from skills.weather_skill import get_weather

if __name__ == "__main__":
    # 测试获取天气
    result = get_weather("北京")
    print("Skill测试结果:")
    print(result)

在终端运行 python test_skill.py ,你应该能看到输出的模拟天气数据。这表明 Skill 的逻辑功能是正常的。

6. 构建 Agent 核心:集成大模型与 Skill 调用

现在,我们将创建一个简单的 Agent 核心,它能够理解用户指令,并决定是否以及如何调用我们刚写好的 Weather Skill。

编写 Agent 核心逻辑: agent/core.py 文件内容如下。这里使用 OpenAI 的 Function Calling 功能。

# agent/core.py
import openai
import json
import os
from dotenv import load_dotenv
from typing import Dict, Any, List

# 加载环境变量
load_dotenv()

class SimpleAgent:
    def __init__(self, model: str = "gpt-3.5-turbo"):
        """
        初始化一个简单的Agent。
        
        Args:
            model (str): 使用的OpenAI模型,例如 "gpt-3.5-turbo", "gpt-4"。
        """
        self.client = openai.OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
        self.model = model
        # 注册可用的Skills列表,每个元素是一个Skill的描述字典。
        self.available_skills: List[Dict] = []
        
    def register_skill(self, skill_description: Dict):
        """向Agent注册一个Skill(工具)。"""
        self.available_skills.append(skill_description)
        print(f"[Agent] 已注册技能: {skill_description['function']['name']}")
        
    def _execute_skill(self, skill_name: str, arguments: Dict) -> Dict[str, Any]:
        """
        根据技能名称和参数执行对应的本地函数。
        这里需要将技能名称映射到实际的Python函数。
        """
        # 技能名称到函数的映射
        skill_map = {
            "get_weather": self._call_weather_skill,
            # 未来可以在这里添加更多映射,如 "calculate": self._call_calc_skill
        }
        
        if skill_name not in skill_map:
            return {"success": False, "error": f"未知的技能: {skill_name}"}
        
        try:
            # 调用对应的函数
            return skill_map[skill_name](**arguments)
        except Exception as e:
            return {"success": False, "error": f"执行技能时出错: {str(e)}"}
    
    def _call_weather_skill(self, city: str) -> Dict[str, Any]:
        """调用天气技能的内部方法。"""
        # 动态导入,避免循环依赖
        from skills.weather_skill import get_weather
        return get_weather(city)
    
    def chat(self, user_input: str, conversation_history: List[Dict] = None) -> Dict[str, Any]:
        """
        与Agent进行一轮对话。
        
        Args:
            user_input (str): 用户输入的自然语言指令。
            conversation_history (List): 之前的对话历史,格式为OpenAI消息列表。
            
        Returns:
            Dict: 包含Agent回复和可能执行的动作结果。
        """
        if conversation_history is None:
            conversation_history = []
        
        # 构建当前轮次的消息
        messages = conversation_history + [{"role": "user", "content": user_input}]
        
        # 第一步:调用大模型,并告知它可用的工具(Skills)
        response = self.client.chat.completions.create(
            model=self.model,
            messages=messages,
            tools=self.available_skills,  # 关键:将技能描述作为工具列表传入
            tool_choice="auto",  # 让模型自动决定是否调用工具
        )
        
        response_message = response.choices[0].message
        tool_calls = response_message.tool_calls
        
        # 初始化回复内容
        final_response = response_message.content or ""
        skill_execution_results = []
        
        # 第二步:如果模型决定调用工具,则执行对应的Skill
        if tool_calls:
            for tool_call in tool_calls:
                skill_name = tool_call.function.name
                try:
                    arguments = json.loads(tool_call.function.arguments)
                except json.JSONDecodeError:
                    arguments = {}
                
                print(f"[Agent] 决定调用技能: {skill_name}, 参数: {arguments}")
                
                # 执行技能
                result = self._execute_skill(skill_name, arguments)
                skill_execution_results.append({
                    "skill": skill_name,
                    "arguments": arguments,
                    "result": result
                })
                
                # 第三步:将技能执行结果作为上下文,再次发送给模型,让它生成面向用户的回答
                messages.append(response_message)  # 添加模型的第一次回复
                messages.append({
                    "role": "tool",
                    "name": skill_name,
                    "content": json.dumps(result),
                    "tool_call_id": tool_call.id
                })
                
                # 获取模型基于工具执行结果的最终回复
                second_response = self.client.chat.completions.create(
                    model=self.model,
                    messages=messages,
                )
                final_response = second_response.choices[0].message.content
        else:
            # 如果模型没有调用工具,直接使用其回复
            final_response = response_message.content
            
        return {
            "response": final_response,
            "skill_calls": skill_execution_results
        }

创建主程序并测试: main.py 文件内容如下。

# main.py
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from agent.core import SimpleAgent
from skills.weather_skill import WEATHER_SKILL_DESCRIPTION

def main():
    print("=== 启动简易 AI Agent ===")
    
    # 1. 初始化Agent
    agent = SimpleAgent(model="gpt-3.5-turbo") # 可根据需要切换为 gpt-4
    
    # 2. 注册Skill
    agent.register_skill(WEATHER_SKILL_DESCRIPTION)
    print(f"当前已注册 {len(agent.available_skills)} 个技能。")
    
    # 3. 开始对话循环
    conversation_history = []
    print("\n你可以开始向Agent提问了。输入 'quit' 或 '退出' 结束对话。")
    
    while True:
        try:
            user_input = input("\n你: ").strip()
            if user_input.lower() in ['quit', '退出', 'exit']:
                print("对话结束。")
                break
            if not user_input:
                continue
                
            # 调用Agent
            result = agent.chat(user_input, conversation_history)
            
            # 更新对话历史(简化处理,实际生产环境需更精细管理)
            conversation_history.append({"role": "user", "content": user_input})
            conversation_history.append({"role": "assistant", "content": result["response"]})
            
            # 打印结果
            print(f"\nAgent: {result['response']}")
            if result['skill_calls']:
                print(f"[调试信息] 本轮调用了技能: {result['skill_calls']}")
                
        except KeyboardInterrupt:
            print("\n\n程序被中断。")
            break
        except Exception as e:
            print(f"\n发生错误: {e}")
            # 可以选择继续对话或退出
            continue

if __name__ == "__main__":
    main()

在终端运行 python main.py 。确保你的 .env 文件中已正确设置 OPENAI_API_KEY 。启动后,尝试输入:“北京今天天气怎么样?” Agent 应该会识别出需要调用 get_weather 技能,并返回一个整合了模拟天气信息的自然语言回答。

7. 功能扩展:开发更多 Skills 并优化 Agent

一个实用的 Agent 需要多种 Skills。让我们再添加一个计算器 Skill,并优化 Agent 的架构。

添加计算器 Skill: 创建 skills/calculator_skill.py

# skills/calculator_skill.py
import math
from typing import Dict, Any

def calculate(expression: str) -> Dict[str, Any]:
    """
    计算一个数学表达式。支持加减乘除、乘方和常见函数。
    警告:使用 eval 存在安全风险,此处仅用于演示。
         生产环境必须使用安全的表达式解析库(如 ast.literal_eval, numexpr)。
    
    Args:
        expression (str): 数学表达式,例如 "3 + 5 * 2", "sqrt(16)"。
    
    Returns:
        Dict: 包含计算结果或错误信息。
    """
    # 安全警告:此处为演示简化,实际项目严禁直接使用eval处理用户输入。
    # 应使用受限制的解析器。
    safe_globals = {"__builtins__": None}
    safe_locals = {"math": math}
    
    try:
        # 非常基础的安全过滤(不完善,仅演示)
        if any(keyword in expression.lower() for keyword in ['import', 'exec', 'compile', 'open', 'os.', 'sys.']):
            raise ValueError("表达式包含不安全字符")
            
        result = eval(expression, {"__builtins__": None}, {"math": math})
        return {
            "success": True,
            "result": result,
            "expression": expression,
            "message": "计算成功。"
        }
    except Exception as e:
        return {
            "success": False,
            "error": str(e),
            "expression": expression,
            "message": "计算失败,请检查表达式格式。"
        }

CALCULATOR_SKILL_DESCRIPTION = {
    "type": "function",
    "function": {
        "name": "calculate",
        "description": "计算一个数学表达式的结果。支持加减乘除(+,-,*,/)、乘方(**)、括号,以及math模块中的函数,如sqrt, sin, cos, log等。示例:'3 + 5 * 2', 'sqrt(16)', 'math.sin(math.pi/2)'。",
        "parameters": {
            "type": "object",
            "properties": {
                "expression": {
                    "type": "string",
                    "description": "需要计算的数学表达式。"
                }
            },
            "required": ["expression"]
        }
    }
}

更新 Agent 核心以支持新 Skill: 修改 agent/core.py 中的 _execute_skill 方法和 skill_map

# 在 agent/core.py 的 SimpleAgent 类中修改
class SimpleAgent:
    # ... __init__, register_skill 等方法保持不变 ...
    
    def _execute_skill(self, skill_name: str, arguments: Dict) -> Dict[str, Any]:
        skill_map = {
            "get_weather": self._call_weather_skill,
            "calculate": self._call_calculator_skill, # 新增映射
        }
        # ... 其余代码不变 ...
    
    def _call_weather_skill(self, city: str) -> Dict[str, Any]:
        from skills.weather_skill import get_weather
        return get_weather(city)
    
    def _call_calculator_skill(self, expression: str) -> Dict[str, Any]: # 新增方法
        from skills.calculator_skill import calculate
        return calculate(expression)
    
    # ... chat 方法保持不变 ...

更新主程序以注册新 Skill: 修改 main.py

# main.py (更新部分)
from agent.core import SimpleAgent
from skills.weather_skill import WEATHER_SKILL_DESCRIPTION
from skills.calculator_skill import CALCULATOR_SKILL_DESCRIPTION # 新增导入

def main():
    print("=== 启动简易 AI Agent ===")
    agent = SimpleAgent(model="gpt-3.5-turbo")
    
    # 注册多个Skills
    agent.register_skill(WEATHER_SKILL_DESCRIPTION)
    agent.register_skill(CALCULATOR_SKILL_DESCRIPTION) # 新增注册
    print(f"当前已注册 {len(agent.available_skills)} 个技能。")
    
    # ... 其余对话循环代码不变 ...

重新运行 python main.py 。现在你可以问:“计算一下 15 的平方加上 20 除以 4 等于多少?” Agent 应该会调用计算器 Skill 并给出答案。你也可以混合提问:“北京天气怎么样?顺便算一下 2 的 10 次方。” 观察 Agent 是如何规划并依次调用多个 Skills 的。

8. 进阶:构建 Skill 的 Web API 服务

为了让 Skills 能被远程调用或集成到更复杂的系统中,我们将其包装成 HTTP API 服务。这里使用 FastAPI。

创建 skill_server.py

# skill_server.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import uvicorn
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from skills.weather_skill import get_weather
from skills.calculator_skill import calculate

app = FastAPI(title="AI Agent Skill Server", description="提供天气查询和计算器技能的API服务")

class WeatherRequest(BaseModel):
    city: str

class CalculatorRequest(BaseModel):
    expression: str

@app.get("/")
def read_root():
    return {"message": "AI Agent Skill Server is running."}

@app.post("/skill/weather")
def execute_weather_skill(request: WeatherRequest):
    """执行天气查询技能"""
    try:
        result = get_weather(request.city)
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"技能执行失败: {str(e)}")

@app.post("/skill/calculate")
def execute_calculator_skill(request: CalculatorRequest):
    """执行计算器技能"""
    try:
        result = calculate(request.expression)
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"技能执行失败: {str(e)}")

@app.get("/skills")
def list_skills():
    """列出所有可用的技能及其描述"""
    skills_list = [
        {
            "name": "get_weather",
            "endpoint": "/skill/weather",
            "method": "POST",
            "description": "获取指定城市的当前天气信息。",
            "input_schema": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"]
            }
        },
        {
            "name": "calculate",
            "endpoint": "/skill/calculate",
            "method": "POST",
            "description": "计算一个数学表达式。",
            "input_schema": {
                "type": "object",
                "properties": {"expression": {"type": "string"}},
                "required": ["expression"]
            }
        }
    ]
    return {"skills": skills_list}

if __name__ == "__main__":
    # 启动服务,默认在 http://127.0.0.1:8000
    uvicorn.run(app, host="127.0.0.1", port=8000)

在终端运行 python skill_server.py 。服务启动后,你可以:

  1. 访问 http://127.0.0.1:8000/docs 查看自动生成的交互式 API 文档(Swagger UI)。
  2. 使用 curl 或 Postman 测试 API:
    # 测试天气API
    curl -X POST "http://127.0.0.1:8000/skill/weather" -H "Content-Type: application/json" -d '{"city":"上海"}'
    # 测试计算器API
    curl -X POST "http://127.0.0.1:8000/skill/calculate" -H "Content-Type: application/json" -d '{"expression":"3.14 * 10**2"}'
    

现在,你的 Agent 核心可以通过 HTTP 请求来调用这些 Skills,实现了松耦合的架构。你可以将 Skill 服务部署在独立的服务器上。

9. 资源占用、性能观察与优化建议

由于本教程的 Agent 核心是调用云端大模型 API,本地资源占用主要集中在 Python 进程和网络 I/O。

资源占用观察:

  • CPU/内存 :运行 main.py skill_server.py 的 Python 进程,内存占用通常在 100MB - 500MB 之间,取决于请求频率和 Skills 的复杂度。CPU 占用很低。
  • 网络延迟 :Agent 的响应时间主要受 OpenAI API 网络延迟和模型推理时间影响。 gpt-3.5-turbo 通常较快(1-3秒), gpt-4 可能慢一些(3-10秒)。
  • 无 GPU 消耗 :所有大模型推理均在云端完成,本地无需 GPU。

性能优化建议:

  1. 对话历史管理 :长时间对话会导致发送给 API 的 tokens 数量增长,增加成本和延迟。需要设计策略,如只保留最近 N 轮对话,或总结历史对话。
  2. Skill 调用超时与重试 :网络调用可能失败。在 _execute_skill 方法中应添加超时和重试逻辑。
  3. 异步处理 :对于需要调用多个 Skills 或处理多个并发用户请求的场景,可以使用 asyncio aiohttp 进行异步编程,提升吞吐量。
  4. 缓存 :对结果变化不频繁的 Skill(如天气,可缓存几分钟)实施缓存,减少不必要的 API 调用和等待时间。
  5. API 密钥轮询与负载均衡 :如果使用频繁,考虑管理多个 API 密钥,并在请求时轮询使用,避免触发速率限制。

10. 常见问题与排查方法

在开发过程中,你可能会遇到以下问题:

问题现象 可能原因 排查方式 解决方案
启动 main.py 时报错 ModuleNotFoundError 1. 虚拟环境未激活。
2. 依赖包未安装。
3. Python 路径问题。
1. 检查终端提示符前是否有 (venv)
2. 运行 pip list 查看 openai , fastapi 等包是否存在。
3. 检查 sys.path 或使用绝对导入。
1. 激活虚拟环境。
2. 运行 pip install -r requirements.txt
3. 确保在项目根目录下运行脚本,或正确设置 PYTHONPATH
调用 OpenAI API 时报错 AuthenticationError API 密钥无效或未设置。 1. 检查 .env 文件是否存在且格式正确。
2. 检查环境变量 OPENAI_API_KEY 是否被成功加载。
3. 在代码中打印 os.getenv(“OPENAI_API_KEY”) 的前几位(勿打印全部)。
1. 确保 .env 文件在项目根目录,且密钥正确。
2. 重启终端或 IDE 使环境变量生效。
3. 在 OpenAI 官网检查密钥状态。
Agent 不调用 Skill,直接回答 1. Skill 描述 ( description ) 不够清晰。
2. 用户指令与 Skill 功能不匹配。
3. 模型 ( gpt-3.5-turbo ) 的推理能力有限。
1. 检查 WEATHER_SKILL_DESCRIPTION 中的 description parameters 是否准确描述了功能。
2. 尝试更明确的指令,如“ 使用天气工具查询 北京天气”。
3. 查看 API 返回的完整消息,确认 tool_calls 字段是否存在。
1. 优化 Skill 描述,使其目的和参数更明确。
2. 在系统提示词 ( system message ) 中强调 Agent 应优先使用工具。
3. 升级到 gpt-4 模型,其工具调用能力更强。
Skill 执行出错 1. Skill 函数内部代码有 bug。
2. 参数类型或格式错误。
3. 依赖的外部 API 不可用。
1. 单独运行 test_skill.py 测试 Skill 函数。
2. 在 _execute_skill 方法中添加更详细的错误日志。
3. 检查网络连接和外部 API 状态。
1. 修复 Skill 函数内的代码逻辑。
2. 在 Skill 函数中添加参数验证和类型转换。
3. 为外部 API 调用添加异常处理和备用方案。
Web API 服务 ( skill_server.py ) 无法访问 1. 端口被占用。
2. 防火墙阻止。
3. 服务未成功启动。
1. 检查终端是否有启动成功的日志。
2. 使用 netstat -ano | findstr :8000 (Win) 或 lsof -i:8000 (Mac/Linux) 查看端口占用。
3. 尝试访问 http://127.0.0.1:8000 /docs
1. 终止占用 8000 端口的进程,或修改 skill_server.py 中的端口号。
2. 确保在正确的网络环境下运行。
3. 查看终端错误信息并解决。

11. 最佳实践与项目部署建议

当你完成基础开发后,可以考虑以下步骤将项目工程化:

  1. 配置管理 :使用 pydantic-settings python-decouple 管理更复杂的配置,如不同环境的 API 端点、超时时间、日志级别等。
  2. 日志记录 :使用 logging 模块替代 print ,为不同级别(INFO, DEBUG, ERROR)的信息配置输出到文件和控制台,便于问题追踪。
  3. 错误处理与重试 :为所有外部调用(OpenAI API、Skill 的 HTTP 请求)添加完善的异常捕获、重试机制和断路器模式。
  4. 技能发现与自动注册 :可以通过扫描 skills 目录下的模块,自动发现并注册所有带有 *_SKILL_DESCRIPTION 变量的技能,避免手动维护注册列表。
  5. 测试 :为每个 Skill 编写单元测试 ( pytest ),为 Agent 的核心逻辑编写集成测试,确保代码质量。
  6. 容器化部署 :使用 Docker 将 Agent 服务和 Skill 服务分别容器化,通过 docker-compose 编排,实现环境一致性和便捷部署。
  7. API 网关与认证 :在生产环境,为 Skill 服务器添加 API 网关(如 Kong, Traefik)以实现限流、认证和监控。
  8. 监控与告警 :集成 Prometheus 和 Grafana 监控 API 调用延迟、成功率、Token 消耗等关键指标。

通过这个从零到一的实战流程,你已经掌握了 AI Agent 与 Skill 开发的核心链路: 定义技能、封装工具、集成大模型、处理交互、构建服务 。这个模式可以无限扩展,加入更多的 Skills(如发送邮件、查询数据库、控制智能家居),从而打造出功能强大的专属智能体。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐