项目背景与核心架构逻辑
本视频旨在展示如何创建一个仅由不到 330行代码 构成的编码代理(Coding Agent)。该演示项目基于Andrew Ford之前的视频《How Coding Agents Work》,是一个包含故意遗留Bug的小型Node.js代码库,主要涉及 package.json、total.js 和 test.test.js。代理的核心工作流是一个循环过程:用户提示与工具调用被发送至 Claude API,随后模型要么响应执行特定工具,要么直接输出文本。这种架构确保了代理能够像人类开发者一样逐步理解项目结构、读取文件内容并解释其中的Bug。
"It's showing that it is reading the files into code... giving a bit of an explanation about them. And also the bug itself."
这种循环机制是构建智能代理的基础,它要求系统能够持续维护对话状态并动态响应模型的需求。通过这种交互模式,代理不仅能执行代码任务,还能解释其推理过程,从而提供透明的开发辅助体验。
环境配置与依赖安装
构建该代理的第一步是准备Node.js运行环境,推荐使用 Node version 26(或LTS版本)。开发者需创建项目目录并初始化npm,设置包类型为 module。随后安装关键依赖:
- Anthropic AI SDK:用于与Claude模型进行通信。
- TypeScript (ts) 和 TSX:用于类型安全的脚本编写。
- Node Types:提供必要的TypeScript类型定义。
此外,必须创建 .env 文件并填入从Anthropic网站获取的 ANTHROPIC_API_KEY。这是代理与模型服务建立连接的身份验证凭证。所有依赖安装完成后,项目即具备了运行基础代码所需的软件栈支持。
核心类结构与输入处理机制
在 main.ts 文件中,首先导入Anthropic SDK及Node的 createInterface 模块。后者用于处理命令行输入,自动管理标准输入/输出流及特殊字符,简化了用户交互的开发难度。代码中定义了 Message 类型以适配Anthropic的消息格式,并指定使用 Opus 5.5 模型。为了增强命令行输出的可读性,代码中引入了颜色对象(Color Object),区分用户消息与Claude的回复。
代理的核心是一个名为 Agent 的类。其构造函数初始化Anthropic客户端,并定义了一个异步函数用于启动主循环。该循环通过 getUserMessage 获取用户输入,若未收到输入则退出循环。对话数组(Conversation Array) 在此过程中扮演关键角色,它存储了所有的消息参数。正如原文所述:
"The model doesn't remember anything between calls. So every time we call it, we send the whole conversation again. And that array is the agent's entire memory."
这意味着代理没有内置的长期记忆,其上下文完全依赖于每次请求时发送的历史消息数组。
推理循环与工具定义规范
主运行逻辑包含一个 while 循环,持续获取用户输入并推入对话数组。随后调用异步的 runInference 函数,将消息发送给Claude模型。runInference 负责处理与Anthropic客户端的实际通信。当模型返回响应时,代码会检查停止原因(如拒绝或正常结束),并通过遍历消息内容将文本输出到控制台。
为了让代理具备执行代码的能力,必须为其定义 工具(Tools)。每个工具由四个核心部分组成: 1. Name:工具的标识名称。 2. Description:描述模型在何种场景下使用该工具,这是模型决策的关键依据。 3. JSON Schema:定义输入参数的严格格式,确保模型传递的数据结构正确。 4. Code:实际执行的逻辑代码,返回字符串或抛出错误。
这种结构化的工具定义方式使得代理能够根据上下文动态选择并执行外部功能,从而扩展其能力边界。
工具定义架构与核心接口设计
构建自定义 Agent 的第一步是确立模块化且类型安全的工具(Tools)定义体系。在 tools.ts 文件中,开发者引入了 Anthropic SDK 以获取标准的工具定义接口。该体系的核心在于一个明确的 TypeScript 接口,它规定了每个工具必须包含的三个关键要素:名称(name)、描述性文本(description)以及 输入模式定义(input schema)。这种结构化的设计确保了 LLM 能够准确理解每个工具的用途及所需参数格式,而具体的执行逻辑则被封装在独立的函数中。通过这种分离架构,Agent 的核心推理引擎与底层系统操作解耦,使得新增工具只需遵循既定接口规范即可无缝集成。这种设计不仅提高了代码的可维护性,也为后续扩展复杂的多步操作奠定了坚实基础。
基础文件系统工具的实现细节
在具体的工具实现中,read_file(读取文件)被设计为最基础且最简单的功能模块。该工具接收一个相对路径作为参数,其描述明确指出仅用于文件而非目录。在代码层面,开发者利用 Node.js 的 fs(文件系统)模块中的 readFile API。当工具被调用时,系统会读取指定路径下的文件内容,并将其转换为 UTF-8 编码的字符串返回。这一过程确保了文本数据的完整性和兼容性。紧接着,list_files(列出文件)工具被引入以增强 Agent 对目录结构的感知能力。该工具支持递归遍历,能够列出指定路径下的所有文件和子文件夹。目录名称在返回结果中会以斜杠(/)结尾,以此区分文件与文件夹。实现逻辑包括对空字符串的检查、当前目录(.)的默认处理,以及对返回结果的排序和格式化映射。这些基础工具为 Agent 提供了读取和理解本地文件系统状态的能力。
安全机制与受控命令执行
为了保障系统安全性,bash_command(Bash 命令)工具被设计为具有严格的访问控制机制。该工具并非直接开放执行权限,而是设置了一道用户授权门控(Gate)。只有当用户在交互中明确输入特定关键词“why”时,Agent 才会获准执行该 Bash 命令。这种设计防止了 LLM 因幻觉或恶意提示而随意执行破坏性系统指令,体现了安全优先(Safety First)的开发原则。在代码结构中,该工具的定义同样遵循前述的接口规范,包含名称、描述及输入 Schema。通过将高风险操作置于用户确认之后,开发者在赋予 Agent 强大系统交互能力的同时,有效地控制了潜在风险。这种受控执行模式是构建生产级 AI Agent 的关键实践之一,确保了自动化操作的可审计性和可控性。
Agent 推理循环与工具执行逻辑
在 main.ts 主程序中,Agent 的初始化过程涉及将上述定义的工具注入到 Anthropic SDK 的配置中。关键在于,传递给 Claude 的仅是工具的元数据(名称、描述和 Schema),而非具体的执行代码。实际的函数实现保留在开发者本地机器上,永远不会发送给 LLM。推理循环(Loop)的逻辑经过精心设计:当 Claude 返回包含工具调用的响应时,系统不会立即等待用户输入,而是自动在后台执行相应的工具函数(如 execute_tool)。只有当 Claude 没有更多需要调用的工具,且任务完成时,循环才会暂停并等待用户输入。这种“自动执行-反馈结果”的闭环机制极大地提升了 Agent 处理复杂任务的效率。此外,为了增强调试体验,开发者在工具执行结果中加入了颜色标记(Color),以便清晰区分不同工具的输出。整个流程展示了如何将静态的工具定义转化为动态的、可交互的智能代理行为。
文件编辑工具的错误处理与逻辑流程
在构建 Agent 的工具链时,edit_file(编辑文件)工具的设计核心在于其严谨的错误处理机制。该工具的输入来自 Claude,用户需提供文件路径、旧字符串和新字符串。如果提供的参数无效(如路径为空或新旧字符串相同),工具将直接返回错误,这迫使模型重新审视输入。其内部逻辑遵循一个清晰的流程图:首先检查文件是否存在;若不存在且旧字符串为空,则创建新文件;否则报错。若文件存在,工具尝试用新字符串替换旧字符串。关键在于,当发生错误时(如未找到旧字符串),工具会返回 error: true 标志。
"The key thing is there is that the errors there are important. So those become a error equal true, and then the model will try and read that error and try again."
这种设计利用了 LLM 的自我修正能力。模型能够读取返回的错误信息,并据此调整策略再次尝试,这是该工具设计中最精妙的部分。为了实现这一功能,开发者需要在代码中集成 make_directory 和 writeFile 函数。编辑工具的实现分为两部分:首先是定义工具的 Schema,明确告知 Claude 所需的属性(如路径、旧字符串必须与新字符串不同);其次是执行逻辑,包括检查文件是否存在以及调用底层的写入函数。同时,还需要添加创建新文件的辅助功能,其逻辑类似但更简单:若目录存在则报错,否则在根目录下创建文件。最后,必须更新主程序中的工具数组,将 edit_file 注册为可用工具。只有当错误被正确返回给 Claude 时,模型才能利用这一反馈循环来修复问题。
Bash 工具的安全限制与执行机制
bash 工具是 Agent 中最具风险的部分,因为它允许在终端中执行 Shell 命令。为了控制这种高风险操作,开发者引入了多重安全限制机制。首先是超时设置:如果脚本运行时间过长(例如超过 30 秒),进程将被强制终止,防止 Agent 陷入无限等待或启动需要长时间响应的服务器。其次是输出长度限制:为了防止终端被大量数据淹没,工具实现了一个截断函数(truncate function),当输出字符数超过设定的最大值时,只保留前部分文本并附加提示信息。这些限制旨在防止 Agent 自身卡死或过载,但无法阻止恶意命令的执行。
"The time limit and the output limit is going to stop the agent getting stuck or flooding itself, but that's not going to stop a bash command."
在技术实现上,该工具分为 make_bash_tool 和运行函数两部分。使用 Node.js 的 child_process.spawn 方法启动命令,将其置于独立进程组并分离运行。代码中定义了常量超时时间,一旦触发即杀死进程。由于技术限制无法完全屏蔽命令危害,最终的安全防线依赖于用户确认。开发者实现了 get_user_message 函数,在每次执行 Bash 命令前询问用户是否同意。默认值为“否”,只有当用户明确输入 "Y" 时,命令才会被执行。这种权限门控(permission gate)将最终决策权交还给人类用户,确保任何潜在的危险操作都经过人工审核。
工具集成与权限确认的实际演示
在完成所有工具的代码编写后,开发者将其整合到主程序中。首先导入 make_bash_tool 函数,并在工具数组中注册它。关键步骤是在调用该工具前插入用户确认逻辑:系统会高亮显示待执行的命令,并提示用户输入 "Y" 确认。这一流程确保了 Agent 在执行敏感操作时的可控性。
为了验证功能,开发者运行了 Agent。首先测试基础的 list_files 工具,Agent 成功返回了当前目录下的文件列表:Notes.txt, package.json, total.js 和 total.test.js。随后,为了演示 Bash 工具的权限控制机制,开发者要求 Agent 删除 Notes.txt 文件。Agent 生成了相应的 Bash 命令(如 rm Notes.txt)并列出后续操作。此时,系统暂停执行,向用户展示该危险命令。由于存在通配符等潜在风险(如误删所有文件),用户必须仔细审查。在确认无误并输入 "Y" 后,命令得以执行。Agent 随后再次列出文件目录以验证结果,确认 Notes.txt 已被成功删除,仅剩余其他必要文件。这一过程完整展示了从工具定义、安全限制到用户确认的闭环流程。
"Every bash command needs a Y from you before it runs."
通过这一案例,清晰地表明了在赋予 AI 系统操作权限时,人工确认环节是不可或缺的安全屏障。虽然技术上的超时和截断能保护系统稳定性,但只有用户的主动授权才能防止不可逆的数据损失。
编码代理修复测试的实际演示
在构建好基础的编程智能体后,接下来的核心环节是验证其实际修复能力。演示中设定了一个具体的测试失败场景:智能体需要识别错误并修正代码逻辑。当用户输入确认指令后,智能体展示了其内部的处理路径与决策依据。它首先读取了目标文件 total.js,识别出需要替换的旧字符串及新字符串的具体内容。随后,智能体规划了执行 npm test 的 Bash 脚本命令以验证修复结果。这一过程清晰地展示了智能体如何通过工具链(读取、编辑、运行脚本)来闭环解决代码问题。用户只需在终端确认执行,智能体便完成了从诊断到修复的全自动流程。
代码缺陷分析与逻辑修正细节
本次演示的具体案例涉及一个计算总价的函数 calculateTotal。原有的代码逻辑存在严重缺陷:它仅对商品单价进行累加,而完全忽略了商品的购买数量。这导致测试结果不符合预期。修正前的计算逻辑为 3 + 6 = 9,而正确的业务逻辑应当是考虑数量后的加权求和。修复方案是将每个商品的价格乘以其对应的数量,从而得出准确的总价。修正后的计算逻辑变为 3 * 2 + 6 * 1 = 12,这与测试用例的预期结果完全一致。此外,代码还增加了对缺失数量字段的容错处理,确保在字段为空时能正常输出名称。这一案例生动地说明了智能体能够理解业务逻辑并执行精确的代码重构。正如视频中所述:
"The problem was that calculateTotal added up each item price but it ignored its quantity... The fix, each item's price is now multiplied by its quantity so that's as expected and if an item has no quantity field line will come out as named."
技术实现原理与安全建议总结
从技术架构层面来看,本教程展示了如何利用 Anthropic SDK 构建一个极简的编程智能体。其核心在于赋予模型一系列基础工具,包括文件读取、代码编辑、目录列表以及 Bash 脚本执行能力。通过这些工具的组合,智能体能够自主完成复杂的开发任务。然而,视频作者特别强调了安全性与生产环境使用的局限性。虽然演示中的智能体功能完整,但直接用于日常开发存在风险,因为缺乏必要的安全检查机制和权限控制。作者建议普通用户继续使用成熟的工具如 Claude Code 或 Codex CLI,并鼓励开发者在后续工作中深入思考这些智能体背后的工作逻辑与工具调用机制。视频最后呼吁观众点赞订阅,以支持后续更多关于智能体构建的内容分享。
"I wouldn't recommend you use that day to day because there's obviously a lot more checks that need in place to make it safe. So I'd recommend keep using the tools you know Claude Code or Codex CLI and try and think about what the tool is doing next time you're doing some work."
结论
本演示证实,基于不到330行代码及Anthropic SDK构建的编码代理具备自主诊断与修复Bug的能力。通过工具链闭环,它能读取文件、识别逻辑缺陷(如忽略数量的计算错误)、执行编辑并运行测试验证,展示了LLM在复杂任务中的自我修正潜力。其核心优势在于透明的推理过程与模块化架构,使开发者能清晰理解代理决策路径。
然而,该方案存在显著安全短板。Bash命令执行依赖用户手动确认(输入"Y"),且缺乏生产级权限控制,存在误删文件或执行恶意指令的风险。技术限制如超时和输出截断仅防卡死,不防危害。因此,该架构适合作为学习工具调用机制的教学案例,而非日常开发替代方案。普通用户应继续使用Claude Code等成熟工具,开发者可借此深入理解智能体底层逻辑与安全风险。