:主程序整合与端到端实战演示)
作者主页编程的一拳超人⛺️ 欢迎关注点赞 留言 收藏 于高山之巅方见大河奔涌于群峰之上更觉长风浩荡。专栏系列C AI Agent 实战 / 大模型工具调用 / 智能编程助手⭐如果本文对你有帮助欢迎点赞、收藏、关注三连支持问题交流评论区留言或私信看到必回C 手写 AI 编程 Agent10主程序整合与端到端实战演示7. 主程序与交互界面7.1 完整的 main.cpp8. 完整操作流程演示8.1 端到端示例创建一个完整的 C 计算器项目8.2 编译失败自修复的完整过程8.3 代码重构任务示例8.4 Bug 定位与修复示例 系列目录C 手写 AI 编程 Agent10主程序整合与端到端实战演示适用标准C17 |难度中级 |阅读时间约 15 分钟本文是「C 手写 AI 编程 Agent」12篇系列的第10篇把所有模块组装起来跑通完整流程。7. 主程序与交互界面7.1 完整的 main.cpp// src/main.cpp#includeagent.h#includefile_tools.h#includecompile_tool.h#includeshell_tool.h#includefmt/core.h#includeiostream#includefstream#includesstream#includecstdlib/// 从文件加载 system promptstd::stringload_system_prompt(conststd::stringpath){std::ifstreamfile(path);if(!file.is_open()){fmt::print(stderr,Warning: Cannot load system prompt from {}\n,path);returnYou are a helpful C coding assistant.;}std::stringstream ss;ssfile.rdbuf();returnss.str();}/// 注册所有内置工具voidregister_all_tools(Agentagent){// 文件操作工具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);}voidprint_banner(){fmt::print(R( ╔══════════════════════════════════════════╗ ║ C AI Agent v1.0 ║ ║ Read · Write · Compile · Self-Fix ║ ╚══════════════════════════════════════════╝ Commands: /reset - Reset conversation /stats - Show statistics /quit - Exit ));}intmain(){// 从环境变量获取 API Keyconstchar*api_key_envstd::getenv(OPENAI_API_KEY);if(!api_key_env){fmt::print(stderr,Error: OPENAI_API_KEY environment variable not set.\nPlease set it: export OPENAI_API_KEYsk-...\n);return1;}// 配置 AgentAgentConfig config;config.api_keyapi_key_env;config.base_urlstd::getenv(OPENAI_BASE_URL)?std::getenv(OPENAI_BASE_URL):https://api.openai.com/v1;config.modelstd::getenv(AGENT_MODEL)?std::getenv(AGENT_MODEL):gpt-4o;config.system_promptload_system_prompt(system_prompt.txt);config.max_iterations20;config.verbosetrue;// 创建 Agent 并注册工具Agentagent(config);register_all_tools(agent);// 设置回调可选自定义输出格式AgentCallbacks callbacks;callbacks.on_think[](intiter,conststd::stringthought){fmt::print(\n [Think #{}] {}\n,iter,thought);};callbacks.on_tool_call[](conststd::stringtool,constjsonargs){fmt::print( [Call] {}({})\n,tool,args.dump());};callbacks.on_tool_result[](conststd::stringtool,constToolResultr){fmt::print({} [Result] {}: {}\n,r.success?✅:❌,tool,r.output.substr(0,200));};callbacks.on_complete[](conststd::stringanswer){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;// 去除首尾空白autotrim[](std::strings){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){autostatsagent.get_stats();fmt::print(Iterations: {}, Tool calls: {}, Tokens: {}\n,stats.total_iterations,stats.total_tool_calls,stats.total_tokens);continue;}// 运行 Agenttry{std::string responseagent.run(input);// 最终回复已通过回调输出}catch(conststd::exceptione){fmt::print(stderr,\n❌ Error: {}\n,e.what());}}return0;}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等高级模式