Agent Loop - main.py

"""

LangChain 1.0 - Agent 执行循环

本模块重点讲解:

  1. Agent 执行循环的详细过程
  2. 流式输出(streaming)
  3. 查看中间步骤
  4. 理解消息流转
    """

import sys
import os
from urllib import response

from openai import chat

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from init_model import get_chat_model

from langchain_core.tools import tool
from init_model import get_chat_model
from langchain.agents import create_agent

导入自定义工具

from tools import weather
from tools import web_search
from tools import calculator

初始化数据

weather_tool = weather.get_weather
web_search_tool = web_search.web_search
calculator_tool = calculator.calculator
chat_model = get_chat_model()

============================================================================

示例 1:理解执行循环 - 查看完整消息历史

============================================================================

def example_1():

"""
示例1:理解执行循环 - 查看完整消息历史

展示 Agent 执行过程中的所有消息,包括工具调用和模型回复
"""

agent = create_agent(model=chat_model, tools=[calculator_tool])  # 计算工具
response = agent.invoke({"messages": [{"role": "user", "content": "25 乘以 8"}]})

# 1. 查看完整历史
for msg in response["messages"]:
    print(f"{msg.__class__.__name__}: {msg.content}")

# 2.查看结果
print(response["messages"][-1].content)

============================================================================

示例 2:流式输出(Streaming)

============================================================================

def example_2():

"""
示例2:流式输出(Streaming)

展示 Agent 执行过程中的实时输出,适用于长任务
"""
agent = create_agent(
    model=chat_model, tools=[calculator_tool, weather_tool]
)  # 计算工具 #天气查询工具

message = [
    {
        "role": "user",
        "content": "北京今天天气怎么样?",
    }
]
for chunk in agent.stream({"messages": message}):
    # chunk 结构可能是 {'model': {'messages': [...]}} 或 {'tools': {'messages': [...]}}
    # 我们需要遍历 chunk 的值来找到 'messages' 列表
    for key, value in chunk.items():
        if isinstance(value, dict) and "messages" in value:
            messages_list = value["messages"]
            for msg in messages_list:
                # 获取内容
                content = getattr(msg, "content", "")

                # 1. 处理 AI 的回答 (流式或最终)
                if msg.type == "ai" and content:
                    # 使用 end="" 实现打字机效果
                    print(content, end="", flush=True)

                # 2. 处理工具的执行结果 (可选,如果你想看中间计算过程)
                elif msg.type == "tool" and content:
                    # 换行显示工具结果,避免和 AI 回答混在一起
                    print(f"\n[计算器结果]: {content}", flush=True)

                # 3. 处理工具调用意图 (可选,显示模型决定调用什么)
                elif (
                    msg.type == "ai"
                    and hasattr(msg, "tool_calls")
                    and msg.tool_calls
                ):
                    tool_name = msg.tool_calls[0].get("name", "unknown")
                    print(f"\n[模型决定调用工具]: {tool_name}...", flush=True)

============================================================================

示例 3:多步骤执行

============================================================================

def example_3():

"""
示例3:Agent 执行多个工具调用

理解复杂任务的执行过程
"""
agent = create_agent(
    model=chat_model,
    tools=[calculator_tool],
    system_prompt="你是一个数学助手。当遇到复杂计算时,分步骤计算。",
)
response = agent.invoke(
    {"messages": [{"role": "user", "content": "先算 10 加 20,然后把结果乘以 3"}]}
)

tool_calls_count = 0
for msg in response["messages"]:
    if hasattr(msg, "tool_calls") and msg.tool_calls:
        tool_calls_count += len(msg.tool_calls)
        print(f"工具调用 {tool_calls_count}: {msg.tool_calls}")

print(f"\n工具调用次数: {tool_calls_count}")
print(f"最终答案: {response['messages'][-1].content}")

============================================================================

示例 4:理解消息类型

============================================================================

def example_4():

"""
示例4:理解消息类型

展示不同消息类型的作用和区别
"""
agent = create_agent(
    model=chat_model, tools=[calculator_tool, weather_tool]
)  # 计算工具 #天气查询工具

response = agent.invoke(
    {"messages": [{"role": "user", "content": "北京今天天气怎么样?"}]}
)

print("\n消息类型分析:")
for msg in response["messages"]:
    msg_type = msg.__class__.__name__

    if msg_type == "HumanMessage":
        print(f"\n[HumanMessage] 用户输入")
        print(f"  内容: {msg.content}")
    elif msg_type == "AIMessage":
        if hasattr(msg, "tool_calls") and msg.tool_calls:
            print(f"\n[AIMessage] AI 决定调用工具")
            print(f"  工具: {msg.tool_calls[0]['name']}")
            print(f"  参数: {msg.tool_calls[0]['args']}")
        else:
            print(f"\n[AIMessage] AI 的最终回答")
            print(f"  内容: {msg.content}")
    elif msg_type == "ToolMessage":
        print(f"\n[ToolMessage] 工具执行结果")
        print(f"  工具: {msg.name}")
        print(f"  结果: {msg.content}")

print("\n\n消息类型总结:")
print(
    """
        HumanMessage  → 用户的输入
        AIMessage     → AI 的输出(可能包含 tool_calls 或最终答案)
        ToolMessage   → 工具的执行结果
        SystemMessage → 系统指令(通过 system_prompt 设置)
    """
)

if name == "__main__":

# example_1()
# example_2()
example_4()
添加新评论