04 构建你的第一个 AI Agent

本篇属于「AI Agent 开发实战系列」第 4 篇

前言

前三篇我们学习了 AI Agent 的核心概念、ReAct 模式原理,以及 MCP 协议的基础。现在是时候动手了------本篇将从零开始,一步步构建一个完整的、可工作的 AI Agent 应用。

这个 Agent 会具备以下能力:

  • 理解用户意图
  • 调用外部工具(天气查询、计算器、网络搜索)
  • 进行推理和规划
  • 返回有意义的结果

我们会使用 Python + LangChain + Claude API 来实现,代码简洁易懂,适合初学者。


核心概念回顾

Agent 的三个关键组件

  1. LLM(大语言模型):大脑,负责理解和推理
  2. Tools(工具集):手臂,执行具体操作
  3. Memory(记忆):神经,保存上下文和历史

ReAct 循环

scss 复制代码
用户输入 → 思考(Thought) → 行动(Action) → 观察(Observation) → 循环

环境准备

1. 安装依赖

bash 复制代码
# 创建虚拟环境
python3 -m venv agent-env
source agent-env/bin/activate

# 安装必要的包
pip install langchain langchain-anthropic python-dotenv requests

2. 配置 API Key

创建 .env 文件:

env 复制代码
ANTHROPIC_API_KEY=your_api_key_here

3. 验证环境

python 复制代码
from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")
response = llm.invoke("Hello, are you ready to be an agent?")
print(response.content)

第一步:定义工具集

Agent 需要一套工具来与外部世界交互。我们定义三个基础工具:

python 复制代码
import json
import requests
from typing import Any
from langchain_core.tools import tool

# 工具1:计算器
@tool
def calculator(expression: str) -> str:
    """
    执行数学计算。
    
    Args:
        expression: 数学表达式,如 "2 + 2" 或 "sqrt(16)"
    
    Returns:
        计算结果
    """
    try:
        # 使用 eval 需要谨慎,生产环境应使用更安全的方式
        result = eval(expression)
        return f"计算结果:{result}"
    except Exception as e:
        return f"计算错误:{str(e)}"

# 工具2:天气查询(模拟)
@tool
def get_weather(city: str) -> str:
    """
    查询指定城市的天气。
    
    Args:
        city: 城市名称
    
    Returns:
        天气信息
    """
    # 这里使用模拟数据,实际应调用真实 API
    weather_data = {
        "北京": "晴天,温度 15°C,风力 3 级",
        "上海": "多云,温度 18°C,风力 2 级",
        "深圳": "晴天,温度 22°C,风力 2 级",
        "杭州": "阴天,温度 16°C,风力 4 级"
    }
    return weather_data.get(city, f"暂无 {city} 的天气数据")

# 工具3:网络搜索(模拟)
@tool
def search_web(query: str) -> str:
    """
    搜索网络信息。
    
    Args:
        query: 搜索关键词
    
    Returns:
        搜索结果摘要
    """
    # 模拟搜索结果
    search_results = {
        "Python": "Python 是一种高级编程语言,以其简洁易学而著称。",
        "AI": "人工智能是计算机科学的一个分支,致力于创建能够执行通常需要人类智能的任务的系统。",
        "Agent": "AI Agent 是能够感知环境、做出决策并采取行动的自主系统。"
    }
    return search_results.get(query, f"未找到关于 '{query}' 的信息")

# 将工具收集到列表
tools = [calculator, get_weather, search_web]

第二步:创建 Agent

使用 LangChain 的 Agent 框架:

python 复制代码
from langchain_anthropic import ChatAnthropic
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

# 初始化 LLM
llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")

# 定义 Agent 的系统提示
system_prompt = """你是一个有用的 AI 助手。你可以使用以下工具来帮助用户:

1. calculator - 执行数学计算
2. get_weather - 查询天气信息
3. search_web - 搜索网络信息

当用户提出问题时,你应该:
1. 理解用户的意图
2. 选择合适的工具来解决问题
3. 基于工具的结果进行推理
4. 给出清晰的答案

如果你不确定是否需要使用工具,可以直接回答。
"""

# 创建提示模板
prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

# 创建 Agent
agent = create_tool_calling_agent(llm, tools, prompt)

# 创建 Agent 执行器
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,  # 打印详细的执行过程
    max_iterations=10,  # 最多执行 10 次迭代
)

第三步:运行 Agent

python 复制代码
# 测试用例 1:数学计算
print("=" * 50)
print("测试 1:数学计算")
print("=" * 50)
result = agent_executor.invoke({
    "input": "请计算 (100 + 50) * 2 的结果"
})
print(f"最终答案:{result['output']}\n")

# 测试用例 2:天气查询
print("=" * 50)
print("测试 2:天气查询")
print("=" * 50)
result = agent_executor.invoke({
    "input": "北京今天天气怎么样?"
})
print(f"最终答案:{result['output']}\n")

# 测试用例 3:复合问题
print("=" * 50)
print("测试 3:复合问题")
print("=" * 50)
result = agent_executor.invoke({
    "input": "北京天气怎么样?如果温度低于 20°C,建议穿什么衣服?"
})
print(f"最终答案:{result['output']}\n")

# 测试用例 4:知识查询
print("=" * 50)
print("测试 4:知识查询")
print("=" * 50)
result = agent_executor.invoke({
    "input": "什么是 AI Agent?"
})
print(f"最终答案:{result['output']}\n")

完整代码示例

将上述所有代码整合到一个文件 my_first_agent.py

python 复制代码
import os
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.tools import tool

# 加载环境变量
load_dotenv()

# ============ 定义工具 ============
@tool
def calculator(expression: str) -> str:
    """执行数学计算"""
    try:
        result = eval(expression)
        return f"计算结果:{result}"
    except Exception as e:
        return f"计算错误:{str(e)}"

@tool
def get_weather(city: str) -> str:
    """查询指定城市的天气"""
    weather_data = {
        "北京": "晴天,温度 15°C,风力 3 级",
        "上海": "多云,温度 18°C,风力 2 级",
        "深圳": "晴天,温度 22°C,风力 2 级",
        "杭州": "阴天,温度 16°C,风力 4 级"
    }
    return weather_data.get(city, f"暂无 {city} 的天气数据")

@tool
def search_web(query: str) -> str:
    """搜索网络信息"""
    search_results = {
        "Python": "Python 是一种高级编程语言,以其简洁易学而著称。",
        "AI": "人工智能是计算机科学的一个分支,致力于创建能够执行通常需要人类智能的任务的系统。",
        "Agent": "AI Agent 是能够感知环境、做出决策并采取行动的自主系统。"
    }
    return search_results.get(query, f"未找到关于 '{query}' 的信息")

tools = [calculator, get_weather, search_web]

# ============ 创建 Agent ============
llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")

system_prompt = """你是一个有用的 AI 助手。你可以使用以下工具来帮助用户:
1. calculator - 执行数学计算
2. get_weather - 查询天气信息
3. search_web - 搜索网络信息

当用户提出问题时,理解意图、选择合适的工具、进行推理、给出清晰的答案。"""

prompt = ChatPromptTemplate.from_messages([
    ("system", system_prompt),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

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

# ============ 运行 Agent ============
if __name__ == "__main__":
    # 交互式循环
    print("欢迎使用 AI Agent!输入 'quit' 退出。\n")
    
    while True:
        user_input = input("你:")
        if user_input.lower() == 'quit':
            print("再见!")
            break
        
        try:
            result = agent_executor.invoke({"input": user_input})
            print(f"Agent:{result['output']}\n")
        except Exception as e:
            print(f"错误:{str(e)}\n")

常见问题

Q1: Agent 没有调用工具怎么办?

原因:LLM 可能认为不需要工具就能回答。

解决方案

  • 在系统提示中明确指出何时应该使用工具
  • 调整 max_iterations 参数
  • 检查 LLM 是否支持 tool calling

Q2: 工具调用失败了怎么办?

原因:工具定义有问题或参数不匹配。

解决方案

python 复制代码
# 添加错误处理
@tool
def my_tool(param: str) -> str:
    """工具描述"""
    try:
        # 工具逻辑
        return result
    except Exception as e:
        return f"工具执行失败:{str(e)}"

Q3: 如何让 Agent 记住之前的对话?

解决方案:使用 ConversationBufferMemory

python 复制代码
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key="chat_history")

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True,
)

Q4: 如何限制 Agent 的权限?

解决方案

  • 只提供必要的工具
  • 在工具中添加权限检查
  • 使用沙箱环境执行代码

进阶拓展

1. 添加更多工具

python 复制代码
@tool
def send_email(to: str, subject: str, body: str) -> str:
    """发送邮件"""
    # 实现邮件发送逻辑
    return f"邮件已发送给 {to}"

@tool
def read_file(path: str) -> str:
    """读取文件内容"""
    with open(path, 'r') as f:
        return f.read()

2. 使用不同的 LLM

python 复制代码
# 使用 OpenAI
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4")

# 使用本地模型
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama2")

3. 持久化对话历史

python 复制代码
from langchain.memory import ConversationSummaryMemory

memory = ConversationSummaryMemory(
    llm=llm,
    memory_key="chat_history"
)

4. 添加日志和监控

python 复制代码
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 在 Agent 执行前后记录日志
logger.info(f"执行 Agent,输入:{user_input}")
result = agent_executor.invoke({"input": user_input})
logger.info(f"Agent 输出:{result['output']}")

最佳实践

  1. 工具设计

    • 工具应该单一职责
    • 提供清晰的文档字符串
    • 包含错误处理
  2. 提示工程

    • 系统提示要明确
    • 给出具体的使用示例
    • 定义 Agent 的角色和限制
  3. 性能优化

    • 使用 max_iterations 限制循环次数
    • 缓存工具结果
    • 异步调用工具
  4. 安全性

    • 验证工具输入
    • 限制可访问的资源
    • 记录所有操作
  5. 测试

    • 为每个工具编写单元测试
    • 测试 Agent 的各种场景
    • 监控 Agent 的性能

总结

本篇我们从零开始构建了一个完整的 AI Agent:

定义了工具集 :计算器、天气查询、网络搜索 ✅ 创建了 Agent :使用 LangChain 框架 ✅ 实现了 ReAct 循环 :思考→行动→观察 ✅ 提供了完整代码:可直接运行

这个 Agent 虽然简单,但包含了生产级 Agent 的所有核心要素。下一篇我们将学习如何让 Agent 拥有长期记忆,通过 RAG 技术增强其知识库。


下篇预告

第 5 篇:RAG 与 Agent 的结合

  • 什么是 RAG(检索增强生成)
  • 如何为 Agent 构建知识库
  • 向量数据库的选择和使用
  • 实战:构建一个能查询文档的 Agent

参考资料

相关推荐
ZWZhangYu1 小时前
【Gradio系列】使用 Gradio 快速构建机器学习图像分类实战
人工智能·机器学习·分类
溪饱鱼1 小时前
如何节省OpenClaw 80%的Token消耗
人工智能·aigc·ai编程
羽翼安全1 小时前
终端电脑视觉感知防拍屏软件 视觉感知防拍照软件
人工智能
霖大侠1 小时前
Towards Generalizable Scene Change Detection
人工智能·深度学习·机器学习
marteker1 小时前
Meta 用人工智能取代内容审核人员,并扩大人工智能支持机器人使用范围
人工智能·机器人
2601_950760791 小时前
UA-MHC H-2D(b)/EGSRNQDWL gp100四聚体-APC标记在抗原特异性T细胞检测中的应用
人工智能·深度学习·机器学习
Roselind_Yi2 小时前
技术拆解:《从音频到动效:我是如何用 Web Audio API 拆解音乐的?》
前端·javascript·人工智能·音视频·语音识别·实时音视频·audiolm
智算菩萨2 小时前
深度剖析GPT - 5.3 - Codex:技术架构、性能表现与国内API接入全攻略
人工智能·gpt·ai·chatgpt·架构·ai编程·codex
deephub2 小时前
知识引导上下文优化(KgCoOp):一种解决灾难性遗忘的 Prompt Tuning 机制
人工智能·深度学习·机器学习·微调·prompt