手把手教你用200行代码实现AI编程智能体

作者:菠萝爱吃肉2026.11.04 12:14浏览量:0

简介:本教程面向希望理解代码智能体内部原理的开发者,讲解如何基于大模型的工具调用能力,用约200行代码从零实现一个可在终端运行的极简编程智能体。内容覆盖智能体主循环、工具定义与安全执行、上下文工程入门,并提供结果验证清单与常见问题排查方法,帮助你系统建立AI原生开发的实践认知。

一、教程目标与背景

近一年来,代码智能体(Coding Agent)的能力出现了阶跃式提升:大模型的推理时间更长、可自主处理的任务复杂度显著提高,软件开发的协作方式随之被改写。教学与工程实践也在同步演进——某知名高校新近发布的现代软件开发课程,就推翻了上一年的教案,将“用约200行代码实现一个命令行编程智能体”安排为第一周的动手实验,并要求学生后续向真实的生产级开源代码库提交代码合并请求。这一安排背后的判断是:AI原生开发者正在成为软件团队中的核心角色,而理解智能体的内部机制,是成为这类工程师的第一步。

本教程将带你完成同样的核心任务:从零开始,用约200行代码实现一个能在终端中运行的极简编程智能体。它具备四个最基础的工具——读取文件、写入文件、编辑文件、执行终端命令,并通过一个“模型调用循环”自主完成多步编程任务。

学完本教程,你将掌握:

  1. 代码智能体的底层循环逻辑,这是所有主流智能体共同的结构骨架;
  2. 工具的定义、注册与安全执行方法;
  3. 系统提示词与工具描述的编写技巧,即“上下文工程”的入门实践;
  4. 基本的安全控制、结果验证与故障排查思路。

二、适用场景与适合读者

本教程适合以下读者:

  • 希望理解智能体内部机制,而不只是“会调用接口”的后端、全栈与客户端开发者;
  • 计划在团队内部搭建研发提效工具的技术负责人与平台工程师;
  • 希望评估智能体能力边界、设计权限与安全策略的运维与架构人员;
  • 关注AI原生开发范式的学生与教学人员。

适用场景包括:本地代码理解与修改助手、小规模重构与批处理脚本生成、代码审查前的预检工具、教学演示,以及在此基础上二次开发企业内部智能体的原型验证。

三、前置准备

在动手之前,请确认以下条件已经就绪:

  1. 开发环境:安装Python 3.10及以上版本,并使用虚拟环境隔离依赖(如python -m venv .venv)。你也可以使用Go、TypeScript等熟悉的其他语言实现,本文示例以Python为准。
  2. 模型服务:需要一个具备“工具调用(函数调用)”能力的大模型推理服务。获取方式有两类:一是使用百度智能云等云平台提供的大模型服务,在其控制台开通服务后获取API密钥与接入地址;二是使用本地部署的开源模型。无论哪种方式,务必确认所选模型能够在对话中返回结构化的工具调用请求,否则整套循环无法运转。
  3. 依赖组件:安装所选模型服务的官方SDK,或准备通过HTTP接口直接调用。
  4. 知识储备:了解JSON格式、基础命令行操作,以及“工具调用”的基本概念——即模型不直接输出答案,而是输出“我想调用哪个工具、传什么参数”的结构化描述。
  5. 安全准备:单独创建一个workspace目录作为智能体的工作区;密钥一律通过环境变量注入,禁止写死在代码或提交到代码仓库。

四、核心原理:智能体的本质是一个循环

单轮调用大模型,只能得到一段“文字回答”,模型无法真正“做事”。让模型具备行动能力,需要三个要素配合:

  • 系统提示词:定义角色、能力边界与行为规则;
  • 工具集:以结构化模式(schema)描述每个工具的名称、用途和参数;
  • 执行器:在本地真实执行工具,并把结果回填到对话上下文中。

三者组合起来,就构成智能体的主循环:

  1. 将用户输入追加到消息列表;
  2. 携带系统提示词、历史消息和工具定义调用模型;
  3. 模型返回普通文本,或返回一个或多个工具调用请求;
  4. 若是工具调用,则本地执行对应函数,将执行结果以工具消息的形式回填;
  5. 再次调用模型,重复上述过程,直到模型不再请求工具、给出最终回答。

理解了这个循环,就理解了当前主流代码智能体的骨架。不同产品之间的差异,主要体现在工具更丰富、上下文工程更精细、权限与沙箱体系更完善、调度能力更强,但底层循环逻辑是一致的。

五、实施步骤

步骤1:搭建工程骨架与安全边界

创建项目目录、虚拟环境并安装SDK依赖;随后定义工作区根目录常量,并约定后续所有文件操作与命令执行都必须限制在该目录内。之所以把安全边界放在第一步,是因为后面要实现的工具具备执行任意命令的能力,先画好红线,可以避免调试过程中出现误删文件、越权访问等问题。

步骤2:编写系统提示词

系统提示词决定智能体的“性格”与边界,是上下文工程的核心。建议覆盖四方面内容:角色定位(你是谁、能做什么)、操作约束(只在工作区内活动、破坏性命令需谨慎)、输出规范(每步只做必要操作、任务完成后简洁总结)、异常行为(需求不明确时先提问而不是臆测)。注意提示词要精炼、可执行、无歧义,堆砌长篇大论反而会稀释关键约束的权重。

步骤3:定义工具模式

为四个基础工具编写结构化定义,说明每个工具的用途、参数类型与是否必填:

  • read_file:读取指定路径的文件内容;
  • write_file:创建或覆盖写入文件;
  • edit_file:以“旧文本替换为新文本”的方式做精确编辑;
  • run_command:在工作区内执行终端命令。

工具描述的质量直接影响模型的选择准确率——模型是依据这些描述来判断“该用哪个工具、怎么传参”的,因此描述要写清楚适用情形与限制条件。

步骤4:实现工具执行器

推荐用“注册表”模式组织执行器,即一个工具名到函数的映射,便于后续扩展。实现时的关键点:

  • 所有涉及路径的操作,先做规范化再校验是否位于工作区之内,拒绝越界访问;
  • 读取与命令输出要做长度截断,避免一个超大文件撑爆上下文;
  • 编辑工具在找不到目标文本时,要返回明确的错误信息而非静默失败;
  • 命令执行要设置工作目录、超时时间,并过滤明显的危险命令;
  • 无论成功还是失败,都把结果以字符串形式返回给模型,错误信息是模型自我修正的重要依据。

步骤5:实现主循环

主循环维护消息列表,按第四节描述的流程反复调用模型。两个必须实现的保护机制:一是设置最大迭代次数,防止模型陷入“调用工具—观察结果—再调用”的死循环;二是当模型返回内容中没有工具调用时,视为任务完成,输出最终回答并退出本轮循环。

步骤6:接入模型服务

从环境变量读取接入地址、API密钥和模型名称,完成客户端初始化,与代码逻辑解耦。生成参数建议使用默认值或较低的温度,编程任务对稳定性的要求高于多样性。配置项与代码分离,便于在不同模型服务之间切换。

步骤7:会话与上下文管理(进阶)

当对话变长后,需要做上下文预算控制:保留系统提示词与最近若干轮对话,对更早的历史进行裁剪或摘要压缩;对超长的工具返回结果做截断。这一步是“上下文工程”的入门实践,直接决定智能体在长任务中的稳定性与调用成本。

六、示例代码

以下为核心骨架示例(完整实现约200行,LLMClient为抽象封装,具体实现取决于你所选模型服务的SDK,只要支持携带工具定义并返回结构化工具调用即可):

  1. import os, subprocess
  2. MAX_ITERATIONS = 15
  3. WORKSPACE = os.path.abspath("./workspace")
  4. SYSTEM_PROMPT = """你是一个运行在终端中的编程助手。规则:
  5. 1. 所有文件操作仅限当前工作区,禁止访问工作区之外的路径;
  6. 2. 执行命令前评估风险,避免删除、覆盖等破坏性操作;
  7. 3. 每步只调用必要的工具,任务完成后用简洁文字总结;
  8. 4. 信息不足时先向用户提问,不要臆测。"""
  9. def safe_path(path: str) -> str:
  10. full = os.path.abspath(os.path.join(WORKSPACE, path))
  11. if not full.startswith(WORKSPACE):
  12. raise ValueError("路径越界:仅允许访问工作区内的文件")
  13. return full
  14. def execute_tool(name: str, args: dict) -> str:
  15. try:
  16. if name == "read_file":
  17. with open(safe_path(args["path"]), encoding="utf-8") as f:
  18. return f.read()[:4000]
  19. if name == "edit_file":
  20. p = safe_path(args["path"])
  21. text = open(p, encoding="utf-8").read()
  22. if args["old"] not in text:
  23. return "编辑失败:未找到目标文本,请先读取文件确认内容"
  24. open(p, "w", encoding="utf-8").write(
  25. text.replace(args["old"], args["new"], 1))
  26. return "编辑完成"
  27. if name == "run_command":
  28. proc = subprocess.run(args["command"], shell=True, cwd=WORKSPACE,
  29. capture_output=True, text=True, timeout=30)
  30. return (proc.stdout + proc.stderr)[:4000] or "命令执行完成"
  31. return f"未知工具:{name}"
  32. except Exception as e:
  33. return f"工具执行出错:{e}" # 错误也回填,便于模型自我修正
  34. def agent_loop(llm, messages):
  35. for _ in range(MAX_ITERATIONS):
  36. resp = llm.chat(messages, tools=TOOLS)
  37. messages.append(resp.message)
  38. if not resp.tool_calls:
  39. return resp.text # 无工具调用,视为任务完成
  40. for call in resp.tool_calls:
  41. result = execute_tool(call.name, call.arguments)
  42. messages.append({"role": "tool",
  43. "tool_call_id": call.id, "content": result})
  44. return "已达最大迭代次数,任务未完成。"
  45. def main():
  46. llm = LLMClient(base_url=os.environ["LLM_BASE_URL"],
  47. api_key=os.environ["LLM_API_KEY"],
  48. model=os.environ["LLM_MODEL"])
  49. messages = [{"role": "system", "content": SYSTEM_PROMPT}]
  50. while True:
  51. user_input = input("> ").strip()
  52. if not user_input:
  53. continue
  54. messages.append({"role": "user", "content": user_input})
  55. print(agent_loop(llm, messages))

七、结果验证

建议按递进难度设计三个测试用例,分别验证不同能力:

  1. 只读任务:让智能体阅读工作区内的一个脚本并总结其功能。用于验证文件读取与循环逻辑是否通畅。
  2. 写入任务:让智能体创建一个小工具脚本(如命令行待办清单)并运行它。用于验证文件写入、命令执行以及多步衔接能力。
  3. 修复任务:在示例代码中故意引入一个边界错误(如差一错误),让智能体定位并修复后重新运行测试。用于验证编辑工具与多轮推理能力。

同时逐项核对验证清单:工具调用参数是否合法、是否存在访问工作区之外的路径、是否出现无意义的重复调用、最终回答是否正确且简洁。三项测试全部通过,说明最小可用智能体已经跑通。

八、常见问题与排查

  1. 模型反复调用工具停不下来:通常是系统提示词缺少“完成即总结”的约束,或任务本身定义模糊。解决思路是强化提示词中的终止条件、设置最大迭代次数,并可在工具返回结果中附加提示,引导模型及时收尾。
  2. 工具调用参数格式错误:模型偶尔会传出缺字段或类型不符的参数。应在执行器中做校验,并把具体错误原因回填给模型,通常下一轮它就能自行修正。
  3. 上下文超限报错:多见于读取大文件或长会话场景。对策是对工具输出做长度截断、对历史消息做裁剪与摘要,并建立简单的Token预算控制。
  4. 命令执行长时间卡死:必须为命令执行设置超时时间,并对输出做截断;必要时进一步限制可执行的命令范围。
  5. 修改了错误的文件或越界访问:检查路径规范化逻辑,确保所有相对路径都基于工作区解析,且校验发生在任何读写动作之前。
  6. 行为不稳定、时好时坏:适当降低生成温度,检查工具描述是否含糊,必要时在系统提示词中补充一两个典型操作示例。

九、优化建议

  • 上下文工程:持续打磨系统提示词与工具描述的准确性,这是提升智能体表现投入产出比最高的手段;
  • 安全加固:坚持目录白名单、危险命令人工确认、最小权限原则;进阶做法是将执行环境放入容器或沙箱中隔离运行;
  • 可维护性:使用工具注册表模式保持扩展性,记录每一轮完整的消息与工具调用日志,便于回放与调试;
  • 成本与性能:控制迭代轮数、避免重复读取大文件、合理截断输出,直接降低Token消耗与响应延迟;
  • 进阶方向:在四工具基础上扩展代码检索、测试执行等能力;探索标准化的工具扩展协议以接入更多外部系统;研究多智能体的后台并发调度,以及让代码库结构对智能体更友好(清晰的目录组织、完善的说明文档、充分的类型注解),这些正是当前行业前沿课程与一线团队重点投入的方向。

十、总结

本教程以约200行代码为载体,完整走通了实现一个极简编程智能体的全过程:从理解“模型调用—工具执行—结果回填”的核心循环,到编写系统提示词、定义四个基础工具、实现安全的执行器与主循环,再到分场景验证、排查典型问题并给出优化方向。你会发现,智能体并不神秘,它的能力上限取决于工具设计的严谨程度与上下文工程的精细程度。建议你在此骨架上持续迭代:增加工具、完善权限体系、尝试更复杂的真实任务,逐步建立属于自己的AI原生开发方法论。