C++ 手写 AI 编程 Agent(10):主程序整合与端到端实战演示
·
📃作者主页:编程的一拳超人
⛺️ 欢迎关注:👍点赞 👂🏽留言 🌟收藏 💞 💞 💞
于高山之巅,方见大河奔涌;于群峰之上,更觉长风浩荡。
📌 专栏系列:C++ AI Agent 实战 / 大模型工具调用 / 智能编程助手
⭐ 如果本文对你有帮助,欢迎点赞、收藏、关注三连支持!
💬 问题交流:评论区留言或私信,看到必回

C++ 手写 AI 编程 Agent(10):主程序整合与端到端实战演示
适用标准:C++17 | 难度:中级 | 阅读时间:约 15 分钟
本文是「C++ 手写 AI 编程 Agent」12篇系列的第10篇,把所有模块组装起来跑通完整流程。
7. 主程序与交互界面
7.1 完整的 main.cpp
// src/main.cpp
#include "agent.h"
#include "file_tools.h"
#include "compile_tool.h"
#include "shell_tool.h"
#include <fmt/core.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
/// 从文件加载 system prompt
std::string load_system_prompt(const std::string& path) {
std::ifstream file(path);
if (!file.is_open()) {
fmt::print(stderr, "Warning: Cannot load system prompt from {}\n", path);
return "You are a helpful C++ coding assistant.";
}
std::stringstream ss;
ss << file.rdbuf();
return ss.str();
}
/// 注册所有内置工具
void register_all_tools(Agent& agent) {
// 文件操作工具
agent.register_tool(make_read_file_tool());
agent.register_tool(make_write_file_tool());
agent.register_tool(make_edit_file_tool());
agent.register_tool(make_list_directory_tool());
agent.register_tool(make_search_in_files_tool());
// 编译工具
agent.register_tool(make_compile_tool());
// Shell 工具
agent.register_tool(make_shell_tool());
fmt::print("\n✓ All tools registered.\n\n");
}
void print_banner() {
fmt::print(R"(
╔══════════════════════════════════════════╗
║ C++ AI Agent v1.0 ║
║ Read · Write · Compile · Self-Fix ║
╚══════════════════════════════════════════╝
Commands:
/reset - Reset conversation
/stats - Show statistics
/quit - Exit
)");
}
int main() {
// 从环境变量获取 API Key
const char* api_key_env = std::getenv("OPENAI_API_KEY");
if (!api_key_env) {
fmt::print(stderr,
"Error: OPENAI_API_KEY environment variable not set.\n"
"Please set it: export OPENAI_API_KEY=sk-...\n");
return 1;
}
// 配置 Agent
AgentConfig config;
config.api_key = api_key_env;
config.base_url = std::getenv("OPENAI_BASE_URL")
? std::getenv("OPENAI_BASE_URL")
: "https://api.openai.com/v1";
config.model = std::getenv("AGENT_MODEL")
? std::getenv("AGENT_MODEL")
: "gpt-4o";
config.system_prompt = load_system_prompt("system_prompt.txt");
config.max_iterations = 20;
config.verbose = true;
// 创建 Agent 并注册工具
Agent agent(config);
register_all_tools(agent);
// 设置回调(可选:自定义输出格式)
AgentCallbacks callbacks;
callbacks.on_think = [](int iter, const std::string& thought) {
fmt::print("\n💭 [Think #{}] {}\n", iter, thought);
};
callbacks.on_tool_call = [](const std::string& tool, const json& args) {
fmt::print("🔧 [Call] {}({})\n", tool, args.dump());
};
callbacks.on_tool_result = [](const std::string& tool, const ToolResult& r) {
fmt::print("{} [Result] {}: {}\n",
r.success ? "✅" : "❌", tool,
r.output.substr(0, 200));
};
callbacks.on_complete = [](const std::string& answer) {
fmt::print("\n{'='*60}\n");
fmt::print("🎯 FINAL ANSWER:\n{}\n", answer);
fmt::print("{'='*60}\n");
};
agent.set_callbacks(std::move(callbacks));
print_banner();
// REPL 主循环
std::string input;
while (true) {
fmt::print("\n👤 You: ");
if (!std::getline(std::cin, input)) break;
// 去除首尾空白
auto trim = [](std::string& s) {
s.erase(0, s.find_first_not_of(" \t\r\n"));
s.erase(s.find_last_not_of(" \t\r\n") + 1);
};
trim(input);
if (input.empty()) continue;
// 特殊命令处理
if (input == "/quit" || input == "/exit") {
fmt::print("Goodbye!\n");
break;
}
if (input == "/reset") {
agent.reset();
fmt::print("Conversation reset.\n");
continue;
}
if (input == "/stats") {
auto stats = agent.get_stats();
fmt::print("Iterations: {}, Tool calls: {}, Tokens: {}\n",
stats.total_iterations, stats.total_tool_calls,
stats.total_tokens);
continue;
}
// 运行 Agent
try {
std::string response = agent.run(input);
// 最终回复已通过回调输出
} catch (const std::exception& e) {
fmt::print(stderr, "\n❌ Error: {}\n", e.what());
}
}
return 0;
}
8. 完整操作流程演示
8.1 端到端示例:创建一个完整的 C++ 计算器项目
用户输入:
Create a simple calculator library with add, subtract, multiply, divide functions.
Include a main.cpp that demonstrates usage. Set up CMakeLists.txt.
Then compile and verify everything works.
Agent 思考过程逐步展示:
============================================================
Iteration 1/20
============================================================
💭 [Think #1] I need to create three files: the header, implementation,
main.cpp, and CMakeLists.txt. Let me start by creating the project structure.
🔧 [Call] write_file({"path": "include/calculator.h", "content": "#pragma once\n..."})
✅ [Result] write_file: Successfully wrote 245 bytes to include/calculator.h
🔧 [Call] write_file({"path": "src/calculator.cpp", "content": "#include ..."})
✅ [Result] write_file: Successfully wrote 389 bytes to src/calculator.cpp
🔧 [Call] write_file({"path": "src/main.cpp", "content": "#include ..."})
✅ [Result] write_file: Successfully wrote 512 bytes to src/main.cpp
🔧 [Call] write_file({"path": "CMakeLists.txt", "content": "cmake_minimum..."})
✅ [Result] write_file: Successfully wrote 328 bytes to CMakeLists.txt
============================================================
Iteration 2/20
============================================================
💭 [Think #2] All files created. Now I need to compile to verify correctness.
🔧 [Call] compile({"build_dir": "./build"})
❌ [Result] compile: Build FAILED (exit code 1).
src/calculator.cpp:3:10: fatal error: 'calculator.h' file not found
#include "calculator.h"
============================================================
Iteration 3/20
============================================================
💭 [Think #3] The include path is wrong. I need to fix the include directive
to use the correct relative path since headers are in include/.
🔧 [Call] edit_file({"path": "src/calculator.cpp",
"old_string": "#include \"calculator.h\"",
"new_string": "#include \"../include/calculator.h\""})
✅ [Result] edit_file: Replaced 1 occurrence(s) in src/calculator.cpp
============================================================
Iteration 4/20
============================================================
💭 [Think #4] Fixed the include path. Let me also update CMakeLists.txt to
properly set include directories, then recompile.
🔧 [Call] edit_file({"path": "CMakeLists.txt",
"old_string": "add_executable(calc src/main.cpp src/calculator.cpp)",
"new_string": "add_executable(calc src/main.cpp src/calculator.cpp)\ntarget_include_directories(calc PRIVATE include)"})
✅ [Result] edit_file: Replaced 1 occurrence(s) in CMakeLists.txt
🔧 [Call] compile({"build_dir": "./build", "clean": true})
✅ [Result] compile: Build succeeded.
============================================================
Iteration 5/20
============================================================
💭 [Think #5] Build succeeded! Let me run the program to verify output.
🔧 [Call] shell_exec({"command": "./build/calc"})
✅ [Result] shell_exec:
Calculator Demo
5 + 3 = 8
10 - 4 = 6
6 * 7 = 42
15 / 3 = 5
🎯 FINAL ANSWER:
Successfully created a calculator project with the following files:
- include/calculator.h: Header with function declarations
- src/calculator.cpp: Implementation
- src/main.cpp: Demo program
- CMakeLists.txt: Build configuration
Encountered one issue: include path was incorrect initially.
Fixed by adding target_include_directories to CMakeLists.txt.
Project compiles and runs correctly. ✅
8.2 编译失败自修复的完整过程
这个例子展示了 Agent 最核心的价值——自动发现并修复编译错误:
- Agent 编写代码 → 编译失败
- Agent 阅读错误信息 → 分析原因
- Agent 编辑代码 → 重新编译
- 如果仍然失败 → 重复步骤 2-3
- 编译通过 → 报告完成
关键在于 system prompt 中的 “VERIFY AFTER CHANGES” 原则,以及 LLM 对编译器错误的理解能力。
8.3 代码重构任务示例
User: Refactor the calculator to use a class-based design with operator overloading.
Agent 思考链:
1. read_file("include/calculator.h") → 了解当前接口
2. read_file("src/calculator.cpp") → 了解当前实现
3. read_file("src/main.cpp") → 了解使用方式
4. write_file("include/calculator.h") → 重写为类设计
5. write_file("src/calculator.cpp") → 重写实现
6. edit_file("src/main.cpp") → 更新使用方式
7. compile() → 验证编译
8. shell_exec("./build/calc") → 验证运行结果
8.4 Bug 定位与修复示例
User: The divide function returns wrong results for negative numbers. Fix it.
Agent 思考链:
1. read_file("src/calculator.cpp") → 查看 divide 实现
2. Thought: "I see the issue - integer division truncates toward zero,
but the expected behavior might be floor division..."
3. read_file("src/main.cpp") → 查看测试用例
4. edit_file(...) → 修复逻辑
5. compile() → 验证
6. shell_exec("./build/calc") → 验证输出正确
📚 系列目录
- 第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总结
⬅️ 上一篇:第9篇:Prompt工程从System Prompt到AB测试
➡️ 下一篇:第11篇:Reflexion与Tree-of-Thought等高级模式
更多推荐


所有评论(0)