AI Agent 开发实战:从 Function Calling 到 Multi-Agent 协作

3 阅读9分钟

AI Agent 开发实战:从 Function Calling 到 Multi-Agent 协作

2026 年,AI Agent 已经从学术概念变成了工程实践。本文从零开始,带你理解 Agent 的核心机制,掌握 Function Calling、ReAct 范式、工具编排,最终实现多智能体协作系统。


一、什么是 AI Agent?

简单来说,AI Agent = LLM + 工具 + 记忆 + 规划

传统的 LLM 只能"说话",而 Agent 能"做事"。

能力传统 LLMAI Agent
回答问题
搜索网页
读写文件
调用 API
执行代码
制定计划
多步推理有限

Agent 的核心循环:

感知 → 思考 → 行动 → 观察 → 思考 → 行动 → ...

这个循环会持续进行,直到任务完成。


二、Function Calling:Agent 的手和脚

Function Calling(函数调用)是让 LLM 能调用外部工具的关键技术。几乎所有主流模型都支持:

  • OpenAI:tools 参数
  • Anthropic Claude:tool_use
  • 智谱 GLM:tools 参数
  • 通义千问:tools 参数

2.1 基本原理

你告诉模型"你有这些工具可用",模型在需要时决定调用哪个工具、传什么参数。

定义工具:

{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "获取指定城市的天气信息",
    "parameters": {
      "type": "object",
      "properties": {
        "city": {
          "type": "string",
          "description": "城市名称"
        },
        "unit": {
          "type": "string",
          "enum": ["celsius", "fahrenheit"],
          "description": "温度单位"
        }
      },
      "required": ["city"]
    }
  }
}

模型响应:

{
  "tool_calls": [{
    "function": {
      "name": "get_weather",
      "arguments": "{\"city\": \"北京\", \"unit\": \"celsius\"}"
    }
  }]
}

你执行函数,把结果返回给模型,模型再生成最终回答。

2.2 实际代码示例(Python + OpenAI)

from openai import OpenAI
import json

client = OpenAI()

# 定义工具
tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "获取指定城市的天气",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "城市名"}
            },
            "required": ["city"]
        }
    }
}, {
    "type": "function",
    "function": {
        "name": "search_flights",
        "description": "搜索航班信息",
        "parameters": {
            "type": "object",
            "properties": {
                "from_city": {"type": "string", "description": "出发城市"},
                "to_city": {"type": "string", "description": "目的城市"},
                "date": {"type": "string", "description": "出发日期"}
            },
            "required": ["from_city", "to_city", "date"]
        }
    }
}]

# 模拟工具实现
def get_weather(city):
    data = {"北京": "晴,25°C", "上海": "多云,28°C", "深圳": "阵雨,30°C"}
    return data.get(city, "暂无该城市天气数据")

def search_flights(from_city, to_city, date):
    return f"找到 {from_city}{to_city} 的航班,日期 {date},票价 ¥580 起"

# 工具分发器
tool_map = {
    "get_weather": get_weather,
    "search_flights": search_flights,
}

# Agent 循环
messages = [{"role": "user", "content": "北京明天天气怎么样?帮我查查北京飞上海的航班"}]

while True:
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        tools=tools,
        tool_choice="auto"
    )
    
    message = response.choices[0].message
    messages.append(message)
    
    # 如果模型决定调用工具
    if message.tool_calls:
        for tool_call in message.tool_calls:
            func_name = tool_call.function.name
            func_args = json.loads(tool_call.function.arguments)
            
            # 执行函数
            result = tool_map[func_name](**func_args)
            
            # 将结果返回给模型
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": str(result)
            })
    else:
        # 没有更多工具调用,输出最终回答
        print(message.content)
        break

输出:

北京明天天气晴朗,气温约25°C。我已经帮你查到北京飞上海的航班,票价580元起。需要我帮你查看具体航班时刻吗?

这就是一个最简单的 Agent——模型自主决定调用哪些工具、传什么参数,然后根据结果继续对话。


三、ReAct 范式:推理 + 行动

ReAct(Reasoning + Acting) 是 Agent 设计的核心范式,由 Yao et al. 2022 提出。

3.1 核心思想

让模型在每一步都先思考(Thought),再行动(Action),然后观察(Observation)。

Question: 用户想订一张从北京到上海的机票

Thought 1: 我需要先搜索航班信息
Action 1: search_flights("北京", "上海", "2026-04-15")
Observation 1: 找到3个航班,CA1234 ¥580, MU5678 ¥620, HU9012 ¥550

Thought 2: 机票已找到,我应该把结果整理给用户
Action 2: finish("找到3个航班:CA1234 ¥580、MU5678 ¥620、HU9012 ¥550")

3.2 代码实现

def react_agent(question, tools, max_steps=10):
    messages = [
        {"role": "system", "content": 
         "你是一个智能助手。对于每个问题,先思考(Thought),再行动(Action)。\n"
         "格式:\n"
         "Thought: 你的思考过程\n"
         "Action: 工具名(参数)\n"
         "当你认为可以回答时:\n"
         "Thought: 我已经有了足够的信息\n"
         "Answer: 最终回答"},
        {"role": "user", "content": question}
    ]
    
    for step in range(max_steps):
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools
        )
        
        msg = response.choices[0].message
        messages.append(msg)
        
        if msg.content and "Answer:" in msg.content:
            return msg.content.split("Answer:", 1)[1].strip()
        
        if msg.tool_calls:
            for tc in msg.tool_calls:
                result = tool_map[tc.function.name](
                    **json.loads(tc.function.arguments))
                messages.append({
                    "role": "tool",
                    "tool_call_id": tc.id,
                    "content": str(result)
                })
    
    return "达到最大步骤数,无法完成"

四、Agent 框架选择

4.1 主流框架对比

框架语言特点适合场景
LangChainPython/JS生态最丰富,社区最大通用 Agent 开发
LlamaIndexPythonRAG 能力最强知识库问答
OpenAI Assistants APIRESTOpenAI 原生,简单易用快速原型
AutoGenPython多 Agent 对话多智能体协作
CrewAIPython角色扮演式多 Agent团队协作任务
Dify开源平台可视化编排非开发者友好

4.2 LangChain 示例

from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool

# 定义工具
@tool
def calculate(expression: str) -> str:
    """计算数学表达式"""
    try:
        return str(eval(expression))
    except:
        return "计算错误"

@tool
def search_web(query: str) -> str:
    """搜索网页信息"""
    return f"搜索结果:关于 '{query}' 的最新信息..."

# 创建 Agent
llm = ChatOpenAI(model="gpt-4o")
tools = [calculate, search_web]
agent = create_openai_tools_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# 运行
result = executor.invoke({
    "input": "帮我算一下 (150 * 28) + 3650,然后搜索这个数字代表什么"
})
print(result["output"])

4.3 Dify 可视化编排

如果不想写代码,Dify 是一个很好的选择:

  1. 在 Dify 中创建应用 → 选择 Agent 类型
  2. 可视化添加工具节点(搜索、代码、HTTP 请求等)
  3. 配置 Prompt 和推理策略
  4. 一键发布为 API 或 Web 应用

五、Multi-Agent:多智能体协作

单个 Agent 能力有限,复杂任务需要多个 Agent 分工协作。

5.1 常见协作模式

模式一:主从模式(Supervisor)

用户 → Supervisor Agent → 分发给专业 Agent
                          → Researcher(搜索调研)
                          → Coder(写代码)
                          → Reviewer(审查)
                          ← 汇总结果

模式二:对等模式(Peer-to-Peer)

Product Manager Agent ←→ Developer Agent ←→ QA Agent
        ↓                        ↓                   ↓
   需求分析                  编写代码              测试验证

模式三:流水线模式(Pipeline)

Researcher → Writer → Editor → Publisher
  搜索调研    撰写内容   审核修改    发布上线

5.2 CrewAI 实战:内容创作团队

from crewai import Agent, Task, Crew, Process

# 定义 Agent 角色
researcher = Agent(
    role="资深技术研究员",
    goal="深入研究给定主题,收集全面的信息",
    backstory="你是一名有10年经验的技术研究员,擅长快速搜集和分析技术资料",
    verbose=True,
    allow_delegation=False,
)

writer = Agent(
    role="技术博客作者",
    goal="基于研究结果撰写高质量的技术文章",
    backstory="你是一名优秀的技术写手,善于将复杂概念用通俗语言解释",
    verbose=True,
    allow_delegation=False,
)

reviewer = Agent(
    role="技术审稿人",
    goal="审核文章的准确性和可读性,提出改进建议",
    backstory="你是一名严谨的技术审稿人,关注事实准确性和文章结构",
    verbose=True,
    allow_delegation=False,
)

# 定义任务
research_task = Task(
    description="深入研究 {topic} 的最新技术趋势和实践方案",
    expected_output="详细的技术调研报告",
    agent=researcher,
)

write_task = Task(
    description="基于调研报告,撰写一篇关于 {topic} 的技术博客",
    expected_output="完整的博客文章草稿",
    agent=writer,
    context=[research_task],
)

review_task = Task(
    description="审核文章草稿,确保内容准确、结构清晰、有深度",
    expected_output="审核意见和修改后的文章",
    agent=reviewer,
    context=[write_task],
)

# 组建团队并执行
crew = Crew(
    agents=[researcher, writer, reviewer],
    tasks=[research_task, write_task, review_task],
    process=Process.sequential,
    verbose=True,
)

result = crew.kickoff(inputs={"topic": "AI Agent 开发实战"})
print(result)

5.3 MCP:Agent 的标准工具协议

MCP(Model Context Protocol) 是 Anthropic 提出的开放协议,让 Agent 能标准化地连接各种外部工具和数据源。

为什么需要 MCP?

之前:每个 Agent 框架都要自己对接每个工具 → N × M 的对接工作
现在:工具实现 MCP Server → 所有 Agent 都能调用 → N + M 的对接工作

MCP 架构:

AI Agent (MCP Client) ←→ MCP Server (工具)
                           ├── 文件系统
                           ├── 数据库
                           ├── 搜索引擎
                           ├── GitHub
                           ├── Slack / 飞书
                           └── 自定义工具...

六、Agent 记忆系统

6.1 三种记忆类型

类型说明实现
短期记忆当前对话上下文messages 数组
中期记忆会话级持久化Redis / SQLite
长期记忆跨会话的知识向量数据库

6.2 长期记忆实现

from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

# 向量存储
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(persist_directory="./memory", 
                     embedding_function=embeddings)

# 保存记忆
def save_memory(user_id, content):
    vectorstore.add_texts(
        texts=[content],
        metadatas=[{"user_id": user_id, 
                    "timestamp": datetime.now().isoformat()}]
    )

# 检索记忆
def retrieve_memory(user_id, query, k=5):
    results = vectorstore.similarity_search(query, k=k)
    return [doc.page_content for doc in results 
            if doc.metadata.get("user_id") == user_id]

# 在 Agent 响应前注入相关记忆
memories = retrieve_memory("user_001", "用户之前问过什么关于 Agent 的问题?")
system_prompt = f"用户历史记忆:{'; '.join(memories)}\n\n当前问题:{question}"

七、实战项目:构建智能助手 Agent

把以上知识整合,构建一个能搜索、计算、管理日程的智能助手。

架构设计

用户输入
    ↓
Router Agent(理解意图,分发任务)
    ├── 搜索 Agent → 搜索工具
    ├── 计算工具 → 计算器
    ├── 日程 Agent → 日历 API
    └── 闲聊 → 直接回答
    ↓
记忆模块(保存关键信息)
    ↓
格式化输出

关键代码

import json
from openai import OpenAI

client = OpenAI()

tools = [
    {
        "type": "function",
        "function": {
            "name": "web_search",
            "description": "搜索互联网获取最新信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string", "description": "搜索关键词"}
                },
                "required": ["query"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "create_event",
            "description": "创建日历事件",
            "parameters": {
                "type": "object",
                "properties": {
                    "title": {"type": "string", "description": "事件标题"},
                    "start_time": {"type": "string", "description": "开始时间"},
                    "duration": {"type": "integer", "description": "持续分钟数"}
                },
                "required": ["title", "start_time"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculator",
            "description": "数学计算",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {"type": "string", "description": "数学表达式"}
                },
                "required": ["expression"]
            }
        }
    }
]

SYSTEM_PROMPT = """你是一个智能助手,能帮用户搜索信息、管理日程、做计算。
工作流程:
1. 理解用户意图
2. 如果需要信息,使用 web_search
3. 如果需要计算,使用 calculator
4. 如果需要安排日程,使用 create_event
5. 整合所有结果,给出清晰的回复
注意:
- 一次可以调用多个工具
- 如果信息不足,主动询问用户
- 重要信息要记住并提醒用户
"""

def run_agent(user_message, history=None):
    messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if history:
        messages.extend(history)
    messages.append({"role": "user", "content": user_message})
    
    tool_map = {
        "web_search": lambda q: search_api(q),
        "create_event": lambda **kw: calendar_api(**kw),
        "calculator": lambda expr: str(eval(expr))
    }
    
    max_iterations = 5
    for i in range(max_iterations):
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )
        
        msg = response.choices[0].message
        messages.append(msg)
        
        if not msg.tool_calls:
            return msg.content, messages[1:]
        
        for tc in msg.tool_calls:
            args = json.loads(tc.function.arguments)
            result = tool_map[tc.function.name](**args)
            messages.append({
                "role": "tool",
                "tool_call_id": tc.id,
                "content": str(result)
            })
    
    return "抱歉,处理超时,请重试。", messages[1:]

# 使用
history = []
while True:
    user_input = input("👤 你:")
    if user_input.lower() in ("退出", "exit", "quit"):
        break
    reply, history = run_agent(user_input, history)
    print(f"🤖 助手:{reply}\n")

八、常见问题与最佳实践

Q1:Agent 陷入无限循环怎么办?

# 设置最大迭代次数
MAX_ITERATIONS = 5

# 或在 system prompt 中明确要求:
"如果你已经调用了 3 次工具仍然无法完成任务,请直接根据已有信息回答。"

Q2:工具调用结果太大怎么办?

def truncate_result(result, max_chars=2000):
    if len(result) > max_chars:
        return result[:max_chars] + "\n...(结果已截断)"
    return result

Q3:如何提高工具调用的准确性?

  • 工具描述要清晰:告诉模型什么时候该用、什么时候不该用
  • 参数描述要具体:包含格式要求、取值范围、示例
  • 减少工具数量:一次给太多工具会降低选择准确性
  • 使用 examples:在 system prompt 中给出工具使用的示例

Q4:如何降低成本?

  • 使用更小的模型(GPT-4o-mini)做路由,大模型做最终回答
  • 缓存常见的工具调用结果
  • 对上下文做摘要压缩

九、总结

AI Agent 的核心就是 LLM + 工具 + 循环

  1. Function Calling 是基础设施——让模型能操作外部世界
  2. ReAct 是设计范式——先思考再行动
  3. 记忆系统 让 Agent 有持久性——从无状态到有状态
  4. Multi-Agent 实现复杂协作——单个不够就组队
  5. MCP 是标准化协议——让工具生态互通

下一步建议: 从一个简单的单 Agent 开始,加上 2-3 个工具,跑通核心循环。然后逐步加入记忆、规划、多 Agent 等能力。


📌 如果这篇文章对你有帮助,欢迎点赞收藏!有问题欢迎评论区讨论~