12-day3-ReAct Agent-实验2-交互式

升级 react_agent.py 为一个 交互式 ReAct Agent,并新增两个实用工具:

  1. get_current_time:获取当前时间(带时区)
  2. get_os_info:返回当前操作系统类型(Windows / macOS / Linux)

同时:

  • 支持用户循环输入问题
  • 输入 quitexit 退出
  • 保留清华源包查询功能

✅ 修改后的交互式 react_agent_2.py

tee react_agent_2.py <<'EOF'
# react_agent.py
import os
import platform
from datetime import datetime
from dotenv import load_dotenv
from langchain_core.tools import tool
from langchain.agents import AgentExecutor, create_react_agent
from langchain import hub
from langchain_openai import ChatOpenAI
import requests

# 加载 API Key
load_dotenv()

# ────────────────────────────────────────────────
# 🔧【工具 1:查询包在清华源是否可用】
# ────────────────────────────────────────────────
@tool
def check_package_on_tsinghua_mirror(package_name: str) -> str:
    """
    检查指定的 Python 包是否在清华大学 PyPI 镜像中可用。
    示例输出: "numpy: ✅ 可用,最新版本 1.26.4"
    """
    try:
        url = f"https://pypi.tuna.tsinghua.edu.cn/{package_name}/json"
        headers = {"User-Agent": "langchain-agent"}
        response = requests.get(url, headers=headers, timeout=8)

        if response.status_code == 200:
            data = response.json()
            version = data["info"]["version"]
            return f"{package_name}: ✅ 可用,最新版本 {version}"
        elif response.status_code == 404:
            return f"{package_name}: ❌ 未在 PyPI 或清华源中找到"
        else:
            return f"{package_name}: ⚠️ 镜像服务返回错误 {response.status_code}"
    except Exception as e:
        return f"查询失败: {str(e)}"

# ────────────────────────────────────────────────
# 🕒【工具 2:获取当前时间】
# ────────────────────────────────────────────────
@tool
def get_current_time(dummy: str = "") -> str:
    """
    获取当前日期和时间(中国标准时间)。
    参数 dummy 仅为满足工具调用格式,可忽略。
    示例输出: "2026-01-27 22:30:45 (CST)"
    """
    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    return f"{now} (CST)"

# 💻【工具 3:获取详细操作系统信息】
@tool
def get_os_info(dummy: str = "") -> str:
    """
    返回当前操作系统的详细类型和版本。
    - Windows / macOS:返回系统名称
    - Linux:尝试读取 /etc/os-release 获取发行版详情
    参数 dummy 仅为满足工具调用格式,可忽略。
    示例输出:
      "Ubuntu 22.04.4 LTS"
      "Windows"
      "macOS"
      "CentOS Linux 7 (Core)"
    """
    system = platform.system()
    
    if system == "Windows":
        return "Windows"
    
    elif system == "Darwin":
        return "macOS"
    
    elif system == "Linux":
        # 尝试读取标准 Linux 发行版标识文件
        release_files = [
            "/etc/os-release",
            "/etc/lsb-release",
            "/etc/redhat-release",
            "/etc/debian_version"
        ]
        
        for filepath in release_files:
            try:
                with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
                    content = f.read().strip()
                    if not content:
                        continue
                    
                    # 优先解析 os-release(最标准)
                    if filepath == "/etc/os-release":
                        lines = content.splitlines()
                        props = {}
                        for line in lines:
                            if "=" in line and not line.startswith("#"):
                                key, val = line.split("=", 1)
                                val = val.strip('"').strip("'")
                                props[key] = val
                        name = props.get("PRETTY_NAME") or props.get("NAME") or "Linux"
                        version = props.get("VERSION", "")
                        full = f"{name} {version}".strip()
                        return full if full != "" else "Linux"
                    
                    # 其他文件直接返回内容(通常是一行描述)
                    elif content:
                        # 清理多余空格和换行
                        first_line = content.split("\n")[0].strip()
                        if first_line:
                            return first_line
                    
            except (FileNotFoundError, PermissionError, OSError):
                continue  # 忽略无法读取的文件
        
        # 所有文件都失败,回退到通用 Linux
        return "Linux"
    
    else:
        return f"其他系统: {system}"

# ────────────────────────────────────────────────
# 🧠【LLM 配置:使用 Qwen via DashScope】
# ────────────────────────────────────────────────
llm = ChatOpenAI(
    model="qwen-max",
    temperature=0,
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    api_key=os.getenv("DASHSCOPE_API_KEY")
)

# 注册所有工具
tools = [check_package_on_tsinghua_mirror, get_current_time, get_os_info]

# ────────────────────────────────────────────────
# 📜【加载 ReAct 提示模板】
# ────────────────────────────────────────────────
prompt = hub.pull("hwchase17/react")

# ────────────────────────────────────────────────
# 🤖【创建 ReAct Agent】
# ────────────────────────────────────────────────
agent = create_react_agent(llm, tools, prompt)

# ────────────────────────────────────────────────
# ⚙️【创建执行器】
# ────────────────────────────────────────────────
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True,
    handle_parsing_errors=True,
    max_iterations=6  # 稍微放宽,支持多工具组合
)

# ────────────────────────────────────────────────
# 💬【交互式主循环】
# ────────────────────────────────────────────────
print("🚀 ReAct Agent 已启动!支持以下能力:")
print("  • 查询 PyPI 包是否在清华源可用")
print("  • 获取当前时间")
print("  • 识别操作系统类型")
print("\n请输入您的问题(输入 'quit' 或 'exit' 退出):\n")

while True:
    try:
        user_input = input("❓ 你: ").strip()
        if not user_input:
            continue
        if user_input.lower() in ("quit", "exit", "q"):
            print("👋 再见!")
            break

        print("\n🧠 Agent 正在思考...\n")
        result = agent_executor.invoke({"input": user_input})

        print("\n" + "=" * 60)
        print("🤖 Agent 回答:")
        print(result["output"])
        print("\n" + "—" * 60 + "\n")

    except KeyboardInterrupt:
        print("\n\n👋 用户中断,再见!")
        break
    except Exception as e:
        print(f"\n❌ 运行出错: {e}\n")
EOF

✅ 新增功能说明

功能 使用示例 说明
交互式输入 直接运行后输入问题 支持连续提问,直到输入 quit
查时间 “现在几点?”“今天几号?” 调用 get_current_time
查系统 “我用的是什么操作系统?”“这是 Windows 吗?” 调用 get_os_info
查包 “requests 在清华源吗?” 原有功能保留
组合任务 “我在 Linux 上,现在能用清华源装 torch 吗?” Agent 可能先查 OS,再查包

🧪 测试建议

你可以尝试以下问题:

现在几点?
我用的是什么系统?
我想在这个系统安装 Pypi,怎么安装?
numpy 在清华源上有吗?
我在 Windows 上,怎么用清华源安装 pandas?

Agent 会根据问题自动选择一个或多个工具,完成推理闭环。


posted @ 2026-01-27 22:45  船山薪火  阅读(19)  评论(0)    收藏  举报
![image](https://img2024.cnblogs.com/blog/3174785/202601/3174785-20260125205854513-941832118.jpg)