在这里插入图片描述

📃作者主页:编程的一拳超人

⛺️ 欢迎关注:👍点赞 👂🏽留言 🌟收藏 💞 💞 💞

于高山之巅,方见大河奔涌;于群峰之上,更觉长风浩荡。


在这里插入图片描述

📌 专栏系列: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 支持。

核心流程:

  1. 定义阶段:向 LLM 描述可用工具的名称、功能、参数格式(JSON Schema)
  2. 选择阶段:LLM 根据当前任务决定是否需要调用工具,以及调用哪个
  3. 调用阶段:LLM 生成结构化的工具调用请求(函数名+参数)
  4. 执行阶段:宿主程序解析请求,执行对应操作,返回结果
  5. 反馈阶段:将执行结果作为消息回传给 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 使用量:累计消耗,用于成本控制
  • 工作目录:当前操作的根目录

📚 系列目录


➡️ 下一篇第2篇:环境搭建与CMake依赖管理


Logo

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

更多推荐