智能体面试准备(十二):从零写一个 ReAct Agent——不依赖框架的完整可运行实现
智能体面试准备十二从零写一个 ReAct Agent——不依赖框架的完整可运行实现系列写到第十二篇该交作业了。前面讲了 ReAct 范式B2、工具调用B3、状态机编排B9、评估体系B11今天把这些线头收拢从零写一个不依赖任何 Agent 框架、纯 Python 标准库、可以直接运行调试的 ReAct Agent。为什么面试要准备这个因为手写一个简单 Agent正在成为智能体岗位的新型手撕题。框架用得再熟create_react_agent()一行调用证明不了理解深度能白板写出提示词模板→模型输出解析→工具执行→结果回填这个闭环的人才真正把 ReAct 焊进了脑子。更实际的是自己写过一遍之后LangChain/LangGraph 里那些魔法般的抽象会突然变得透明。一、动手前想清楚:ReAct 闭环的五个组件ReAct 的本质一句话让模型交替产生推理Thought和动作Action动作的观察结果Observation回填进上下文循环往复直到模型认为可以给出最终答案Final Answer。拆成工程组件就是五块组件职责关键设计决策提示词模板告诉模型输出格式与可用工具格式约束越明确解析越稳工具注册表管理工具的名称、描述、参数、执行函数描述是写给模型看的质量决定选对率输出解析器从模型自由文本中抽出 Action/Final Answer必须容错格式漂移是最高频故障执行引擎调工具、捕获异常、把结果回填工具报错要回喂给模型而不是直接崩溃循环控制最大步数、重复动作检测、超时没有护栏的循环生产上必出事故这张表本身就是答题框架面试官问设计一个 Agent 要考虑什么按五个组件逐个展开即可。二、完整实现:150 行可运行代码下面的实现有两个刻意设计其一FakeLLM用规则模拟模型行为让整个 Agent无需 API Key 就能跑通你可以先在纯离线环境理解机制再把FakeLLM换成真实的 OpenAI 兼容接口其二所有护栏最大步数、重复动作、解析失败处理都写全了这些正是面试官区分玩具和工程的检查点。从零实现 ReAct Agent纯标准库无需 API Key 即可运行 import re, json, math # 1. 工具注册表 class ToolRegistry: def __init__(self): self._tools {} def register(self, name, description): def deco(fn): self._tools[name] {desc: description, fn: fn} return fn return deco def spec_text(self): return \n.join(f- {n}: {t[desc]} for n, t in self._tools.items()) def run(self, name, arg): if name not in self._tools: return f错误工具 {name} 不存在可用工具{list(self._tools)} try: return str(self._tools[name][fn](arg)) except Exception as e: # 工具异常回喂模型而非崩溃 return f工具执行出错{e} registry ToolRegistry() registry.register(calculator, 计算数学表达式输入如 23*4712) def calculator(expr): if not re.fullmatch(r[0-9\-*/().\s], expr): raise ValueError(仅支持数字与四则运算) return eval(expr) # 已用白名单正则约束演示可用 registry.register(knowledge_base, 查询知识库输入为关键词) def knowledge_base(query): kb {珠穆朗玛峰: 珠穆朗玛峰海拔 8848.86 米, 马里亚纳海沟: 马里亚纳海沟最深处约 10909 米} for k, v in kb.items(): if k in query: return v return 知识库中未找到相关条目 # 2. 提示词模板 PROMPT 尽你所能回答问题。你可以使用以下工具 {tools} 严格使用以下格式 Question: 需要回答的问题 Thought: 你的思考 Action: 工具名必须是 [{names}] 之一 Action Input: 工具输入 Observation: 工具返回结果 ...Thought/Action/Action Input/Observation 可重复多轮 Thought: 我已知道最终答案 Final Answer: 对原问题的最终回答 开始 Question: {question} {scratchpad} # 3. 输出解析器容错 def parse(text): if Final Answer: in text: return finish, text.split(Final Answer:)[-1].strip() m re.search(rAction:\s*(\w)\s*[\n\r]Action Input:\s*(.), text) if m: return action, (m.group(1).strip(), m.group(2).strip().strip()) return error, 无法解析输出请严格按 Action/Action Input 格式 # 4. 模拟 LLM可换成真实 API 调用 class FakeLLM: 按 scratchpad 状态决定下一步模拟真实模型的 ReAct 行为 def invoke(self, prompt): if Observation: 珠穆朗玛峰海拔 not in prompt: return (Thought: 我需要先查珠峰海拔\n Action: knowledge_base\nAction Input: 珠穆朗玛峰) if Observation: 5 not in prompt: return (Thought: 海拔 8848.86 米换算成千米需要除以 1000 再保留两位\nAction: calculator\nAction Input: 8848.86/1000) return (Thought: 我已知道最终答案\n Final Answer: 珠穆朗玛峰海拔约 8848.86 米即约 8.85 千米) # 5. 执行引擎与循环控制 class ReActAgent: def __init__(self, llm, registry, max_steps6): self.llm, self.registry, self.max_steps llm, registry, max_steps def run(self, question, verboseTrue): scratchpad, seen_actions , set() for step in range(1, self.max_steps 1): prompt PROMPT.format(toolsself.registry.spec_text(), names, .join(self.registry._tools), questionquestion, scratchpadscratchpad) output self.llm.invoke(prompt) kind, payload parse(output) if verbose: print(f--- Step {step} ---\n{output}\n) if kind finish: return {answer: payload, steps: step, status: ok} if kind error: # 解析失败回喂纠错 scratchpad f\nObservation: {payload}\n continue tool, arg payload if (tool, arg) in seen_actions: # 重复动作护栏 scratchpad \nObservation: 检测到重复动作请换一种思路\n continue seen_actions.add((tool, arg)) obs self.registry.run(tool, arg) scratchpad f\n{output}\nObservation: {obs}\n return {answer: None, steps: self.max_steps, status: max_steps} # 运行 if __name__ __main__: agent ReActAgent(FakeLLM(), registry) result agent.run(珠穆朗玛峰海拔多少米换算成千米是多少) print(最终结果:, json.dumps(result, ensure_asciiFalse))直接python react_agent.py就能看到完整的 Thought→Action→Observation 三轮循环与最终答案。接真实模型时只需把FakeLLM.invoke换成对 OpenAI 兼容接口的调用stop[Observation:]参数别忘了——防止模型自己编造 Observation这是接真实 API 时最经典的坑。三、代码讲解:六个面试检查点写完不算完要能讲。以下六个点对应面试官大概率的追问为什么 scratchpad 是字符串拼接而不是消息列表原始 ReAct 论文基于 completion 模式把历史拼进 prompt。改成 chat 模式的消息列表tool role 回填就演化成了 Function Calling 形态——两者机制等价Function Calling 由 API 层强制格式解析更稳B3 详述。解析失败为什么不重试而是回喂把错误信息作为 Observation 回喂让模型自我纠正比机械重试更有效——模型看到格式错了通常下一轮就改对。这是 self-correction 的最小实现。重复动作检测为什么用 (tool, arg) 二元组只记 tool 会误伤同一工具不同参数的合法调用记完整二元组精确命中真死循环。B9 讲过的防死循环三层护栏步数/重复/预算这里落了两层。工具异常为什么返回字符串而不抛出Agent 的鲁棒性原则环境的任何反馈都是信息。参数错误回喂给模型它往往能自己修正参数重试直接崩溃则整条任务报废。eval 的安全问题演示里用白名单正则约束了字符集生产必须换ast.literal_eval或专用表达式引擎并放进沙箱——这里主动提一句 Agent 安全B16 会展开显得有安全意识。这个 Agent 怎么测直接套上一篇B11的评估器固定任务集 参考轨迹统计成功率、轨迹匹配度、工具选择准确率。run()返回的结构化结果就是为评估预留的接口。四、从 150 行到生产还差什么差距项本文实现生产要求模型输出FakeLLM 规则模拟真实 API 流式 重试退避状态管理内存字符串持久化断点续跑、审计并发单任务同步异步并发 队列可观测printtracing 埋点langfuse 等安全白名单正则沙箱执行 权限最小化评估无评估集 CI 回归这张表也是极好的答题素材写一个 demo Agent 和上生产差在哪——按行展开即可且每一行都能挂回本系列对应篇目。收尾建议把这份代码放进自己的 GitHubREADME 里写清设计决策与护栏思路面试时直接投屏讲。能讲清为什么这么写的 150 行比能跑起来的 1500 行更有说服力。下一篇 B13 继续实战给 Agent 加上可持久化的记忆系统把 B6 的记忆理论落成完整可运行的工程实现。

相关新闻

JAVA练习374- 找出字符串中第一个匹配项的下标

JAVA练习374- 找出字符串中第一个匹配项的下标

题目概览 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。 示例 1: 输入:hays…

2026/7/30 19:10:29阅读更多 →
JAVA练习371- 最长公共前缀

JAVA练习371- 最长公共前缀

题目概览 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 示例 1: 输入:strs ["flower","flow","flight"] 输出:"fl" 示例 2&am…

2026/7/30 19:10:29阅读更多 →
JAVA练习370- 最后一个单词的长度

JAVA练习370- 最后一个单词的长度

题目概览 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 1: 输入:s "Hello World" 输出&am…

2026/7/30 19:10:29阅读更多 →
OpenClaw TTS声学模型训练实战指南

OpenClaw TTS声学模型训练实战指南

1. 项目概述:OpenClaw TTS声学模型实战OpenClaw TTS作为新一代开源语音合成框架,其声学模型训练效果直接决定了最终语音输出的自然度和表现力。在实际项目中,训练数据的准备与配置环节往往占据整个流程70%以上的工作量,却鲜有系统…

2026/7/30 20:22:57阅读更多 →
AI视频生成工具应该怎么选择,国内外10个AI视频生成工具对比

AI视频生成工具应该怎么选择,国内外10个AI视频生成工具对比

过去制作一个视频,意味着需要摄影设备、剪辑软件、专业人员以及大量时间。但现在,只需要输入一句文字:“一个穿越未来城市的机器人,在雨夜街头行走。”几分钟后,AI就可以生成一段具有电影感的视频。AI视频生成正在快速…

2026/7/30 20:22:57阅读更多 →
模块化动漫素描教学:从基础到商业应用的全流程设计

模块化动漫素描教学:从基础到商业应用的全流程设计

1. 项目概述:当模块化教学遇上动漫素描十年前我刚接触动漫设计教学时,最头疼的就是学生对着石膏像画完一学期素描后,面对角色设计作业依然手足无措。直到在东京某工作室交流时,看到他们用《进击的巨人》角色拆解教学,才…

2026/7/30 20:22:57阅读更多 →
Ubuntu与Windows网线直连:静态IP配置与网络调试全指南

Ubuntu与Windows网线直连:静态IP配置与网络调试全指南

1. 场景引入:为什么需要一根网线直连?在服务器运维、嵌入式开发或者临时搭建测试环境时,我们经常会遇到一个看似简单却让人头疼的场景:一台没有显示器的Ubuntu服务器,和一台手边的Windows笔记本电脑,如何快…

2026/7/30 20:22:57阅读更多 →
【单片机课设毕设项目】基于单片机的心率血氧超限声光报警系统设计 基于嵌入式开发的人体健康监测终端设计与实现(013201)

【单片机课设毕设项目】基于单片机的心率血氧超限声光报警系统设计 基于嵌入式开发的人体健康监测终端设计与实现(013201)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/7/30 20:22:57阅读更多 →
Helion分布式训练支持:多GPU/TPU环境下的高效内核开发

Helion分布式训练支持:多GPU/TPU环境下的高效内核开发

Helion分布式训练支持:多GPU/TPU环境下的高效内核开发 【免费下载链接】helion A Python-embedded DSL that makes it easy to write fast, scalable ML kernels with minimal boilerplate. 项目地址: https://gitcode.com/gh_mirrors/hel/helion Helion是一…

2026/7/30 20:20:57阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/30 15:03:16阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/30 12:22:27阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/30 15:13:02阅读更多 →
3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 🚀 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 你是否曾经因为iOS系统的严格…

2026/7/30 0:00:58阅读更多 →
[GESP202606 四级] 扫雷

[GESP202606 四级] 扫雷

B4557 [GESP202606 四级] 扫雷 https://www.luogu.com.cn/problem/B4557 中国计算机学会(CCF)2026年6月C四级讲解——扫雷 https://www.bilibili.com/video/BV1MCMg6AEXR/ B4557 [GESP202606 四级] 扫雷 https://www.bilibili.com/video/BV1ZKTj6ZEVh/ 2…

2026/7/30 0:00:58阅读更多 →
Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:58阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/30 0:27:26阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/30 4:47:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/30 15:43:46阅读更多 →