C++ 手写 AI 编程 Agent(1):AI Agent 概念入门与 ReAct 架构设计
📃作者主页:编程的一拳超人
⛺️ 欢迎关注:👍点赞 👂🏽留言 🌟收藏 💞 💞 💞
于高山之巅,方见大河奔涌;于群峰之上,更觉长风浩荡。

📌 专栏系列:C++ AI Agent 实战 / 大模型工具调用 / 智能编程助手
⭐ 如果本文对你有帮助,欢迎点赞、收藏、关注三连支持!
💬 问题交流:评论区留言或私信,看到必回
C++ 手写 AI 编程 Agent(1):AI Agent 概念入门与 ReAct 架构设计
适用标准:C++17 | 难度:入门 | 阅读时间:约 15 分钟
本文是「C++ 手写 AI 编程 Agent」12篇系列的第1篇,建立概念基础。
1. 什么是 AI Agent
1.1 Agent 与普通 Chatbot 的区别
普通的 Chatbot(聊天机器人)本质上是一个"文本接龙"机器:你给它一段输入,它返回一段输出,整个过程是单轮、无状态、无行动力的。而 AI Agent 则完全不同——它是一个能够自主思考、使用工具、与环境交互的智能体。
| 特性 | 普通 Chatbot | AI Agent |
|---|---|---|
| 交互模式 | 单轮问答 | 多轮思考+行动循环 |
| 外部能力 | 无 | 可调用工具(文件、编译器、Shell等) |
| 状态管理 | 无/简单上下文 | 完整的对话历史+任务状态 |
| 错误处理 | 无法自我修正 | 观察结果→反思→重试 |
| 目标导向 | 被动响应 | 主动规划并执行 |
| 自主性 | 低 | 高(在约束范围内自主决策) |
一个直观的比喻:Chatbot 像一个只会回答问题的百科全书,而 Agent 更像一个能动手干活的工程师——它不仅能告诉你怎么做,还能自己去做、检查结果、发现问题后自行修复。
1.2 ReAct 范式详解(Reasoning + Acting)
ReAct 是当前主流 AI Agent 的核心思维范式,由 Yao et al. (2022) 提出。其核心思想是将**推理(Reasoning)和行动(Acting)**交替进行:
Thought: 我需要先了解项目的目录结构,才能确定在哪里创建新文件。
Action: list_directory(path=".")
Observation: [src/, include/, tests/, CMakeLists.txt, README.md]
Thought: 项目使用标准 CMake 布局。新文件应该放在 src/ 目录下。
Action: write_file(path="src/calculator.cpp", content="...")
Observation: File written successfully (256 bytes)
Thought: 文件已创建,现在需要将其添加到 CMakeLists.txt 中并编译验证。
Action: compile(target="myproject")
Observation: Build succeeded.
Thought: 编译通过,任务完成。
Final Answer: 已成功创建 calculator.cpp 并通过编译验证。
ReAct 的关键优势在于:
- 推理引导行动:每一步行动都有明确的思考依据
- 观察修正推理:根据实际执行结果调整后续计划
- 可追溯性:完整的思考链便于调试和理解
- 容错能力:失败时能分析原因并尝试替代方案
1.3 Tool Use Protocol 概念
Tool Use Protocol(工具使用协议)定义了 LLM 如何声明、选择和调用外部工具。现代 LLM API(如 OpenAI、Anthropic、Google)都提供了原生的 Function Calling / Tool Use 支持。
核心流程:
- 定义阶段:向 LLM 描述可用工具的名称、功能、参数格式(JSON Schema)
- 选择阶段:LLM 根据当前任务决定是否需要调用工具,以及调用哪个
- 调用阶段:LLM 生成结构化的工具调用请求(函数名+参数)
- 执行阶段:宿主程序解析请求,执行对应操作,返回结果
- 反馈阶段:将执行结果作为消息回传给 LLM,继续下一轮思考
1.4 Agent 思考循环图解
┌─────────────────────────────────────────────────────┐
│ Agent 思考循环 │
│ │
│ ┌──────────┐ │
│ │ User │ │
│ │ Input │ │
│ └────┬─────┘ │
│ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Think │◄──►│ Select │◄──►│ Execute │ │
│ │(LLM推理) │ │ Tool │ │ Tool │ │
│ └────┬─────┘ └──────────┘ └────┬─────┘ │
│ │ │ │
│ │ ┌──────────┐ │ │
│ ├────────►│ Observe │◄──────────┘ │
│ │ │ (结果) │ │
│ │ └────┬─────┘ │
│ │ │ │
│ │ ┌─────────▼─────────┐ │
│ │ │ Need more action? │ │
│ │ └────┬────────┬─────┘ │
│ │ YES│ │NO │
│ │ ▼ ▼ │
│ │ (回到Think) ┌──────────┐ │
│ │ │ Complete │ │
│ │ │ Response │ │
│ │ └──────────┘ │
│ ▼ │
│ ┌──────────┐ │
│ │ Output │ │
│ │ to User │ │
│ └──────────┘ │
└─────────────────────────────────────────────────────┘
1.5 Agent 发展简史
AI Agent 的概念并非一夜之间诞生,而是经历了从理论到实践的漫长演进。了解这段历史有助于我们理解当前 Agent 技术的设计哲学和发展方向。
| 时间 | 里程碑 | 核心贡献 | 局限性 |
|---|---|---|---|
| 2022.10 | ReAct 论文发表 | Yao et al. 提出 Reasoning+Acting 范式,奠定现代 Agent 理论基础 | 仅停留在学术研究层面 |
| 2023.03 | AutoGPT 发布 | 首个引爆社区的自主 Agent 项目,展示了 LLM 自主循环的可能性 | 稳定性差、缺乏工具生态、容易陷入死循环 |
| 2023.04 | BabyAGI | 引入任务队列和优先级排序,简化了 Agent 架构 | 功能单一,实际可用性低 |
| 2023.06 | LangChain Agents | 提供了标准化的 Agent 框架和工具集成方案 | 抽象层过厚,调试困难 |
| 2023.09 | OpenAI Function Calling | LLM 原生支持结构化工具调用,大幅提升可靠性 | 依赖特定 API,不够通用 |
| 2023.11 | AutoGen (Microsoft) | 多 Agent 对话框架,支持人机协作 | 配置复杂,学习曲线陡峭 |
| 2024.01 | CrewAI | 面向角色分工的多 Agent 编排框架 | 灵活性受限于预定义角色 |
| 2024.03 | Devin (Cognition) | 首个"AI 软件工程师",具备完整的开发环境交互能力 | 闭源、价格昂贵、实际效果有争议 |
| 2024.06 | Claude Code / Cursor Agent | IDE 级别的编码 Agent,深度集成开发工作流 | 依赖特定 IDE 生态 |
| 2024.11 | Anthropic MCP 协议 | 标准化工具/数据源连接协议,推动工具互操作性 | 生态尚在早期建设阶段 |
| 2025.01 | Claude Agent SDK | Anthropic 官方 Agent 构建工具包,提供生产级基础设施 | 绑定 Claude 模型生态 |
| 2025~至今 | Agent 百花齐放 | OpenAI Codex Agent、Google Jules、各类开源 Agent 涌现 | 标准化不足、安全挑战突出 |
关键洞察:Agent 的发展轨迹清晰地呈现出三个趋势——从"演示"到"实用"、从"单 Agent"到"多 Agent 协作"、从"私有协议"到"开放标准(MCP)"。C++ 开发者在这一浪潮中的独特机会在于:将 Agent 能力嵌入高性能系统和传统软件生态中。
1.6 主流 Agent 框架对比
在选择或自建 Agent 框架之前,有必要了解当前主流方案的优劣。以下对比涵盖了 Python 生态中最具影响力的框架以及 C++ 自研方案:
| 特性 | LangChain | AutoGen | CrewAI | Claude Agent SDK | C++ 自研(本教程) |
|---|---|---|---|---|---|
| 语言 | Python | Python | Python | Python/TS | C++ |
| 学习曲线 | 中等 | 较高 | 较低 | 中等 | 较高 |
| 单 Agent 能力 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 多 Agent 协作 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐(需自建) |
| 工具生态 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐(需自建) |
| 执行性能 | ⭐⭐ | ⭐⭐ | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 类型安全 | ❌ | ❌ | ❌ | 部分 | ✅ |
| 部署复杂度 | 高(Python 环境) | 高 | 中 | 中 | 低(单二进制) |
| 系统集成 | 一般 | 一般 | 一般 | 较好 | 极佳 |
| 调试友好度 | 较差 | 中等 | 较好 | 好 | 取决于实现 |
| 适用场景 | 通用原型验证 | 多 Agent 研究 | 角色扮演/流程编排 | Claude 生态应用 | 嵌入式/高性能/系统级 |
| 社区活跃度 | 极高 | 高 | 中高 | 快速增长 | 无(自维护) |
选型建议:如果你需要快速验证想法,选 LangChain/CrewAI;如果你构建多 Agent 研究系统,选 AutoGen;如果你在 Claude 生态内开发,选 Claude Agent SDK;如果你需要将 Agent 嵌入 C++ 系统、追求极致性能或深入理解底层原理,那么本教程的 C++ 自研方案正是你需要的。
1.7 C++ 实现 vs Python 实现详细对比
为了帮助读者做出更明智的技术选型,以下是两种实现路线在多个维度上的深入对比:
| 对比维度 | C++ 实现 | Python 实现 | 评价 |
|---|---|---|---|
| 启动速度 | 毫秒级(编译后直接运行) | 秒级(解释器+依赖加载) | C++ 胜 |
| 内存占用 | 10-50 MB | 200-500 MB | C++ 胜 |
| 工具执行效率 | 原生系统调用,零开销 | subprocess/os 模块有额外开销 | C++ 胜 |
| LLM API 调用 | cpr/libcurl,性能优秀 | requests/httpx,足够用 | 平手(瓶颈在网络) |
| JSON 处理 | nlohmann/json,编译期优化 | 内置 json 模块,运行时解析 | C++ 略胜 |
| 开发速度 | 较慢,需手动管理更多细节 | 快,框架封装完善 | Python 胜 |
| 生态丰富度 | 有限,需自行实现很多组件 | 极其丰富,开箱即用 | Python 大胜 |
| 并发模型 | 多线程/std::async/io_uring | asyncio/多线程/GIL 限制 | C++ 胜 |
| 错误诊断 | 编译期捕获大量错误 | 运行时才发现类型/逻辑错误 | C++ 胜 |
| 可嵌入性 | 可作为库嵌入任何 C++ 项目 | 需要 Python 运行时环境 | C++ 大胜 |
| 跨平台 | CMake + 标准库,良好支持 | 天然跨平台 | 平手 |
| 热更新/动态加载 | 困难(需重新编译) | 简单(importlib/reload) | Python 胜 |
| 适合团队规模 | 小到中型团队 | 任意规模 | Python 胜 |
| 长期维护成本 | 代码量少但修改成本高 | 代码量多但修改灵活 | 视情况而定 |
实践建议:对于本教程的学习目的,C++ 实现能让你深入理解每一个底层细节。在实际项目中,一种务实的做法是:用 Python 做原型验证和上层编排,用 C++ 实现性能关键的工具层,两者通过 MCP 协议或 gRPC 通信,兼得开发效率和运行性能。
1.8 Agent 能力分级(L1-L5)
参照自动驾驶的分级标准,我们可以将 AI Agent 的能力划分为五个等级。这个分级有助于评估当前 Agent 的水平,也指明了未来的发展方向:
| 等级 | 名称 | 描述 | 典型代表 | 人类角色 |
|---|---|---|---|---|
| L1 | 辅助级 | LLM 仅提供建议和知识,所有操作由人类执行 | ChatGPT 普通对话、Copilot 补全 | 完全主导 |
| L2 | 工具级 | Agent 能调用工具执行简单任务,但每步需人类确认 | GitHub Copilot Chat、Cursor Tab | 逐步确认 |
| L3 | 自主级 | Agent 能自主完成明确定义的任务,仅在异常时请求人类介入 | Claude Code、Devin、本教程实现 | 监督审核 |
| L4 | 协作级 | 多个 Agent 协同工作,能处理模糊需求,具备规划和自我修正能力 | AutoGen 多 Agent、CrewAI 团队 | 高层指导 |
| L5 | 通用级 | Agent 能在开放域环境中自主学习、适应和改进,接近人类专家水平 | 尚未实现(AGI 愿景) | 平等伙伴 |
当前行业现状:大多数商用 Agent 处于 L2-L3 过渡期。本教程实现的 Agent 定位为 L3 级别——它能在给定工作空间内自主完成编码、编译、修复等任务,但仍受限于预定义的工具集和安全边界。
各等级的关键技术门槛:
- L1→L2:Function Calling / Tool Use 协议的可靠实现
- L2→L3:自主思考循环 + 错误自修复 + 安全防护
- L3→L4:多 Agent 协调 + 长期记忆 + 任务规划
- L4→L5:自主学习 + 元认知 + 开放域推理(前沿研究课题)
1.9 C++ 实现 Agent 的独特价值
为什么选择 C++ 而不是 Python 来实现 AI Agent?
- 极致性能:工具执行(尤其是编译、文件IO)是 CPU/IO 密集型操作,C++ 的原生性能优势显著
- 系统级访问:直接操作文件系统、进程、内存,无需中间层
- 嵌入式场景:可将 Agent 嵌入到 IDE 插件、游戏引擎、EDA 工具等 C++ 生态中
- 类型安全:编译期检查减少运行时错误,对于需要高可靠性的 Agent 尤为重要
- 学习价值:深入理解 Agent 底层机制,而非停留在框架抽象层
- 零依赖部署:编译为单一二进制文件,无需运行时环境
当然,C++ 也有劣势:开发速度较慢、生态不如 Python 丰富。本教程选择的库(nlohmann/json、cpr、fmt)都是 header-only 或易于集成的,尽量降低开发负担。
1.10 主流 Agent 架构模式分类
除了 ReAct 范式之外,学术界和工业界还提出了多种 Agent 架构模式。理解这些模式有助于在不同场景下选择最合适的方案:
| 架构模式 | 核心思想 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|---|
| ReAct | 推理与行动交替进行 | 灵活、可追溯、容错 | 每步都需 LLM 调用,延迟较高 | 通用任务、交互式编程 |
| Plan-and-Execute | 先制定完整计划,再逐步执行 | 全局视角、减少无效探索 | 计划可能与实际脱节、规划本身消耗 token | 复杂多步骤任务、项目重构 |
| Reflexion | 执行后自我反思,积累经验教训 | 能从失败中学习、持续改进 | 需要额外 LLM 调用做反思 | 反复试错型任务、代码调试 |
| LATS | 树搜索 + 反思 + 价值评估 | 系统性探索解空间 | 计算开销大、实现复杂 | 数学推理、创意生成 |
| AutoGPT-style | 完全自主的任务分解与执行循环 | 高度自主 | 容易失控、难以调试 | 研究探索、概念验证 |
| Multi-Agent Debate | 多个 Agent 从不同角度辩论 | 提高决策质量、减少幻觉 | 通信开销大、收敛慢 | 代码审查、方案设计 |
| Human-in-the-Loop | 关键节点暂停等待人类确认 | 安全可控、结合人类判断 | 打断自动化流程、依赖人类响应 | 生产环境、高风险操作 |
┌─────────────────────────────────────────────────────────────┐
│ Agent 架构模式选择决策树 │
│ │
│ 任务复杂度低? ─── YES ──→ ReAct(简单直接) │
│ │NO │
│ ▼ │
│ 需要全局规划? ─── YES ──→ Plan-and-Execute │
│ │NO │
│ ▼ │
│ 允许试错学习? ─── YES ──→ Reflexion │
│ │NO │
│ ▼ │
│ 需要多角度验证? ── YES ──→ Multi-Agent Debate │
│ │NO │
│ ▼ │
│ 高风险操作? ──── YES ──→ Human-in-the-Loop │
│ │NO │
│ ▼ │
│ 默认 → ReAct + 安全防护 │
└─────────────────────────────────────────────────────────────┘
实践建议:大多数场景下,ReAct 是最佳起点。当遇到特定瓶颈时再叠加其他模式——例如在 ReAct 基础上加入 Reflexion 的自我评估环节,或在复杂任务前增加 Planning 阶段。不要过度设计,从简单开始,按需演进。
2. 技术架构设计
2.1 完整架构图
┌─────────────────────────────────────────────────────────────────────┐
│ C++ AI Agent 架构 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 用户交互层 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌──────────────────┐ │ │
│ │ │ REPL 终端 │ │ 任务模式 │ │ 对话模式 │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └────────┬─────────┘ │ │
│ │ └─────────────────┼──────────────────┘ │ │
│ └───────────────────────────┼─────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Agent 核心引擎 │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │
│ │ │ Message │ │ Think Loop │ │ State │ │ │
│ │ │ Manager │ │ Controller │ │ Manager │ │ │
│ │ │ (消息管理) │ │ (思考循环) │ │ (状态管理) │ │ │
│ │ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │ │
│ │ │ │ │ │ │
│ │ └─────────────────┼────────────────────┘ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ LLM Client (HTTP/API) │ │ │
│ │ │ • Function Calling 请求构造 │ │ │
│ │ │ • Streaming 响应解析 │ │ │
│ │ │ • Token 计数与窗口管理 │ │ │
│ │ │ • 错误重试与恢复 │ │ │
│ │ └──────────────────────┬───────────────────────────────┘ │ │
│ └──────────────────────────┼───────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 工具系统层 │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ ToolRegistry (工具注册表) │ │ │
│ │ │ • 动态注册/注销 • JSON Schema 序列化 │ │ │
│ │ │ • 按名称查找 • 参数校验 │ │ │
│ │ └──────────────────────┬───────────────────────────────┘ │ │
│ │ ┌─────────────┼─────────────┬──────────────┐ │ │
│ │ ▼ ▼ ▼ ▼ │ │
│ │ ┌──────────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐ │ │
│ │ │ FileTools │ │Compile │ │ ShellTool │ │ Custom │ │ │
│ │ │ • read_file │ │ Tool │ │ • exec │ │ Tools │ │ │
│ │ │ • write_file │ │ • cmake │ │ • sandbox │ │ • ... │ │ │
│ │ │ • edit_file │ │ • make │ │ • timeout │ │ │ │ │
│ │ │ • list_dir │ │ • ninja │ │ │ │ │ │ │
│ │ │ • search │ │ • parse │ │ │ │ │ │ │
│ │ └──────────────┘ └──────────┘ └───────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 基础设施层 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │ │
│ │ │ cpr │ │ nlohmann │ │ fmt │ │ std:: │ │ │
│ │ │ (HTTP) │ │ /json │ │ (格式化) │ │ filesystem│ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └───────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
2.2 核心循环详解
Agent 的核心是一个 Think-Act-Observe 循环:
User Input → [Think → Select Tool → Execute → Observe] × N → Complete/Output
关键设计决策:
- 最大迭代次数:防止无限循环,默认 20 次
- 超时机制:单次工具执行超时 + 总任务超时
- 中间输出:每轮思考和行动都实时展示给用户
- 优雅终止:LLM 返回纯文本(非工具调用)时视为完成
2.3 消息协议设计
所有消息统一使用以下结构:
struct Message {
std::string role; // "system" | "user" | "assistant" | "tool"
std::string content; // 文本内容
std::string tool_call_id; // 工具调用ID(仅 tool 角色)
// 工具调用信息(仅 assistant 角色发起工具调用时)
struct ToolCall {
std::string id;
std::string function_name;
nlohmann::json arguments;
};
std::vector<ToolCall> tool_calls;
};
2.4 工具注册与发现机制
采用注册表模式(Registry Pattern):
- 每个工具是一个
ToolDefinition结构体 + 一个 handler 函数 - 启动时将所有工具注册到
ToolRegistry - LLM 请求时,Registry 序列化为 JSON Schema 数组
- 收到工具调用请求时,Registry 按名称查找并执行 handler
2.5 状态管理
Agent 维护以下状态:
- 对话历史:完整的 Message 列表
- 当前任务状态:idle / thinking / executing_tool / completed / error
- 迭代计数器:当前思考轮次
- Token 使用量:累计消耗,用于成本控制
- 工作目录:当前操作的根目录
📚 系列目录
- ✅ 第1篇:AI Agent概念入门与ReAct架构设计(当前阅读)
- 第2篇:环境搭建与CMake依赖管理
- 第3篇:工具注册表与文件操作工具集
- 第4篇:编译诊断工具与Shell执行引擎
- 第5篇:工具超时缓存与链式组合模式
- 第6篇:Agent核心循环消息管理与LLM调用
- 第7篇:Token窗口管理与错误恢复策略
- 第8篇:记忆系统规划引擎与多Agent协作
- 第9篇:Prompt工程从System Prompt到AB测试
- 第10篇:主程序整合与端到端实战演示
- 第11篇:Reflexion与Tree-of-Thought等高级模式
- 第12篇:性能优化安全防护与FAQ总结
➡️ 下一篇:第2篇:环境搭建与CMake依赖管理
更多推荐



所有评论(0)