Agent学习三:构建第一个 Agent(详细完整版)

设计目标 :通过渐进式实战,亲手构建具备工具调用能力的 Agent,掌握从零到一的完整开发流程,建立"可调试、可扩展、安全可靠"的工程化思维。所有代码均适配 Linux 环境

3.1 环境初始化(5 分钟快速就绪)

bash 复制代码
# 激活模块一配置的环境
source ~/agent-env/bin/activate

# 安装精准版本依赖(避免 LangChain 大版本变动导致示例失效)
pip install "langchain==0.1.16" "langchain-community==0.0.34" \
            "langchain-core==0.1.46" "requests==2.31.0" \
            "python-dotenv==1.0.0" "tqdm==4.66.1"

# 创建标准项目结构
mkdir -p my-first-agent/{tools,agents,config,logs}
cd my-first-agent
touch __init__.py tools/__init__.py agents/__init__.py .env .gitignore requirements.txt

.env 安全模板

bash 复制代码
# LLM 配置(三选一)
OPENAI_API_KEY=sk-...
# ANTHROPIC_API_KEY=sk-...
# LOCAL_MODEL_ENDPOINT=http://localhost:11434/api/generate  # Ollama

# 安全沙箱配置
ALLOWED_LINUX_COMMANDS=ls,pwd,cat,df,du
COMMAND_TIMEOUT=5

3.2 核心实战:三阶段渐进式开发

🌱 实战学习一:基础 ReAct Agent(天气查询助手)

tools/weather_tool.py

python 复制代码
import requests
from langchain.tools import Tool
from dotenv import load_dotenv
import os

load_dotenv()

def get_weather(city: str) -> str:
    """
    安全封装天气查询(模拟 API,实际项目替换为真实服务)
    安全设计:城市名校验 + 超时控制 + 错误隔离
    """
    # 白名单校验(防 Prompt Injection)
    allowed_cities = ["beijing", "shanghai", "guangzhou", "shenzhen", "hangzhou"]
    city_clean = city.strip().lower()
    
    if city_clean not in allowed_cities:
        return f"❌ 仅支持查询: {', '.join(allowed_cities)}。您输入了: {city}"
    
    try:
        # 实际项目替换为和风天气/彩云天气 API
        # 此处用 mock 数据避免依赖外部服务
        mock_data = {
            "beijing": "🌤️ 北京: 晴, 28°C, 微风",
            "shanghai": "🌧️ 上海: 小雨, 26°C, 东南风3级",
            "guangzhou": "⛈️ 广州: 雷阵雨, 31°C, 南风2级"
        }
        return mock_data.get(city_clean, f"🌤️ {city_clean.capitalize()}: 晴, 25°C")
    except Exception as e:
        return f"⚠️ 天气服务异常: {str(e)[:50]}"

# 注册为 LangChain Tool
weather_tool = Tool(
    name="get_weather",
    func=get_weather,
    description=(
        "查询中国主要城市的实时天气。"
        "参数: 城市英文名(小写,如 beijing)。"
        "注意: 仅支持 beijing/shanghai/guangzhou/shenzhen/hangzhou"
    )
)

agents/weather_agent.py

python 复制代码
from langchain.agents import create_react_agent, AgentExecutor
from langchain.prompts import PromptTemplate
from langchain_community.llms import Ollama  # 本地模型,无需网络
from tools.weather_tool import weather_tool
import logging

# 配置日志(Linux 工程师熟悉的方式)
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s | %(levelname)s | %(message)s',
    handlers=[
        logging.FileHandler("logs/agent.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

def create_weather_agent():
    # 1. 选择本地模型(适配 Linux 环境)
    llm = Ollama(
        model="qwen:7b",  # 需提前 ollama pull qwen:7b
        temperature=0.3,   # 降低随机性,提升工具调用稳定性
        timeout=120
    )
    
    # 2. 定制 ReAct Prompt(关键!注入领域知识)
    template = """你是一个严谨的天气查询助手,严格遵守以下规则:
1. 用户问天气时,必须调用 get_weather 工具
2. 城市名必须转为小写英文(如"北京"→"beijing")
3. 若工具返回错误,明确告知用户限制范围
4. 最终回答需包含emoji和实用建议(如"适合带伞")

工具描述:
{tools}

使用以下格式:
Question: 用户问题
Thought: 分析需求
Action: 工具名 参数
Observation: 工具返回
...(可重复)
Final Answer: 清晰结论

当前问题: {input}
{agent_scratchpad}"""
    
    prompt = PromptTemplate.from_template(template)
    
    # 3. 创建 Agent
    agent = create_react_agent(llm, [weather_tool], prompt)
    executor = AgentExecutor(
        agent=agent,
        tools=[weather_tool],
        verbose=True,      # 关键:输出思考过程
        handle_parsing_errors=True,  # 防止 LLM 格式错误崩溃
        max_iterations=5   # 防止无限循环
    )
    
    logger.info("✅ Weather Agent 初始化成功")
    return executor

# CLI 入口(Linux 工程师熟悉的交互方式)
if __name__ == "__main__":
    agent = create_weather_agent()
    print("🌤️ 天气助手已启动 (输入 'quit' 退出)")
    print("-" * 50)
    
    while True:
        try:
            user_input = input("\n👤 你的问题: ").strip()
            if user_input.lower() in ["quit", "exit"]:
                break
            if not user_input:
                continue
                
            result = agent.invoke({"input": user_input})
            print(f"\n🤖 助手: {result['output']}")
            
        except KeyboardInterrupt:
            print("\n⚠️ 用户中断")
            break
        except Exception as e:
            logger.error(f"Agent 执行异常: {e}")
            print(f"❌ 系统错误: {str(e)[:100]}")
    
    print("\n👋 感谢使用!日志已保存至 logs/agent.log")

运行验证

bash 复制代码
cd my-first-agent
python agents/weather_agent.py
# 输入: "上海明天天气如何?" 
# 预期输出: 🌧️ 上海: 小雨, 26°C, 东南风3级 → 建议携带雨具
相关推荐
盐焗西兰花2 小时前
鸿蒙学习实战之路-Share Kit系列(16/17)-隔空传送与可信任设备
学习·华为·harmonyos
少许极端3 小时前
算法奇妙屋(四十二)-贪心算法学习之路 9
学习·算法·贪心算法
EmbeddedCore3 小时前
MQTT协议学习笔记(深入解析版)
笔记·学习
WYT王玉桐4 小时前
LINUX学习
学习
H Journey4 小时前
openCV学习之-腐蚀
人工智能·opencv·学习
AI成长日志5 小时前
【算法学习专栏】动态规划基础·简单三题精讲(70.爬楼梯、118.杨辉三角、121.买卖股票的最佳时机)
学习·算法·动态规划
嵌入式小企鹅5 小时前
阿里编程模型赶超、半导体涨价蔓延、RISC-V新品密集上线
人工智能·学习·ai·程序员·risc-v·芯片
艾莉丝努力练剑5 小时前
【Linux系统:信号】线程安全不等于可重入:深度拆解变量作用域与原子操作
java·linux·运维·服务器·开发语言·c++·学习
red_redemption5 小时前
自由学习记录(155)
学习