AI Agent 实例开发实战:从零构建你的第一个智能代理

1次阅读
没有评论

共计 3251 个字符,预计需要花费 9 分钟才能阅读完成。

image.webp

1. 为什么需要 AI Agent?

传统脚本在处理固定流程任务时表现优异,但面对需要动态决策的场景就显得力不从心。比如天气预报查询,如果只是简单调用 API 返回数据,脚本完全可以胜任。但如果我们想要实现这样的功能:

AI Agent 实例开发实战:从零构建你的第一个智能代理

  • 根据用户输入自动判断是否需要查询天气(比如用户说 ” 明天需要带伞吗 ”)
  • 能够处理模糊地点(如 ” 我家附近 ” 需要结合用户位置信息)
  • 支持多轮对话(追问某地未来一周天气)

这时候传统脚本就需要写大量条件判断,而 AI Agent 通过结合 LLM 的推理能力和预定义工具集,可以更优雅地解决这类问题。

2. LangChain vs 裸调 LLM

2.1 纯 LLM 调用的痛点

直接调用大语言模型 API 开发 Agent 会遇到:

  • 提示工程 (Prompt Engineering) 复杂:需要精心设计 system message 和 few-shot 示例
  • 输出解析困难:LLM 返回的非结构化文本需要复杂正则匹配
  • 状态管理缺失:多轮对话需要自行维护上下文

2.2 LangChain 的优势

LangChain 框架提供了以下关键抽象:

  • 工具(Tools):将 API 封装成可描述、可调用的标准化接口
  • 代理(Agents):内置多种决策策略(ReAct, Self-ask 等)
  • 记忆(Memory):自动管理对话历史

下面我们通过天气预报 Agent 实例来具体演示。

3. 天气预报 Agent 完整实现

3.1 项目结构

weather_agent/
├── tools.py        # 工具定义
├── agent.py        # 代理核心逻辑
└── config.py       # 配置管理

3.2 工具模块实现

在 tools.py 中定义天气查询工具:

import requests
from typing import Optional
from pydantic import BaseModel

class WeatherInput(BaseModel):
    location: str
    date: Optional[str] = None

class WeatherTool:
    name = "get_weather"
    description = "查询指定地点和日期的天气情况"
    args_schema = WeatherInput

    @classmethod
    def run(cls, location: str, date: str = None):
        """调用天气 API 并格式化返回结果"""
        # 实际项目应该从配置读取 API KEY
        api_key = "your_api_key"
        base_url = "https://api.weatherapi.com/v1/forecast.json"

        params = {
            "key": api_key,
            "q": location,
            "days": 1 if not date else 7,
            "aqi": "no",
            "alerts": "no"
        }

        try:
            response = requests.get(base_url, params=params)
            response.raise_for_status()
            data = response.json()

            # 简化返回结构
            if date:
                forecast = next((day for day in data["forecast"]["forecastday"] 
                     if day["date"] == date),
                    None
                )
                return f"{location}{date}天气: {forecast['day']['condition']['text']}"
            else:
                current = data["current"]
                return f"{location}当前天气: {current['condition']['text']}, 温度{current['temp_c']}℃"

        except Exception as e:
            return f"天气查询失败: {str(e)}"

3.3 Agent 核心逻辑

在 agent.py 中初始化代理:

from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
from tools import WeatherTool

class WeatherAgent:
    def __init__(self):
        self.llm = ChatOpenAI(
            temperature=0,
            model_name="gpt-3.5-turbo"
        )

        self.tools = [WeatherTool]

        self.agent = initialize_agent(
            tools=self.tools,
            llm=self.llm,
            agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
            verbose=True,
            handle_parsing_errors=True
        )

    def query(self, input_text: str) -> str:
        """执行用户查询"""
        try:
            return self.agent.run(input_text)
        except Exception as e:
            return f"Agent 执行出错: {str(e)}"

3.4 配置管理

在 config.py 中处理敏感信息:

import os
from dotenv import load_dotenv

load_dotenv()

class Config:
    OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
    WEATHER_API_KEY = os.getenv("WEATHER_API_KEY")

    @classmethod
    def validate(cls):
        if not cls.OPENAI_API_KEY:
            raise ValueError("Missing OPENAI_API_KEY in .env")
        if not cls.WEATHER_API_KEY:
            raise ValueError("Missing WEATHER_API_KEY in .env")

4. 生产环境注意事项

4.1 API 限流策略

  • 为 WeatherTool 添加 @rate_limited 装饰器
  • 使用 Tenacity 库实现自动重试
from tenacity import (
    retry,
    stop_after_attempt,
    wait_exponential,
    retry_if_exception_type
)
import requests

@retry(stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=4, max=10),
    retry=retry_if_exception_type(requests.exceptions.RequestException)
)
def safe_api_call(url, params):
    response = requests.get(url, params=params)
    response.raise_for_status()
    return response

4.2 敏感信息管理

  • 永远不要将 API KEY 硬编码在代码中
  • 使用.env 文件 +python-dotenv 加载配置
  • 为不同环境 (开发 / 测试 / 生产) 使用不同的凭证

5. 常见问题及解决方案

5.1 工具函数缺乏幂等性

问题现象:网络超时导致 Agent 重复调用天气 API

解决方案:

  • 为工具函数添加唯一请求 ID
  • 实现本地结果缓存

5.2 LLM 输出解析失败

问题现象:Agent 无法理解 LLM 返回的动作指令

解决方案:

  • 使用 Pydantic 严格定义工具输入模式
  • 添加 try-catch 处理解析异常

5.3 上下文溢出

问题现象:长对话后 LLM 开始遗忘早期信息

解决方案:

  • 使用 ConversationSummaryMemory 自动摘要历史
  • 设置合理的 max_token_limit

6. 扩展思考

当前的 Agent 是顺序执行工具的,如何改进架构以支持:

  1. 并行工具调用(如同时查询天气和交通)
  2. 工具依赖管理(B 工具需要 A 工具的结果作为输入)
  3. 工具调用超时处理

欢迎在评论区分享你的设计方案!

正文完
 0
评论(没有评论)