315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」

搜索
AI-TNT
正文
资源拓展
315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」
2025-05-03 17:31

知名 Go 大佬 Thorsten Ball 最近用 315 行代码构建了一个编程智能体,并表示「它运行得非常好」且「没有护城河」(指它并非难以复制)。


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


Thorsten Ball 在编程领域以其对系统编程和编程语言的深入研究而闻名,尤其擅长解释器、编译器和虚拟机等主题。


他撰写的《用 Go 语言自制编译器》和《用 Go 语言自制解释器》则被视为编译原理领域的「入门平替」。


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


虽然这个编程智能体无法和 Claude、Gemini 等推出的编码功能相媲美,却为初学者提供了一个探索智能体的良好学习范例。


这反映了他一贯的理念:通过实践和开源项目揭开技术的「神秘面纱」。


Thorsten Ball 在博客中分享了他的具体操作步骤。(注:本文中的代码截图可能并不完整,详细内容请参阅原博客。)


博客地址:https://ampcode.com/how-to-build-an-agent


乍看之下,智能体编辑文件、运行命令、自行解决错误似乎很复杂,但实际上只需一个大语言模型、一个循环和足够的 tokens。


构建一个小型的智能体并不需要太多工作,少于 400 行代码即可实现,且大部分是样板代码。


接下来将展示如何从零开始逐步构建一个「game changer」,读者可以尝试亲自动手编写代码。


准备工作


首先准备好我们的「文具」:


  • GoANTHROPIC_API_KEY


铅笔出场!让我们直接开始,用四个简单的命令来设置一个新的 Go 项目:



315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


现在,打开 main.go,作为第一步,将需要的东西的框架放入其中:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


是的,这还没有编译。但是我们这里有一个 Agent,它可以访问 anthropic.Client


(默认情况下,它会查找 ANTHROPIC_API_KEY),并且可以通过从终端上的 stdin 读取来获取用户消息。


现在让我们添加缺少的 Run() 方法:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


这并不多,对吧?90 行代码,而其中最重要的就是 Run() 中的这个循环,它让我们能够与 Claude 对话,但这已经是这个程序的核心了。


对于一个核心来说,这个过程相当简单:我们首先打印一个提示,询问用户输入内容,将其添加到对话中,发送给 Claude,


然后将 Claude 的回复添加到对话中,打印出回复,然后再循环进行。


你日常使用的 AI 聊天应用其实就是这样的,只不过这是在终端中实现的。


运行它:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


然后你可以和 Claude 对话了,就像这样:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


注意到我们在多个回合中保持了同一个对话吗?它记住了我们在第一条消息中的名字。每次回合对话都在增长,我们每次都发送整个对话。


服务器——准确来说是 Anthropic 的服务器——是无状态的。它只看到 conversation 片段中的内容,维护这一点由我们来负责。


现在继续,因为输出结果很糟糕,这还不是一个智能体。


什么是智能体?可以这样定义:一个具有访问工具能力的大语言模型(LLM),这些工具使其能够修改上下文窗口之外的内容。


添加工具


一个具有工具访问能力的大语言模型(LLM)是什么呢?


工具的定义是这样的:你向模型发送一个 prompt,告知它在想要使用「工具」时应以特定方式回复。然后,你接收消息后「使用工具」执行该指令,并返回结果。


其他一切都是在这一基础上进行的抽象。


想象一下,你正在与朋友交谈,你告诉他们:「在接下来的交流中,如果你想让我举起手臂,就眨眼。」这种表达方式虽然有些奇怪,但概念非常容易理解。


我们已经能够在不改变任何代码的情况下尝试这种方法。


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


我们告诉 Claude,当它想知道天气时,就用 get_weather 来「眨眼」。接下来的步骤是举起我们的手臂,并回复「工具的结果」。


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


第一次尝试非常成功!


这些模型经过训练和微调,能够使用「工具」,并且非常注重利用这些工具。


到 2025 年,它们在一定程度上「知道」自己不具备所有信息,因此可以借助工具获取更多信息。(虽然这不是完全准确的描述,但目前这个解释足够了。)


总结关于工具使用的关键点有:


  • 你告诉模型有哪些工具是可用的。


  • 当模型想要使用工具时,它会通知你,你执行工具并将响应发送回模型。


为简化步骤(1),大型模型提供商已经内置了 API,用于发送工具定义。


现在,让我们开始构建我们的第一个工具:read_file。


read_file 工具


为了定义 read_file 工具,我们将使用 Anthropic SDK 建议的类型,但请记住:在底层,这一切最终都会变成发送给模型的字符串。


这一切都是「如果你希望我使用 read_file,就眨眼」。


我们要添加的每个工具都需要以下内容:


• 名称


• 描述,告诉模型这个工具的功能、何时使用、何时不使用、返回什么等等。


• 输入模式,描述为 JSON schema,说明该工具期望什么输入以及输入的形式。


• 一个实际执行工具的函数,使用模型发送给我们的输入并返回结果。


那么让我们把这些添加到我们的代码中。



315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


现在我们给出 Agent 工具定义:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」



并将它们发送到 runInference 中的模型:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


用户发送工具定义,Anthropic 在服务器上将这些定义包装在这个系统提示中(并不多),


然后将其添加到对话中,如果模型想要使用该工具,它就会以特定的方式回复。


好的,所以工具定义正在发送,但我们还没有定义任何工具。让我们来定义 read_file 工具。


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


这并不多,是不是?这只是一个函数,ReadFile,以及模型将看到的两个描述:


一个是描述工具本身的 Description(Read the contents of a given relative file path. ...),另一个是该工具拥有的单一输入参数的描述(The relative path of a ...)。


ReadFileInputSchema 和 GenerateSchema 之类的工作是做什么的?我们需要这些来为工具定义生成一个 JSON 模式(schema),然后发送给模型。


为此,我们使用 jsonschema 包,需要进行导入和下载:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


然后运行以下命令:


go mod tidy



然后,在 main 函数中,我们需要确保我们使用定义:



315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


是时候尝试一下了!


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


哇哦,它想要使用这个工具!显然,你的输出可能会有些不同,但听起来 Claude 确实知道它可以读取文件,对吧?


问题是我们没能聆听!当 Claude 给出提示时,我们没有去注意这一点,我们需要解决这个问题。


通过一个简单、快捷且异常敏捷的动作,我们可以通过替换智能体的 Run 方法来实现:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


可以说,这段过程 90% 是固定格式,只有 10% 是关键部分:当我们从 Claude 收到消息时,我们会检查 Claude 是否要求我们执行某个工具,通过查看内容的类型是否为「tool_use」来判断;如果是这样,我们就交给 executeTool 处理,在本地注册表中通过名称查找该工具,解析(unmarshal)输入,执行它,并返回结果。如果出现错误,我们会翻转一个布尔值。就是这样。


(是的,的确有一个循环套在另一个循环里,但这不重要。)


我们执行工具,将结果发回给 Claude,然后再次请求 Claude 的响应,就是这么简单。


echo 'what animal is the most disagreeable because it always says neigh?' >> secret-file.txt


这会在我们的目录中生成一个名为 secret-file.txt 的文件,里面包含一个神秘的谜题。


就在同一个目录中,我们运行新的工具使用智能体,要求它查看该文件:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


你只需要给它一个工具,它就会在认为有助于解决任务时使用它。


我们没有说「当用户询问文件时,阅读文件」,也没有说「如果某个东西看起来像是文件名,找出如何读取它」。


我们说的是「帮我解决这个文件里的问题」,Claude 就意识到它可以读取文件来回答这个问题,然后就去做了。


当然,我们可以加以具体引导并鼓励使用某个工具,但它基本上可以自主完成这些任务:


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」


作者接下来还介绍了添加 list_files(列出文件的工具)和 edit_file(让 Claude 编辑文件的工具)的方法,感兴趣的读者可以阅读博客原文。


文章来自于微信公众号“机器之心”,作者 :Thorsten Ball


315 行代码构建编程助手,Go大佬揭开智能体的「神秘面纱」

1
AI代理

【开源免费】Browser-use 是一个用户AI代理直接可以控制浏览器的工具。它能够让AI 自动执行浏览器中的各种任务,如比较价格、添加购物车、回复各种社交媒体等。

项目地址:https://github.com/browser-use/browser-use


2
智能体

【开源免费】AutoGPT是一个允许用户创建和运行智能体的(AI Agents)项目。用户创建的智能体能够自动执行各种任务,从而让AI有步骤的去解决实际问题。

项目地址:https://github.com/Significant-Gravitas/AutoGPT


【开源免费】MetaGPT是一个“软件开发公司”的智能体项目,只需要输入一句话的老板需求,MetaGPT即可输出用户故事 / 竞品分析 / 需求 / 数据结构 / APIs / 文件等软件开发的相关内容。MetaGPT内置了各种AI角色,包括产品经理 / 架构师 / 项目经理 / 工程师,MetaGPT提供了一个精心调配的软件公司研发全过程的SOP。

项目地址:https://github.com/geekan/MetaGPT/blob/main/docs/README_CN.md

3
微调

【开源免费】XTuner 是一个高效、灵活、全能的轻量化大模型微调工具库。它帮助开发者提供一个简单易用的平台,可以对大语言模型(LLM)和多模态图文模型(VLM)进行预训练和轻量级微调。XTuner 支持多种微调算法,如 QLoRA、LoRA 和全量参数微调。

项目地址:https://github.com/InternLM/xtuner

4
prompt

【开源免费】LangGPT 是一个通过结构化和模板化的方法,编写高质量的AI提示词的开源项目。它可以让任何非专业的用户轻松创建高水平的提示词,进而高质量的帮助用户通过AI解决问题。

项目地址:https://github.com/langgptai/LangGPT/blob/main/README_zh.md

在线使用:https://kimi.moonshot.cn/kimiplus/conpg00t7lagbbsfqkq0

IOS下载
安卓下载
微信群
沪ICP备2023015588号