前言

今年年初我开始接触AI Agent,第一个感觉就是:大模型本身像一个知识渊博的专家,但它只会动嘴,不会动手。而Agent不一样,它不仅能说,还能调用工具、查阅资料、执行操作,像一个真正的助理。

举个例子:你问大模型“明天北京飞上海的机票多少钱”,它只能告诉你“请去携程查询”。但如果你问一个Agent,它会自己去查航班信息、比价、甚至帮你下单。

这篇文章就是我学习Agent开发过程中的笔记和总结,从最基础的概念开始,到最终搭建一个可运行的Agent应用。全程代码可复制运行。

一、什么是AI Agent?

1.1 大模型 vs Agent

先区分两个概念:

大模型(LLM) AI Agent(智能体)
能力 理解和生成文本 理解+推理+行动
工具使用 不支持 可调用外部工具(搜索、计算器、API等)
记忆 单次对话 可拥有长期记忆
自主性 被动回答 可主动规划和执行任务
典型例子 ChatGPT网页版 AutoGPT、Manus、Devin

一句话概括:大模型是大脑,Agent是大脑+手脚。

1.2 Agent的核心组成

一个完整的Agent包含三个部分:

  1. 大模型(LLM):负责理解任务、制定计划、生成输出

  2. 工具(Tools):Agent可以调用的外部能力,如搜索引擎、计算器、数据库、API接口等

  3. 编排层(Orchestration):决定Agent什么时候思考、什么时候调用工具、什么时候给出最终答案

1.3 Agent的工作流程

text

用户提问
    ↓
【思考】大模型理解问题,决定需要什么工具
    ↓
【行动】调用工具获取信息(如搜索、计算)
    ↓
【观察】接收工具返回的结果
    ↓
【循环】重复思考→行动→观察,直到信息足够
    ↓
【回答】给出最终答案

这个过程叫做 ReAct(Reasoning + Acting) 模式,即推理与行动交替进行。

二、环境搭建

2.1 安装依赖

bash

# 创建虚拟环境
conda create -n agent python=3.10 -y
conda activate agent

# 安装LangChain及相关组件
pip install langchain==0.1.0
pip install langchain-community==0.1.0
pip install langchain-openai==0.0.5
pip install openai==1.12.0
pip install python-dotenv
pip install duckduckgo-search  # 搜索引擎工具
pip install arxiv  # 学术论文搜索
pip install numexpr  # 数学表达式计算

2.2 配置API Key

在项目根目录创建 .env 文件:

bash

OPENAI_API_KEY=你的OpenAI密钥
# 如果用DeepSeek,填写DeepSeek的密钥
DEEPSEEK_API_KEY=你的DeepSeek密钥

或者直接使用本地Ollama模型(无需API Key),本文会展示两种方式。

三、你的第一个Agent

3.1 最简单的Agent

python

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain.tools import tool

load_dotenv()

# 初始化大模型
llm = ChatOpenAI(
    model="gpt-3.5-turbo",
    api_key=os.getenv("OPENAI_API_KEY"),
    temperature=0
)

# ==================== 定义工具 ====================

@tool
def add(a: int, b: int) -> int:
    """计算两个数字的和"""
    return a + b

@tool
def multiply(a: int, b: int) -> int:
    """计算两个数字的乘积"""
    return a * b

# 工具列表
tools = [add, multiply]

# ==================== 创建Agent ====================

from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个数学助手,擅长使用工具解决数学问题。"),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# ==================== 运行 ====================

if __name__ == "__main__":
    result = agent_executor.invoke({"input": "计算 23 乘以 17 加上 45 的结果"})
    print(f"最终答案: {result['output']}")

3.2 运行效果

text

> Entering new AgentExecutor chain...

Invoking: multiply with {'a': 23, 'b': 17}
返回: 391

Invoking: add with {'a': 391, 'b': 45}
返回: 436

> Finished chain.
最终答案: 436

Agent自动完成了两步操作:先乘后加。这就是Agent的核心能力——自主规划和执行。

四、给Agent装上更多工具

4.1 常用工具集合

python

from langchain.tools import DuckDuckGoSearchRun
from langchain_community.tools import ArxivQueryRun
from langchain.tools import WikipediaQueryRun
from langchain.utilities import WikipediaAPIWrapper
import requests
import json

# 1. 网络搜索工具
search = DuckDuckGoSearchRun()

# 2. 维基百科工具
wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())

# 3. 学术论文搜索
arxiv = ArxivQueryRun()

# 4. 当前时间工具
@tool
def get_current_time() -> str:
    """获取当前日期和时间"""
    from datetime import datetime
    return datetime.now().strftime("%Y年%m月%d日 %H:%M:%S")

# 5. 天气查询工具(调用免费API)
@tool
def get_weather(city: str) -> str:
    """查询城市天气,输入城市名称"""
    try:
        url = f"https://wttr.in/{city}?format=%C+%t"
        response = requests.get(url, timeout=5)
        return f"{city}天气:{response.text.strip()}"
    except:
        return "天气查询失败,请稍后重试"

# 所有工具
tools = [
    search,
    wikipedia,
    arxiv,
    get_current_time,
    get_weather
]

4.2 使用工具的完整Agent

python

from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

prompt = ChatPromptTemplate.from_messages([
    ("system", """你是一个全能的AI助手,可以使用以下工具来帮助用户:
- 搜索工具:查询最新的网络信息
- 维基百科:查询百科知识
- 学术论文:搜索学术文献
- 时间工具:获取当前时间
- 天气工具:查询城市天气

请根据用户的问题选择合适的工具,如果工具无法回答,请诚实告知。
"""),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(
    agent=agent, 
    tools=tools, 
    verbose=True,
    max_iterations=5  # 防止死循环
)

# 测试
questions = [
    "现在几点了?",
    "北京今天天气怎么样?",
    "帮我搜索一下什么是Transformer模型",
]

for q in questions:
    print(f"\n问题:{q}")
    result = agent_executor.invoke({"input": q})
    print(f"回答:{result['output']}")
    print("-" * 60)

五、ReAct原理详解

5.1 什么是ReAct?

ReAct = Reasoning(推理) + Acting(行动)

这是一种让大模型交替进行"思考"和"行动"的框架。每一步,模型会输出:

  • Thought(思考):分析当前状态,决定下一步做什么

  • Action(行动):调用某个工具,传入参数

  • Observation(观察):工具返回的结果

然后带着观察结果进入下一步思考,直到得出最终答案。

5.2 ReAct vs 普通调用

普通调用 ReAct Agent
过程 一次生成 多轮思考+行动
准确性 依赖模型内部知识 可查证外部信息
可解释性 黑盒 每一步都可追溯
幻觉风险 较高 较低(有事实依据)

5.3 手动实现ReAct(简化版)

python

import re

def react_agent(question, max_steps=5):
    """手动实现ReAct流程"""
    
    context = f"问题:{question}\n"
    
    for step in range(max_steps):
        print(f"\n--- 第 {step+1} 轮 ---")
        
        # 1. 让模型生成思考+行动
        prompt = f"""
你是一个AI助手,可以使用以下工具:
- search(query):搜索网络信息
- calculate(expression):计算数学表达式

当前已知信息:
{context}

请按照以下格式输出:
思考:<你的分析>
行动:<工具名(参数)>
"""
        
        # 模拟模型响应(实际使用中会调用LLM)
        # 这里为了演示,直接手动构造响应
        
        if "天气" in question and step == 0:
            # 模拟思考+行动
            print("思考:用户询问天气,需要调用搜索工具")
            print("行动:search(北京天气)")
            observation = "北京今天晴,气温15-25度"
            context += f"搜索结果显示:{observation}\n"
            
        elif step == 0:
            # 默认搜索
            print("思考:需要搜索相关信息")
            print("行动:search(" + question + ")")
            observation = "找到了相关信息..."
            context += f"搜索结果:{observation}\n"
        else:
            # 最终回答
            print("思考:已有足够信息,可以回答用户")
            print(f"最终回答:根据搜索结果,{question}的答案是...")
            break
    
    return "回答完成"

# 测试
react_agent("北京今天天气怎么样?")

六、带记忆的Agent

默认情况下,Agent每次调用都是独立的,不记得之前的对话。如果需要多轮对话记忆,需要添加记忆组件。

python

from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain

# 创建带记忆的Agent
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True,
    output_key="output"  # 重要:指定输出字段
)

# 创建Agent时传入memory
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True,
    handle_parsing_errors=True
)

# 多轮对话
print("带记忆的Agent,输入 'quit' 退出")
while True:
    user_input = input("\n你: ")
    if user_input.lower() == 'quit':
        break
    
    result = agent_executor.invoke({"input": user_input})
    print(f"AI: {result['output']}")

运行效果:

text

你: 我叫张三
AI: 你好张三!很高兴认识你。

你: 我叫什么名字?
AI: 你刚才说你叫张三。

七、使用本地模型替代OpenAI

如果你不想用OpenAI的API,可以用Ollama的本地模型:

bash

# 先确保Ollama在运行
ollama run deepseek-r1:7b

python

from langchain_community.llms import Ollama

# 使用本地模型
llm = Ollama(
    model="deepseek-r1:7b",
    base_url="http://localhost:11434",
    temperature=0.7
)

# 其余代码不变
# 直接用llm替换之前的ChatOpenAI

注意:本地模型在工具调用能力上可能不如GPT-4,但对于简单的工具调用(如搜索、计算),7B级别的模型已经够用。

八、实际项目:一个智能科研助手

下面是一个完整的示例,构建一个可以帮助研究人员完成文献检索和数据分析的Agent。

python

import os
import json
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.tools import tool
from langchain_community.tools import ArxivQueryRun
from dotenv import load_dotenv
import requests

load_dotenv()

# ==================== 初始化 ====================
llm = ChatOpenAI(
    model="gpt-3.5-turbo",
    temperature=0,
    api_key=os.getenv("OPENAI_API_KEY")
)

# ==================== 定义工具 ====================

@tool
def search_paper(topic: str) -> str:
    """搜索学术论文,输入研究主题"""
    arxiv = ArxivQueryRun()
    return arxiv.run(topic)

@tool
def get_paper_citation(title: str) -> str:
    """获取论文引用信息,输入论文标题"""
    # 简化版:模拟获取引用
    return f"论文《{title}》已被引用约45次"

@tool
def analyze_sentiment(text: str) -> str:
    """分析文本的情感倾向,返回正面/负面/中性"""
    # 简化版:模拟情感分析
    positive_words = ["好", "优秀", "创新", "显著", "有效"]
    negative_words = ["差", "问题", "不足", "局限"]
    
    score = 0
    for word in positive_words:
        if word in text:
            score += 1
    for word in negative_words:
        if word in text:
            score -= 1
    
    if score > 0:
        return "正面"
    elif score < 0:
        return "负面"
    else:
        return "中性"

@tool
def get_current_time() -> str:
    """获取当前时间"""
    from datetime import datetime
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

tools = [search_paper, get_paper_citation, analyze_sentiment, get_current_time]

# ==================== 创建Agent ====================

prompt = ChatPromptTemplate.from_messages([
    ("system", """你是一个科研助手,帮助研究人员完成以下任务:
1. 搜索和查找学术论文
2. 获取论文引用信息
3. 分析研究文本的情感倾向

请根据用户需求选择合适工具,用专业、简洁的语言回答。
"""),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
agent_executor = AgentExecutor(
    agent=agent, 
    tools=tools, 
    verbose=False,
    max_iterations=6,
    handle_parsing_errors=True
)

# ==================== 运行 ====================

if __name__ == "__main__":
    print("🤖 科研助手已启动")
    print("=" * 50)
    
    tasks = [
        "搜索关于Transformer模型的论文",
        "分析这段文本的情感:这项研究提出了一种创新的方法,显著提升了模型性能",
    ]
    
    for task in tasks:
        print(f"\n任务: {task}")
        result = agent_executor.invoke({"input": task})
        print(f"结果: {result['output']}")
        print("-" * 50)

九、常见问题与排错

问题 原因 解决方案
Agent陷入死循环 思考-行动循环无法终止 设置 max_iterations=5 限制循环次数
工具调用失败 工具参数格式不对 检查工具函数的参数定义,添加类型注解
API Key无效 密钥过期或填错 重新生成并配置环境变量
模型不支持工具调用 模型版本太旧 使用支持函数调用的模型(GPT-3.5-turbo-0613+)
本地模型无法调用工具 Ollama版本不支持 升级Ollama到最新版,或使用支持工具的模型
中文搜索结果不理想 搜索引擎对中文支持有限 添加中文搜索引擎工具(如Bing搜索)
记忆混乱 memory配置不当 检查 output_key 是否匹配

我遇到过的几个问题

问题一:本地DeepSeek模型调用工具时报错,说模型不支持function calling。解决方法是升级Ollama到最新版本,或使用 deepseek-r1:7b 的最新版镜像。

问题二:Agent在搜索工具返回大量文本后,处理速度变慢。解决方法是减少 max_iterations,并在工具返回时限制结果长度。

十、总结

本文完整介绍了AI Agent的开发过程:

内容 核心要点
Agent概念 大模型+工具+编排,能自主决策和行动
ReAct模式 思考→行动→观察→循环→回答
工具定义 使用 @tool 装饰器,添加类型注解和文档
记忆机制 ConversationBufferMemory实现多轮对话记忆
本地部署 用Ollama替代OpenAI,本地运行
实际案例 科研助手、天气查询、数学计算等

几个核心认知:

  1. Agent的本质是大模型+工具调用,关键是把"做什么"和"怎么做"分开

  2. 工具的定义要清晰,包括功能描述和参数说明,这直接影响Agent调用工具的准确性

  3. 必须设置循环上限,否则Agent可能陷入无限推理

  4. 本地模型(如DeepSeek 7B)已经可以做简单的工具调用,但复杂任务仍需要更强的模型

下一步可以做什么:

  1. 接入更多工具(数据库查询、文件读写、邮件发送等)

  2. 使用多Agent协作(多个Agent分工完成复杂任务)

  3. 给Agent加上记忆增强(长期记忆、向量检索)

  4. 部署为Web API服务

📌 本文所有代码已整合在文中,复制即可运行。如遇问题欢迎评论区交流。


如果本文对你有帮助,欢迎点赞、收藏、转发!

参考资料

  1. LangChain官方文档:https://python.langchain.com

  2. ReAct原论文:[2210.03629] ReAct: Synergizing Reasoning and Acting in Language Models

  3. OpenAI Function Calling文档:https://platform.openai.com/docs/guides/function-calling

  4. Ollama官方文档:https://github.com/ollama/ollama

  5. 智谱AI Agent相关文档:Z.ai - Inspiring AGI to Benefit Humanity

推荐标签

AI Agent LangChain 大模型 Agent开发 ReAct

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐