文章介绍

呀呼,距离上一篇Agent已经过去了几个月了,因为Agent和Python联系的太紧密,所以花费了几个月的时间学习了Python,现在我们将正式开始Agent的下一个阶段,从概念转到代码。

目前本篇主要讲解

  • 代码初体验:使用 LangChain 工具初步认识Agent的构建。
  • 工具选择:如何根据现有的各种工具选择合适的学习路线

注意事项

  1. 文章背景是Agent的学习历程,某方面来说没有已经深度学习过Agent的大佬有经验,但根据我目前的学习经历和资料查阅手段,能保证95%左右的正确性,同时绝对是基于目前最新的资料和模型
  2. 我是基于bilibili上的课程和Ai的辅助同步进行,内容方面会更加全面,Ai 搜索使用的是Gemini 3.0 ProAi调用使用的是Gemini 2.5 ,视频是 B站的字节跳动课程,链接 :目前B站最全最细的AI大模型零基础全套教程,2025最新版
  3. 文章都是边学习边记录的,如果有错误和更好的实现方案请大家及时指正。

一、调用LLM模型

💡 什么是LLM模型我就不做过多解释了,我们直接通过Python代码调用Ai大模型,看看怎么回复。

📝 前期准备

  • Python运行环境(我的是Python 3.11),当然并不需要版本一致,因为都是在虚拟环境运行的。
  • Python编译器如Pycharm
  • 一个Ai的密钥:可以选择Deepseek最便宜最方便,我这里使用的是Gemini 2.5
  • 一个科学上网的工具:VPN(根据情况选择,如果你是Deepseek就不用)

关于上述的准备工作大家自行解决,我就不提供教程了,如果要学习Agent这些是最基础最简单的。

🐛 详细代码步骤

  1. 创建一个空的项目(正常创建即可)。
    在这里插入图片描述
  2. 控制台依次执行命令

⚠️ 如果安装速度过慢,注意自己配置清华的Python镜像

python -m venv venv	# 安装虚拟环境

.\venv\Scripts\Activate.ps1		# 打开虚拟环境

python -m pip install --upgrade pip		# 更新pip

pip install --upgrade fastapi	# (可选)更新fastapi,因为我之前的版本比较旧

pip install google-generativeai   # 安装Google-Ai 依赖

python -c "import google.generativeai as genai; print('安装成功!')"	# 测试是否安装成功
  1. 创建两个文件:config.py 和 LLM_demo1.py (名称自定义)
    在这里插入图片描述
  2. config配置文件中的内容是你的API密钥
# Gemini API 配置文件

GEMINI_API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 
  1. 测试文件主要内容是:(注意运行的时候开启VPN
from google import genai
from config import GEMINI_API_KEY

# 从配置文件读取API Key
# 创建客户端,使用配置文件中的API Key
client = genai.Client(api_key=GEMINI_API_KEY)

# 自定义提示词 - 可以修改这里的内容
prompt = "Hello World"

# 调用模型生成内容
try:
    response = client.models.generate_content(
        model="gemini-2.5-flash", 
        contents=prompt
    )
    print("=" * 50)
    print("提示词:", prompt)
    print("=" * 50)
    print("AI回答:")
    print(response.text)
    print("=" * 50)
except Exception as e:
    print(f"发生错误: {e}")

在这里插入图片描述

到这里一个简单的用例就完成了,这是我们迈向Agent最基础也是最简单的一步。

二、使用LangChain构建第一个Agent

2.1 LangChain介绍

💡 LangChain 是一个开发框架(中间件),它的作用是把大模型(LLM)和外部世界连接起来。

  • 如果不使用 LangChain: 你只能像在网页上和 ChatGPT 聊天一样,给它发一段字,它回一段字。
  • 使用 LangChain: 你可以让大模型“长出手脚”。你可以把 PDF 文档、Google 搜索功能、数据库、计算器等工具封装好,通过 LangChain 交给大模型去调用。

它主要解决了两个痛点

  1. 统一接口: 不管你用 OpenAI、Gemini 还是 Claude,LangChain 帮你把代码写成通用的,换模型时改几行配置就行。
  2. 流程编排(Chain): 它能把多个步骤串起来(比如:先搜索 -> 再总结 -> 再翻译),这也是 Agent 的基础。

目前使用的情况

  • 这是2024年最流行的Agent构建工具,生态非常丰富。
  • 排除大型的商业项目使用的是自己写的Agent框架外,其余大部分都是用的是LangChain。

2.2 目前LangChain是否有必要学习

💡 答案是有必要,根据目前了解的资料来说,LangChain的地位就相当于Java的SpringMVC(我认为),这是Agent的基石,虽然随着技术的迭代更新后面又出现了LangGraph 、LlamaIndex等,目前最流行的如下:

  • LlamaIndex: 如果你的 Agent 主要是处理大量文档(RAG),LlamaIndex 在数据索引方面比 LangChain 更专业。
  • CrewAI / AutoGen: 如果你想做 Multi-Agent(多智能体协作),比如一个 Agent 负责写代码,一个负责测试,一个负责写文档。这两个框架目前比 LangChain 更火,尤其是 CrewAI,上手非常简单。
  • Vercel AI SDK: 如果你是做前端开发(Next.js/React),这个 SDK 比 LangChain 轻量得多,是目前 Web 开发者的首选
  • 原生代码 (No-Framework): 随着 Claude 3.5 Sonnet 和 GPT-4o 的能力增强,很多资深开发者开始抛弃笨重的框架,直接写 Python 代码调用 API,因为这样可控性最高。

LangChain 依然是行业标准,它的生态(文档加载器、向量数据库接口)是其他框架无法比拟的。招聘 JD 上通常也会要求会 LangChain

2.3 之后的学习路线

拿我来说,根据资料参考,我还是会基于LangChain 为首要选择进行学习和扩展,等到对于Agent的构建和了解达到一定程度之后再选择其它的工具根据实际业务进行练习,这非常像我们学习web开发一样,你首先得了解基础的Java、JavaScript、HTML、css等等,之后再考虑使用Spring、Vue的各种框架。

当然,根据实际开发过程中遇到的问题来说,我们大部分是基于LangChain的,但过程中还是会掺杂一些最新的技术,因为版本目前已经更新到这里了,不用还不行你说。

2.4 构建第一个Agent

📝 准备工作

🐛 构建步骤

  1. 创建一个新的项目,最好是虚拟环境,切换版本方便。
  2. 首先创建requirements.txt,这是Python开发常见的手段,版本依赖文件。
# LangChain核心框架 - 提供Agent、工具、链等核心功能
langchain>=1.1.0

# Google Gemini模型集成 - 用于连接Google Gemini API(如gemini-2.5-pro)
langchain-google-genai>=3.2.0

# LangChain社区工具 - 提供各种第三方工具集成(如DuckDuckGo搜索、llm-math等)
langchain-community>=0.3.0

# LangChain核心模块 - 提供工具基类、消息类型等核心抽象
langchain-core>=0.3.0

# LangGraph - Agent执行引擎,用于创建和执行ReAct Agent
langgraph>=1.0.0

# Python环境变量管理 - 用于从.env文件加载API密钥等配置
python-dotenv>=1.0.0

# DuckDuckGo搜索库 - 提供网络搜索功能,用于获取实时信息
ddgs>=0.1.0

# HTTP请求库 - 用于API连接测试和网络请求
requests>=2.28.0

# 数学表达式计算库 - LangChain的llm-math工具需要此库来执行数学计算
numexpr>=2.8.0

这里我们使用的是最新的 LangChain + LangGraph 组合,基于资料分析,旧版的纯 LangChain 已经非常不适合使用了,因为其大部分都是黑盒实现,我们自定义的不多,而且效果并不是那么优秀,这里我们不使用旧版本的。

⚠️ 注意一下,LangChain之前有着依赖地狱的称号,因为版本迭代太快,而且不同版本的使用方式大不相同,只是近期才慢慢趋于稳定,也是我们大部分人所能接受的版本,所以不建议学习1.0 版本之前的LangChain,即使有人还在使用,但是可用性实在是不推荐。

  1. 创建 .env 文件,维护Gemini的 API key。
GOOGLE_API_KEY=xxxxxxxxxxxxxxxxxxxxx	# 替换为自己的

这里要特别注意,GOOGLE_API_KEY 是固定的,是 python-dotenv 自动获取的,不要修改。

同时我们简单聊一聊密钥的管理问题,这里我们使用的是配置文件,类似Java的 yml 和 properties 文件,也是中小型项目最常用的一种手段,安全性也很高,只要不是你的服务器被彻底攻破了一般就没事。关于更高级的方案有两个:一是维护到专业的密钥管理第三方,通过他们提供的方式来拿到密钥。二是直接维护到环境变量中(这也是大多企业数采用的方案),第一种适用于中转方,比如业务中存在大量的API key,直接维护到环境变量中会很臃肿,所以采用第三方。

  1. 创建核心测试文件,类似 agent_demo.py
"""
LangChain Agent 示例
功能:回答关于当前中国主席信息的问题,包括姓名、年龄和年龄的平方和
"""

import os
import time
from dotenv import load_dotenv
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.messages import HumanMessage, AIMessage
from langchain.agents import create_agent

# 导入搜索工具
from langchain_community.tools import DuckDuckGoSearchRun
# 导入数学工具
from langchain_community.agent_toolkits import load_tools

# 步骤1:加载环境变量配置
# 从.env文件中加载API密钥
load_dotenv()

# 验证API密钥是否存在
api_key = os.getenv("GOOGLE_API_KEY")
if not api_key:
    raise ValueError(
        "请先在.env文件中配置GOOGLE_API_KEY!\n"
        "步骤:\n"
        "1. 复制.env.example为.env\n"
        "2. 在.env文件中填入您的Gemini 2.5 API密钥"
    )

# 确保环境变量已设置(init_chat_model可能需要)
os.environ["GOOGLE_API_KEY"] = api_key

# 步骤2:初始化LLM模型
# 使用ChatGoogleGenerativeAI初始化Gemini 2.5 Pro模型
# temperature=0.1 确保输出更稳定一致(对应官网的"一致响应的模型配置")

# 先测试API密钥和网络连接
print("\n[步骤1:测试API连接]")
try:
    import requests
    test_url = "https://generativelanguage.googleapis.com/v1beta/models?key=" + api_key
    print("  测试Google API连接...")
    response = requests.get(test_url, timeout=5)
    if response.status_code == 200:
        print("  ✅ API连接正常")
        # 显示可用的模型
        models_data = response.json()
        available_models = [m.get('name', '').replace('models/', '') for m in models_data.get('models', [])]
        print(f"  发现 {len(available_models)} 个可用模型")
        # 过滤gemini模型
        gemini_models = [m for m in available_models if 'gemini' in m.lower()]
        if gemini_models:
            print(f"  Gemini模型:{gemini_models[:5]}...")  # 只显示前5个
    else:
        print(f"  ⚠️ API连接异常:状态码 {response.status_code}")
except Exception as e:
    print(f"  ⚠️ API连接测试失败:{str(e)[:100]}")
    print("  继续尝试初始化模型...")

# 尝试多个模型名称,按优先级顺序
# 根据API返回的可用模型列表,优先使用2.5版本
model_names = [
    "gemini-2.5-flash",    # Gemini 2.5 Flash(快速版本,从API列表看到可用)
    "gemini-2.5-pro",      # Gemini 2.5 Pro(最新版本,从API列表看到可用)
    "gemini-1.5-flash",    # Gemini 1.5 Flash(备用)
    "gemini-1.5-pro",      # Gemini 1.5 Pro(备用)
    "gemini-pro",          # Gemini Pro(通用版本)
]

# 步骤2:初始化LLM模型对象(而不是使用字符串)
# 直接使用ChatGoogleGenerativeAI对象,更可靠且支持超时设置
print("\n[步骤2:初始化LLM模型]")
selected_model_obj = None
selected_model_name = None

for model_name in model_names:
    print(f"\n尝试初始化模型:{model_name}...")
    try:
        # 创建模型对象(只创建对象,不进行API调用,因此不会卡住)
        # 注意:简化参数,避免可能的参数错误导致初始化失败
        llm = ChatGoogleGenerativeAI(
            model=model_name,
            google_api_key=api_key,
            temperature=0.1,
            convert_system_message_to_human=True,  # 适配Gemini的消息格式要求
            transport="rest",  # <--- 关键修改:强制使用REST API,避开gRPC坑
            request_timeout=60  # 建议加上超时设置,避免无限等待
        )
        
        # 只验证对象是否创建成功,不进行实际的API调用测试
        # 实际的API调用会在Agent执行时进行,如果失败会自然抛出异常
        if llm is not None:
            print(f"  ✅ 模型 {model_name} 对象创建成功")
            selected_model_obj = llm
            selected_model_name = model_name
            break
        else:
            print(f"  ⚠️ 模型 {model_name} 对象创建失败")
    except Exception as e:
        print(f"  ⚠️ 模型 {model_name} 初始化失败:{str(e)[:100]}")
        continue

# 如果所有模型都失败,抛出错误
if selected_model_obj is None:
    raise RuntimeError(
        f"所有模型初始化失败!\n"
        f"尝试的模型:{model_names}\n"
        f"请检查:\n"
        f"1. API密钥是否正确\n"
        f"2. 网络连接是否正常\n"
        f"3. 模型名称是否可用"
    )

print(f"\n✅ 成功选择模型:{selected_model_name}")

# 步骤3:创建工具(对应官网的"创建可与外部数据集成的工具")
# 工具1:网络搜索工具 - 用于获取实时信息
search_tool = DuckDuckGoSearchRun()

# 工具2:数学计算工具 - 使用LangChain内置的llm-math工具
# 注意:llm-math工具需要numexpr库,如果没有安装会自动提示
print("\n[步骤3:创建工具]")
print("  创建搜索工具...")
print("  创建数学计算工具...")
try:
    # 使用LangChain内置的数学工具
    # llm-math工具可以让Agent自己进行数学计算,包括理解"年龄平方和"的含义
    math_tools = load_tools(["llm-math"], llm=selected_model_obj)
    calculator_tool = math_tools[0]  # load_tools返回工具列表
    print("  ✅ 使用LangChain内置的llm-math工具")
except Exception as e:
    print(f"  ⚠️ 无法加载llm-math工具:{e}")
    print("  提示:可能需要安装numexpr库:pip install numexpr")
    print("  将使用Agent自身的数学能力进行计算...")
    # 如果无法加载llm-math工具,可以创建一个简单的Python REPL工具
    # 或者直接让Agent自己计算(现代LLM如Gemini有很强的数学能力)
    calculator_tool = None

# 将所有工具组合成列表
if calculator_tool:
    tools = [search_tool, calculator_tool]
else:
    tools = [search_tool]  # 如果没有数学工具,Agent仍然可以使用自己的数学能力

# 步骤4:创建Agent提示模板(对应官网的"详细的系统提示有助于改善代理行为")
# 新版本的create_react_agent使用消息格式,prompt可以是字符串或SystemMessage
# 字符串会自动转换为SystemMessage并添加到消息列表开头
# ReAct模式:Reasoning + Acting,Agent会先思考(Reasoning)再行动(Acting)
system_prompt = """你是一个有用的AI助手。你可以使用工具来回答问题。

当需要获取实时信息时,使用搜索工具。
当需要进行数学计算时,可以使用计算工具,或者直接进行计算。

对于"年龄平方和"这类问题,你需要:
1. 先获取年龄信息(例如:71岁)
2. 理解"平方"的含义:
3. 可以使用计算工具进行计算,或者直接计算

请仔细思考问题,选择合适的工具,然后整合结果给出完整的答案。"""

# 步骤5:创建ReAct Agent
# create_agent会创建一个使用ReAct模式的Agent(返回一个可执行的graph)
# 注意:新版本的LangChain使用langchain.agents.create_agent
# system_prompt参数可以是字符串(会自动转换为SystemMessage)或SystemMessage对象
# 使用预初始化的模型对象,确保模型已正确配置超时和重试
print(f"\n[步骤5:创建Agent]")
print(f"使用模型:{selected_model_name}")
agent = create_agent(
    model=selected_model_obj,  # 使用预初始化的模型对象,而不是字符串
    tools=tools,
    system_prompt=system_prompt  # 字符串会自动转换为SystemMessage
)
print("✅ Agent创建成功")

# 步骤7:定义要回答的问题
question = "当前的中国主席是谁,他的年龄是多少岁,他年龄的平方是多少?"

# 步骤8:执行Agent并获取答案
if __name__ == "__main__":
    print("=" * 60)
    print("LangChain Agent 示例")
    print("=" * 60)
    print(f"\n问题:{question}\n")
    print(f"使用的模型:{selected_model_name}")
    print(f"工具数量:{len(tools)}")
    
    # 先测试搜索工具是否正常工作
    print("\n[测试搜索工具]")
    try:
        test_result = search_tool.run("test")
        print(f"搜索工具测试成功(返回长度:{len(str(test_result))}字符)")
    except Exception as e:
        print(f"⚠️ 搜索工具测试失败:{e}")
        print("这可能导致Agent卡住,请检查网络连接")
    
    print("\nAgent正在处理中...\n")
    print("-" * 60)
    
    try:
        # 执行Agent
        # 新版本的langgraph使用messages格式,需要将问题转换为HumanMessage
        print("正在调用Gemini API...")
        print("提示:如果长时间没有响应,可能是API调用超时,请按Ctrl+C中断")
        
        # 使用invoke模式(更稳定可靠)
        # 如果需要查看详细过程,可以改用stream模式
        USE_STREAM_MODE = True  # 设置为True使用stream模式查看详细过程
        
        print("\n[Agent执行过程]")
        print("-" * 60)
        
        start_time = time.time()
        final_result = None
        
        if USE_STREAM_MODE:
            # Stream模式:可以看到详细的执行过程
            print("使用Stream模式(可以看到详细执行过程)...")
            chunk_count = 0
            try:
                for chunk in agent.stream({"messages": [HumanMessage(content=question)]}, stream_mode="updates"):
                    chunk_count += 1
                    elapsed = time.time() - start_time
                    print(f"\n[收到chunk #{chunk_count}, 耗时: {elapsed:.1f}秒]")
                    
                    # 打印每个节点的更新
                    for node_name, node_output in chunk.items():
                        print(f"[节点: {node_name}]")
                        if "messages" in node_output:
                            messages = node_output["messages"]
                            for msg in messages:
                                if hasattr(msg, 'content') and msg.content:
                                    msg_type = type(msg).__name__
                                    content_preview = str(msg.content)[:200]
                                    print(f"  {msg_type}: {content_preview}...")
                                elif hasattr(msg, 'tool_calls') and msg.tool_calls:
                                    tool_names = [tc.get('name', 'unknown') for tc in msg.tool_calls]
                                    print(f"  AI消息: 调用工具 {tool_names}")
                        else:
                            print(f"  输出键: {list(node_output.keys())}")
                    final_result = node_output
                    
            except Exception as e:
                print(f"\n⚠️ Stream模式出错:{str(e)[:200]}")
                print("切换到invoke模式...")
                USE_STREAM_MODE = False
        
        if not USE_STREAM_MODE or final_result is None:
            # Invoke模式:更稳定,直接获取最终结果
            print("使用Invoke模式(等待Agent完成所有步骤)...")
            print("提示:Agent可能需要调用工具和多次思考,请耐心等待...")
            print("     如果超过60秒没有响应,可能是API调用问题,可以按Ctrl+C中断")
            
            try:
                # 使用invoke直接获取结果
                final_result = agent.invoke({"messages": [HumanMessage(content=question)]})
                elapsed_total = time.time() - start_time
                print(f"✅ Agent执行完成,总耗时: {elapsed_total:.1f}秒")
            except KeyboardInterrupt:
                elapsed = time.time() - start_time
                print(f"\n\n⏸️ 用户中断(已等待 {elapsed:.1f} 秒)")
                print("\n可能的原因:")
                print("1. Gemini API响应慢或超时(请检查网络连接)")
                print("2. 搜索工具调用超时(需要网络访问DuckDuckGo)")
                print("3. API密钥权限问题(请检查API密钥是否有效)")
                print("4. 模型初始化问题(请检查模型名称是否正确)")
                raise
        
        elapsed_total = time.time() - start_time
        print("-" * 60)
        print(f"\n[执行完成,总耗时: {elapsed_total:.1f}秒]")
        print("\n最终答案:")
        
        # 从messages中提取最后一条AI消息作为答案
        messages = final_result.get("messages", [])
        if messages:
            # 找到最后一条AI消息(不是工具消息)
            ai_messages = [msg for msg in messages if isinstance(msg, AIMessage)]
            if ai_messages:
                last_ai_message = ai_messages[-1]
                if hasattr(last_ai_message, 'content') and last_ai_message.content:
                    print(last_ai_message.content)
                else:
                    print("AI消息内容为空")
            else:
                print("未找到AI消息")
                print(f"消息类型: {[type(msg).__name__ for msg in messages]}")
        else:
            print("未找到消息")
            print(f"结果: {final_result}")
        print("\n" + "=" * 60)
        
    except KeyboardInterrupt:
        print("\n\n用户中断执行")
    except Exception as e:
        import traceback
        print(f"\n错误:{str(e)}")
        print("\n详细错误信息:")
        traceback.print_exc()
        print("\n提示:")
        print("1. 请检查.env文件中的GOOGLE_API_KEY是否正确配置")
        print("2. 请检查网络连接是否正常(搜索工具需要网络)")
        print(f"3. 请检查模型名称是否正确(当前:{selected_model_name})")
        print("   如果gemini-2.5-pro不可用,可以尝试:gemini-2.0-flash-exp 或 gemini-pro")
        print("4. 请检查是否安装了所有依赖:pip install -r requirements.txt")
        print("5. 如果搜索工具卡住,可能是网络问题或DuckDuckGo服务不可用")

💡 不要觉得这些代码很多很难,这都是最基础的代码,静下心来仔细看

我最开始是让Cursor直接生成的简单示例,很简洁,接近官方的例子,但后面出现了多种问题一直调试不同,所以慢慢完善得到了现在看起来非常复杂的一个版本,有以下需要注意的地方。

⚠️ 注意点

  • 关于导入的依赖不用太过于纠结每一个是干什么的,这都是官方的示例,每一个依赖都有自己的作用,根据代码就能清晰的明白。
  • 最开始有一步骤是测试API密钥和网络连接,这一个步骤是因为Gemini模型很容易因为VPN的波动而失败,从防御性编程来说这一步是有必要的。
  • model_names 中我使用的都是2.5 及以下版本,这是因为这个版本已经趋于稳定了,用于测试和学习再完美不过,当然你也可以选择Gemini 3.0 Pro。
  • ChatGoogleGenerativeAI 方法中最核心最核心的一个参数是:transport="rest",因为Google的官方API已经使用了最新的gRPC技术,国内调用很困难,所以我们使用REST风格最方便,如果不设置会一直卡住,当然你要是想使用gRPC,网上搜索VPN的代理配置和规则就可以实现。
  • create_agent核心方法中有参数:system_prompt,这是我们正常调用Ai的一个提示词,如果你对于prompt有研究就可以明白,如果在你提问前加上一些限制条件的说明,Ai给出的结果往往更加的准确,这就是新版的一个好处。
  • agent.stream 是可以看到调用过程的,agent.invoke是直接获取结果的,这是两个方法调用的区别。

📝 程序执行流程

在这里插入图片描述
📝 程序运行结果

在这里插入图片描述

根据现在的prompt来说,程序运行的结果是不稳定的,69、70、71等都有可能出现,我来解释一下为什么不是正确的答案:72岁。

  • 核心原因 1:Agent 的“盲目信任”机制

    • 直接问模型的话一般是可以得到准确答案的,类似这种知名的任务模型内部都有训练的数据,而且模型通常会有内部的“系统时钟”感知(知道大概是哪一年),所以能直接推理出大概年龄。
    • 现在我们使用的Agent模式,它的核心逻辑是ReAct(推理+行动),这里的行动指的就是从网络上搜索,而搜索结果往往是旧的数据,所以会导致Agent判断错误
    • Agent 的困境:Agent 必须根据“观察到的结果(Observation)”来回答。如果搜索工具告诉它“他是 70 岁”,Agent 就会抑制自己内部认为“他应该是 71 或 72 岁”的知识,选择信任工具返回的(过时)文本。
  • 核心原因 2:缺少“当前时间”锚点

    • Agent本身是无状态的,也就是没有时间的概念。
    • 基于推理模型来说,他可能会根据搜索结果来随机预测一个年份来计算。
  • 核心原因 3:Prompt 误导了计算逻辑

    • 我的prompt中明确写到了1. 先获取年龄信息,所以可能导致了Agent判断错误。

基于上面的分析,出现错误的答案是很正常的,我们一般有两种方式修复:

  • 通过给prompt增加当前时间的形式,实现类似LLM中时间感知 模块的功能,这是最简单的一种方式,这也是目前Agent的常用解决办法,也是最推荐的一种。
import datetime

# 获取当前日期
current_date = datetime.date.today().strftime("%Y年%m月%d日")

# 修改 System Prompt
system_prompt = f"""你是一个智能AI助手。今天是 {current_date}。

你的任务是回答关于人物信息的问题。

为了保证年龄计算的绝对准确,请严格遵守以下步骤:
1. 【搜索出生日期】:不要直接搜索"年龄",因为搜索结果可能是过时的。请使用搜索工具查找目标的"出生年月日"。
2. 【计算年龄】:根据"今天的日期({current_date})"和"出生日期",精确计算当前的周岁。
   - 算法:(当前年份 - 出生年份) - (如果当前月份日期 < 出生月份日期 则为1 否则为0)
3. 【计算平方】:使用数学工具或自身能力,计算该年龄数字的平方。

注意:搜索工具返回的摘要可能包含过时的年龄信息(例如去年的新闻),请忽略这些直接的年龄数字,只信任出生日期。
"""
  • 封装时间工具:之后Agent会自动调用。
from langchain.tools import tool
from datetime import datetime

@tool
def get_current_date(query: str = "") -> str:
    """
    当需要知道今天是哪一年、哪月、哪日时,必须调用此工具。
    返回格式为:YYYY-MM-DD
    """
    return datetime.now().strftime("%Y-%m-%d")

# 然后把这个工具加到 tools 列表里
tools = [search_tool, calculator_tool, get_current_date]

2.5 关于构建Agent示例的思考

关于上面的例子中输出不稳定的问题,不知道大家有没有一种疑问,难道我之后构建Agent都需要优化提示词或者自己定义工具吗?

如果你有这个疑问就代表你对于Agent的思考更近了一步,首先我们要明白一个问题,我们构建Agent的出发点一定是基于某一个具体的需求进行定制化,它一般都有一个核心且确定的流程,我们按照具体的流程让Agent去协调执行即可,所以不用纠结后面的问题。

如果你在进一步思考,那如果我的业务中流程复杂,一直会动态变化呢?

上面的例子就是一个标准化的流程,官方叫法是:Pipeline,而实际情况比较复杂,我们将引入多智能体编排(Multi-Agent Orchestration),也就是路由/监督者(Router/Supervisor)模式,既然流程不确定,那我们引入的核心就是预设“规则”和“管理者”

  • 以前的模式:你自己去指挥实习生,“先去查资料,然后去写报告”。(流程是你定死的)
  • 现在的模式:你只找项目经理(Supervisor)。你告诉他:“我要一份关于这个文件的竞品分析报告”。
    • 项目经理自己判断:先找“文件专员”读文件 -> 发现缺竞品信息 -> 找“搜索专员”查竞品 -> 资料齐了 -> 找“写作专员”写报告。

当然我们的思考就到这一步,这一章节我们不会更多的深入,只是现在有一个了解。

三、本章总结和下一章节预告

本章总结

💡 关于本章,两个代码例子认识了Agent,打开了迈向Agent的大门,但话糙理不糙,确实只是打开了大门而已,连入门都算不上,后面的知识庞达且复杂,不仅需要理论上的知识,还需要代码上的支持,所以加油吧!

下一章预告

💡 关于Agent的整体学习路线大致如下:

  • Agent基础理论知识(已完成)
  • Python系统学习(已完成)
  • Agent初体验(已完成)
  • Agent认知框架
  • LangChain系统学习
  • RAG 及 Transformer (初步计划)

目前我的学习计划很清晰,按照课程 + Ai 辅助的方法稳步向前,后续计划可能会微调,但整体是不变的,耗时的地方就在LangChain的系统学习和RAG,毕竟这是最多也是最核心的东西。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐