最近在尝试智能体开发时发现很多框架和工具虽然功能强大但入门门槛高内部原理复杂让人望而却步。其实智能体最核心的“自主循环”思想其内核代码可能简单到超乎想象。本文将从一个极简的视角切入带你从零理解智能体的核心运行机制。我们将通过剖析一个仅用while True循环和Bash命令交互构建的智能体内核灵感来源于 Claude Code 的设计思路来揭示智能体如何“自己思考、自己行动”。无论你是想入门 AI 应用开发还是希望深入理解 Agent 原理这篇实战指南都将提供一套清晰、可运行的代码范例和设计思路。1. 智能体开发与自主循环核心概念在深入代码之前我们有必要厘清几个核心概念。这对于理解后续的简化模型至关重要。1.1 什么是智能体Agent在人工智能和软件工程领域智能体通常指一个能够感知环境、自主决策并执行行动以实现特定目标的软件实体。它不同于传统的“输入-处理-输出”程序其核心特征在于自主性和持续性。感知Perception智能体通过API、文件、用户输入、网络数据等方式获取外部信息。决策Decision基于感知到的信息、内置的知识如大语言模型和既定目标决定下一步要做什么。行动Action执行决策例如运行一段代码、调用一个工具、修改一个文件或返回一段文本。目标Goal智能体行为的最终导向可能是回答一个问题、完成一个任务或维持某种状态。一个强大的智能体如 AutoGPT、Devin 或 Claude Code会复杂地集成这些环节。但今天我们要回归本质。1.2 智能体循环Agent Loop的本质智能体循环是驱动智能体持续工作的引擎。它的基本模式可以抽象为以下无限循环初始化状态和目标 循环 直到 目标达成或主动停止 1. 观察获取当前环境/任务状态。 2. 思考分析状态规划下一步行动。 3. 行动执行规划出的动作。 4. 评估观察行动结果更新状态。这个循环就是智能体“永动机”式工作的秘密。我们即将构建的极简内核正是这个循环最直白的代码体现。1.3 Claude Code、Bash 与 Agent HarnessClaude Code这里指的是一种设计模式或概念即让大语言模型如 Claude扮演“大脑”通过生成和解释代码特别是 Shell 命令来与计算机环境交互从而完成复杂任务。它强调模型与系统工具如Bash的无缝衔接。BashUnix/Linux 系统和 macOS 上的默认命令行解释器。它是与操作系统交互的强力工具可以执行文件操作、进程管理、网络请求等几乎所有系统级任务。在智能体架构中Bash 常被作为核心的行动执行器。Agent Harness直译为“智能体套具”或“智能体框架”。它泛指那些用于构建、控制和评估智能体的软件框架或工具包如 LangChain、LlamaIndex 的相关模块。它提供了标准化接口来连接模型、工具和记忆等组件。我们的极简内核可以看作是一个微型的、自制的 Harness。理解这三者的关系我们可以用Agent Harness的思想来设计一个框架让Claude Code模式模型即大脑通过调用Bash这个工具来与环境交互从而实现智能体循环。2. 环境准备与工具说明我们的实验环境力求简单以突出核心逻辑。你只需要一个能运行 Python 和 Bash 的环境。2.1 基础环境要求操作系统推荐 Linux (如 Ubuntu) 或 macOS。Windows 用户可以使用 WSL2 (Windows Subsystem for Linux) 来获得完整的 Bash 环境。Python版本 3.8 及以上。本项目将使用 Python 的subprocess模块来调用 Bash。代码编辑器VS Code、PyCharm 或任何你熟悉的文本编辑器。大语言模型 API为了模拟“思考”环节我们需要一个 LLM。本文将使用 OpenAI 的 GPT 系列 API 进行演示。你需要准备一个有效的 OpenAI API Key。当然核心循环逻辑是通用的你可以轻松替换为 Claude、DeepSeek 等任何提供类似 API 的模型。2.2 安装必要的 Python 库我们主要需要openai库来调用模型。在终端中执行以下命令安装pip install openai如果你使用的是其他模型请安装对应的 SDK例如anthropic用于 Claude。2.3 项目结构初始化创建一个新的项目目录例如simple_agent_core并在其中开始我们的工作。mkdir simple_agent_core cd simple_agent_core后续的所有代码文件都将创建在这个目录下。3. 极简智能体内核30行代码解析现在让我们揭开本文标题中的“30行内核”的真面目。我们将构建一个名为simple_agent.py的文件。3.1 内核代码实现# simple_agent.py import subprocess import openai import os # 1. 初始化设置API Key和目标 openai.api_key os.getenv(OPENAI_API_KEY) # 从环境变量读取更安全 GOAL 在当前目录下创建一个名为‘hello_world.txt’的文件并在其中写入‘Hello from AI Agent!’。 def think(state, goal): 思考环节让LLM根据当前状态和目标决定下一个Bash命令。 prompt f 你是一个在Linux终端中工作的AI助手。你的目标是{goal} 当前工作目录的状态是{state} 请只输出一个能推进目标完成的、最合适的bash命令。不要输出任何解释。 命令 response openai.ChatCompletion.create( modelgpt-3.5-turbo, messages[{role: user, content: prompt}], temperature0.1 # 低温度让输出更确定 ) return response.choices[0].message.content.strip() def act(command): 行动环节执行Bash命令并返回结果。 try: result subprocess.run(command, shellTrue, capture_outputTrue, textTrue, timeout30) return result.stdout, result.stderr, result.returncode except subprocess.TimeoutExpired: return , Command timed out., 1 except Exception as e: return , fCommand failed with exception: {e}, 1 def get_state(): 观察环节获取当前环境状态这里简化为列出当前目录。 stdout, stderr, _ act(ls -la) return stdout if stdout else stderr def main(): 核心智能体循环 print(f 智能体目标{GOAL}) print(*50) while True: # 这就是核心的“永动”循环 # 观察 current_state get_state() print(f[观察] 当前状态\n{current_state}) # 思考 next_command think(current_state, GOAL) print(f[思考] 下一步命令{next_command}) if next_command.lower() in [exit, quit, done]: print(智能体决定终止任务。) break # 行动 print([行动] 执行命令...) stdout, stderr, returncode act(next_command) if stdout: print(f[结果] 标准输出\n{stdout}) if stderr: print(f[结果] 标准错误\n{stderr}) print(f[结果] 返回码{returncode}) # 简单评估如果目标文件已创建且内容正确可以终止本例中我们简化手动检查 # 在实际复杂Agent中这里会有一个复杂的评估函数 if hello_world.txt in current_state: print(✅ 检测到目标文件已存在。任务可能已完成请手动验证。) # 可以加入更复杂的内容检查逻辑这里选择暂停由用户决定 user_input input(任务似乎完成是否继续(y/n): ) if user_input.lower() ! y: break print(-*50) if __name__ __main__: # 在运行前请确保设置了环境变量 OPENAI_API_KEY # export OPENAI_API_KEYyour-api-key-here if not os.getenv(OPENAI_API_KEY): print(错误请设置 OPENAI_API_KEY 环境变量。) exit(1) main()3.2 代码逐行解析导入模块subprocess用于执行 Bash 命令openai用于调用大模型os用于读取环境变量。初始化设置 OpenAI API Key务必通过环境变量设置不要硬编码在代码中和智能体的初始GOAL。think(state, goal)函数这是智能体的“大脑”。它接收当前环境状态和最终目标。构建一个严格的提示词Prompt要求模型只输出一个 Bash 命令。调用gpt-3.5-turbo模型成本低适合实验并设置较低的temperature以获得更稳定、更可执行的命令。返回模型生成的命令字符串。act(command)函数这是智能体的“手和脚”。使用subprocess.run执行传入的 Bash 命令。shellTrue允许使用 Shell 语法如,|。capture_outputTrue和textTrue确保我们能捕获命令的输出结果。包含超时和异常处理防止恶意或死循环命令。返回标准输出、标准错误和命令返回码。get_state()函数这是智能体的“眼睛”。当前实现非常简单仅通过ls -la命令获取当前目录的文件列表作为状态。在复杂智能体中状态可以包含内存、任务列表、API 调用结果等。main()函数与while True循环这就是智能体的“心脏”和核心循环。观察调用get_state()。思考将状态和目标传给think()函数获取下一个命令。决策点检查命令是否为终止指令如 exit。行动调用act()执行命令。反馈打印命令执行结果。评估一个简单的目标检查是否创建了hello_world.txt。这里是智能体“智能”的关键扩展点你可以实现更复杂的评估逻辑来决定循环是否继续。这个循环会一直运行直到模型自己生成exit命令、用户手动中断或我们预设的评估条件被满足。4. 运行你的第一个智能体现在让我们来实际运行这个智能体看它如何自主完成目标。4.1 设置 API 密钥在终端中先设置你的 OpenAI API 密钥export OPENAI_API_KEYsk-你的真实API密钥注意在 Windows CMD 中使用set OPENAI_API_KEYsk-...4.2 执行智能体在项目目录simple_agent_core下运行 Python 脚本python simple_agent.py4.3 观察运行过程你会看到类似下面的输出具体命令可能因模型生成略有不同 智能体目标在当前目录下创建一个名为‘hello_world.txt’的文件并在其中写入‘Hello from AI Agent!’。 [观察] 当前状态 total 8 drwxr-xr-x 3 user staff 96 Apr 10 10:00 . drwxr-xr-x 5 user staff 160 Apr 10 09:58 .. -rw-r--r-- 1 user staff 1234 Apr 10 10:00 simple_agent.py [思考] 下一步命令touch hello_world.txt [行动] 执行命令... [结果] 返回码0 -------------------------------------------------- [观察] 当前状态 total 8 drwxr-xr-x 3 user staff 96 Apr 10 10:00 . drwxr-xr-x 5 user staff 160 Apr 10 09:58 .. -rw-r--r-- 1 user staff 0 Apr 10 10:00 hello_world.txt -rw-r--r-- 1 user staff 1234 Apr 10 10:00 simple_agent.py [思考] 下一步命令echo Hello from AI Agent! hello_world.txt [行动] 执行命令... [结果] 返回码0 -------------------------------------------------- [观察] 当前状态 total 8 drwxr-xr-x 3 user staff 96 Apr 10 10:00 . drwxr-xr-x 5 user staff 160 Apr 10 09:58 .. -rw-r--r-- 1 user staff 24 Apr 10 10:00 hello_world.txt -rw-r--r-- 1 user staff 1234 Apr 10 10:00 simple_agent.py [思考] 下一步命令cat hello_world.txt [行动] 执行命令... [结果] 标准输出 Hello from AI Agent! [结果] 返回码0 -------------------------------------------------- ✅ 检测到目标文件已存在。任务可能已完成请手动验证。 任务似乎完成是否继续(y/n): n4.4 结果验证运行结束后检查当前目录你会发现hello_world.txt文件已经被创建并且内容正确。cat hello_world.txt # 输出Hello from AI Agent!恭喜你已经成功运行了一个具备自主感知、决策和行动能力的极简智能体。它通过“观察-思考-行动”的循环自己生成了touch、echo甚至cat命令逐步完成了你设定的目标。5. 核心机制深度剖析与扩展这个30行的内核虽然简单但完整展示了智能体开发的核心范式。我们来深入分析其设计并探讨扩展方向。5.1while True循环自主性的源泉while True循环是智能体持续运作的基础。它使得程序不再是一次性的脚本而是一个可以应对动态环境、处理多步骤任务的持久性进程。关键在于循环体内的四个阶段必须设计得当否则会陷入死循环或无效行动。关键设计点状态获取 (get_state)必须提供足够且相关的信息给“大脑”做决策。我们的例子只用ls实际可能需要ps进程、df磁盘、curl网络等多种信息。终止条件循环必须有出口。我们的例子提供了三种模型主动输出exit智能终止。评估函数判断目标达成条件终止。用户手动中断外部终止。5.2 Bash万能行动执行器Bash 的强大之处在于它几乎可以操作计算机的一切。这让我们的智能体拥有了极大的行动空间文件操作cp,mv,rm,find,grep进程管理kill,ps,nohup包管理apt-get install,pip install,brew install版本控制git clone,git commit,git push网络请求curl,wget运行任何程序python script.py,node app.js安全警告这是双刃剑。一个不受限制的、能执行任意 Bash 命令的智能体极其危险。它可能rm -rf /删除一切或下载恶意软件。在生产环境中必须实施严格的命令过滤、权限控制和沙箱运行。5.3 提示工程Prompt Engineering的关键作用think()函数中的prompt是控制智能体行为的关键。我们设计的提示词有几个要点明确角色“你是一个在Linux终端中工作的AI助手。”清晰目标直接给出GOAL。提供上下文传入state。严格格式化输出“请只输出一个...bash命令。不要输出任何解释。”如果提示词设计不好模型可能会输出解释性文字导致subprocess.run执行失败。例如如果模型回复“我认为应该使用touch命令。命令是touch hello_world.txt”我们的程序就会尝试执行整句话从而报错。因此提示工程的质量直接决定了智能体的可靠性和稳定性。6. 常见问题与排查思路在运行和扩展这个极简智能体时你可能会遇到以下问题问题现象可能原因排查思路与解决方案ModuleNotFoundError: No module named openai未安装openai库。运行pip install openai。确保在正确的 Python 环境中安装。openai.error.AuthenticationErrorAPI Key 无效或未设置。1. 检查OPENAI_API_KEY环境变量是否正确设置echo $OPENAI_API_KEY。2. 确保 Key 有余额且未过期。3. 不要在代码中硬编码 Key。模型输出的不是纯命令导致执行失败提示词不够严格模型输出了思考过程。1. 强化提示词如使用“只输出命令不要有任何其他文本”。2. 在代码中添加后处理用正则表达式如r([^])提取反引号内的代码。智能体陷入死循环重复执行相同或无效命令1. 状态反馈不足以让模型感知到进展。2. 目标不明确或不可达成。3. 模型“思维”卡住了。1. 丰富get_state()函数提供更多差异化信息如文件内容、时间戳。2. 在think()的提示词中加入历史动作列表避免重复。3. 实现一个“反思”步骤当连续多次命令无效时让模型分析原因并调整策略。执行危险命令如rm -rf /模型可能被诱导或错误理解目标。极其重要在act()函数执行前加入命令验证白名单或黑名单。例如if ‘rm’ in command and ‘-rf’ in command: print(‘危险命令被阻止’); returnsubprocess执行长时间命令卡住命令本身需要长时间运行或等待。1. 如代码所示使用timeout参数。2. 对于需长期运行的后台任务考虑使用nohup或异步执行并让智能体通过ps来检查其状态。在 Windows 上 Bash 命令不工作Windows 默认终端是 CMD 或 PowerShell。1. 使用 WSL2这是最佳方案。2. 或者将act()函数中的命令执行器改为powershell.exe或cmd.exe并调整对应的命令语法。7. 从极简内核到实用智能体进阶实践我们的30行内核是一个完美的起点。要将其发展为实用的智能体你需要考虑以下几个方向的扩展7.1 增强状态管理记忆与上下文目前的智能体是“无状态”的它只根据当前瞬间的目录状态做决策。一个强大的智能体需要有记忆。短期记忆对话上下文将每次的(state, command, result)三元组保存到一个列表中并在每次think()时将这个历史作为上下文传递给模型。这能让模型知道它之前做了什么结果如何避免重复和矛盾。长期记忆向量数据库对于大量文本信息如文档、网页内容可以将其嵌入并存储到向量数据库如 Chroma、FAISS中。当需要相关知识时让智能体先进行检索。7.2 工具扩展超越 BashBash 虽强但并非所有操作都适合用命令行完成。可以定义一套工具集TOOLS { “read_file”: read_file_function, “write_file”: write_file_function, “search_web”: search_web_function, “call_api”: call_api_function, “run_bash”: act, # 我们现有的Bash执行器 }在think()阶段让模型不仅输出命令还可以选择工具和参数。例如模型可能输出{tool: write_file, args: {path: hello.txt, content: Hello}}然后由act()函数解析并调用对应的工具函数。7.3 实现规划与反思任务分解Planning对于复杂目标如“搭建一个博客网站”让模型先进行规划输出一个任务列表[“安装Node.js”, “克隆博客模板”, “安装依赖”, “配置数据库”, “启动服务”]然后循环处理每个子任务。自我反思Reflection在行动失败或陷入僵局时触发一个“反思”步骤。让模型分析错误日志总结失败原因并调整后续计划。这能显著提升智能体的鲁棒性。7.4 安全与权限控制必须做命令过滤建立允许列表Allow List只允许执行预定义的安全命令如ls,cat,grep, 特定的git命令等。对于任何不在列表中的命令直接拒绝。沙箱环境在 Docker 容器或虚拟机中运行智能体限制其对主机系统的访问权限。权限降级不要以 root 或管理员身份运行智能体进程。使用一个权限受限的专用用户。输入验证对模型生成的所有命令和参数进行严格的验证和转义防止注入攻击。7.5 集成成熟框架当你理解了核心循环后可以转向使用成熟的框架来获得更多功能如 LangChain、AutoGen、Transformers Agents 等。这些框架提供了标准化工具、记忆管理、多智能体协作等高级功能我们的极简内核是理解它们底层原理的绝佳钥匙。8. 总结智能体开发的核心是循环与控制通过这个从零构建的30行智能体内核我们清晰地看到智能体开发并非遥不可及。其核心就是实现一个可控的、具备感知-决策-行动能力的循环。while True代表了智能体的自主性与持久性。Bash代表了智能体与环境交互的能力边界。think()函数中的 LLM代表了智能体的决策与规划能力。状态、目标、评估构成了智能体行为的导向与约束。下一步你可以替换大脑尝试将think()函数中的 OpenAI API 换成 Claude、DeepSeek-V3 或本地部署的 Llama 模型观察不同模型在规划能力上的差异。丰富感知让get_state()返回更多信息如系统负载、网络状态、特定文件内容。增加工具为智能体集成 Python 函数、Web API 调用等更丰富的工具。设计复杂任务尝试让智能体完成“整理下载文件夹”、“监控日志报错并通知”等更实际的任务。记住强大的智能体始于一个简单的循环。理解这个基础范式是你深入 Agent 开发世界最重要的一块基石。