大模型应用-进阶核心技能【09:Agent之ReAct模式实战】

W12 · 知识点09:Agent之ReAct模式实战

学习目标:从零实现ReAct Agent,让AI像维修工程师一样"想→查→再想→给结论"。


一、ReAct vs Function Calling

维度 Function Calling ReAct
工具选择 模型内部决定 Prompt显式定义
推理可见性 黑箱 每步可见
框架依赖 需API支持 纯Prompt
调试 较难 容易(看trace)

二、ReAct核心循环

复制代码
Thought: 我需要查这台设备的维修历史
Action: maintenance_history
Action Input: {"device_id": "DEV-002"}
Observation: 维修4次,总费用3250元
Thought: 4次维修较多,再查当前状态
Action: query_device
Action Input: {"device_id": "DEV-002"}
Observation: 状态=停机, 运行4200小时
Thought: 设备已停机且维修频繁
Final Answer: 建议评估是否更换设备...

三、动手练习

bash 复制代码
pip install openai
python scripts/09_react_agent.py

四、本知识点检验标准

  • 理解Thought→Action→Observation循环
  • 从零实现ReAct Agent
  • Agent能串联多工具完成复杂诊断

code

python 复制代码
"""
知识点09: ReAct Agent 实战
===========================
从零实现ReAct设备维修诊断Agent(不依赖LangChain)

pip install openai
"""

import os, json, re
from openai import OpenAI

client = OpenAI(
    api_key=os.environ.get("OPENAI_API_KEY", "sk-your-key"),
    base_url=os.environ.get("OPENAI_BASE_URL", "https://api.deepseek.com/v1"),
)

MOCK = {
    "devices": {"DEV-001": {"name": "1号空压机", "status": "运行中", "hours": 2350}, "DEV-002": {"name": "2号空压机", "status": "停机", "hours": 4200}, "DEV-003": {"name": "3号注塑机", "status": "运行中", "hours": 6800}},
    "history": {"DEV-001": [{"date": "2025-01-15", "fault": "进气阀漏气", "cost": 90}, {"date": "2025-03-20", "fault": "排气温度高", "cost": 500}], "DEV-002": [{"date": "2024-08-10", "fault": "电机过热", "cost": 800}, {"date": "2024-12-05", "fault": "E-07报警", "cost": 1200}, {"date": "2025-03-18", "fault": "漏油", "cost": 350}, {"date": "2025-05-22", "fault": "异响", "cost": 900}]},
    "inventory": {"空压机": [{"name": "进气阀密封件", "qty": 15}], "注塑机": [{"name": "加热圈", "qty": 6}], "通用": [{"name": "轴承6205-2RS", "qty": 20}]},
}

def tool_query_device(device_id): return json.dumps(MOCK["devices"].get(device_id, {"error": "不存在"}), ensure_ascii=False)
def tool_history(device_id):
    h = MOCK["history"].get(device_id, [])
    return json.dumps({"records": h, "count": len(h), "total_cost": sum(r["cost"] for r in h)}, ensure_ascii=False)
def tool_inventory(device_type): return json.dumps(MOCK["inventory"].get(device_type, MOCK["inventory"]["通用"]), ensure_ascii=False)
def tool_work_order(device_id, fault, priority):
    import random
    return json.dumps({"order_id": f"WO-{random.randint(1000,9999)}", "status": "已创建"}, ensure_ascii=False)

TOOLS = {"query_device": tool_query_device, "maintenance_history": tool_history, "spare_inventory": tool_inventory, "create_work_order": tool_work_order}

SYSTEM = """你是设备维修诊断助手。按ReAct格式思考和行动。
可用工具:
- query_device(device_id): 查设备状态(如DEV-001)
- maintenance_history(device_id): 查维修历史
- spare_inventory(device_type): 查备件库存(如"空压机")
- create_work_order(device_id, fault, priority): 创建工单

格式:
Thought: [你的分析]
Action: [工具名]
Action Input: [JSON参数]
或:
Thought: [最终分析]
Final Answer: [完整回答]"""

class ReActAgent:
    def __init__(self, max_steps=8):
        self.max_steps = max_steps

    def run(self, question):
        messages = [{"role": "system", "content": SYSTEM}, {"role": "user", "content": question}]
        print(f"\n👤 {question}")
        print("=" * 55)
        for step in range(self.max_steps):
            resp = client.chat.completions.create(model="deepseek-chat", messages=messages, temperature=0.3)
            text = resp.choices[0].message.content
            messages.append({"role": "assistant", "content": text})
            if "Final Answer:" in text:
                answer = text.split("Final Answer:")[-1].strip()
                print(f"\n✅ {answer}")
                return answer
            am = re.search(r'Action:\s*(\w+)', text)
            im = re.search(r'Action Input:\s*(\{.*?\})', text, re.DOTALL)
            if am:
                action = am.group(1)
                args = json.loads(im.group(1)) if im else {}
                thought = text.split("Action:")[0].replace("Thought:", "").strip()
                print(f"\n🧠 {thought}")
                print(f"🔧 {action}({json.dumps(args, ensure_ascii=False)})")
                try:
                    obs = TOOLS[action](**args) if action in TOOLS else '{"error":"未知工具"}'
                except Exception as e:
                    obs = json.dumps({"error": str(e)})
                print(f"📋 {obs}")
                messages.append({"role": "user", "content": f"Observation: {obs}"})
            else:
                messages.append({"role": "user", "content": "格式有误,请按Thought/Action/Action Input或Final Answer格式。"})
        return "达到步骤限制"

def main():
    print("=" * 60)
    print("  设备维修 ReAct Agent")
    print("=" * 60)
    agent = ReActAgent()
    for q in ["DEV-002维修了几次?还能继续用吗?", "3号注塑机需要什么备件?库存够吗?", "DEV-001排气温度高,帮我诊断并生成工单"]:
        agent.run(q)
        print("\n" + "=" * 60)

if __name__ == "__main__":
    main()
相关推荐
鱼日先生1 天前
Dify 中级实验(13):多 Agent 协作——如何编排多个智能体分工干活?
工作流·dify·ai agent·大模型应用·ai 训练
鱼日先生2 天前
Dify 中级实验(14):对话变量与状态管理——如何让工作流记住多轮对话的状态?
工作流·dify·ai agent·大模型应用·ai 训练
minhuan2 天前
大模型应用CI/CD全流程解析:打通模型训练、评估、部署自动化,应用持续迭代实践23.7
ci/cd·自动化·大模型应用·大模型应用ci/cd全流程解析·大模型应用工程体系
minhuan3 天前
向量数据库选型、向量化与检索调优,结合大模型搭建私有文档检索增强完整应用实践23.6
大模型应用·向量数据库介绍·rag系统调优·rag应用实践
llwszx6 天前
【Java/Go后端手撸原生Agent(第十一篇):RAG检索——给Agent加上“查资料“能力】
llm·向量检索·rag·ai智能体·大模型应用·agent开发·后端转ai
minhuan9 天前
低延迟高可用语音交互架构研究:大模型优化 VAD、唤醒与流式转录应用实践方案23.0
大模型应用·语音交互架构·vad语音活动检测·wake word唤醒词·流式转录
minhuan12 天前
主流大模型能力边界:GPT-4o、Claude3.5、Llama3、Qwen、DeepSeek横向对比22.6
qwen·大模型应用·llama3·gpt-4o·deepseek·主流大模型能力边界·claude3.5
AI_小站16 天前
Loop Engineering又是啥?一文讲清企业Agent落地的四层工程进化论
java·人工智能·架构·prompt·大模型开发·智能体·大模型应用
bloxed19 天前
大模型应用-进阶核心技能【13课:第二阶段工程化与部署】
langchain·大模型应用
minhuan20 天前
大模型上下文工程核心策略解析:窗口管理、消息编排、记忆压缩与检索增强应用实践21.8
人工智能·大模型应用·大模型上下文工程·上下文窗口管理·上下文消息编排·上下文记忆压缩