智能体面试准备(十二):从零手写一个 ReAct Agent——把 B1 到 B11 焊成一台能跑的
智能体面试准备十二从零手写一个 ReAct Agent——把 B1 到 B11 焊成一台能跑的机器写在前面B2 讲过 ReAct 范式B11 讲过怎么评估 Agent。这篇是收官实战——不调任何框架LangChain/CrewAI 统统不用纯标准库从零写一个完整、可运行的 ReAct Agent。它包含 Thought/Action/Observation 循环、工具注册、解析器、最大步数护栏并内置一个假 LLM让它离线就能跑通你面试现场复制就能演示。一、ReAct 到底长什么样ReAct Reason Act。核心是一个循环Thought: 我需要先查一下 X Action: tool_name Action Input: 参数 Observation: 工具返回结果 Thought: 有了结果我再算一下 Y Action: another_tool ... Thought: 信息够了可以回答了 Final Answer: 最终答案模型不是一步出答案而是显式把思考写出来然后决定调什么工具看到结果再思考下一步直到能回答。这正是 B1 讲的自主智能体的最小形态也是 B9 状态机、B10 Agentic RAG 的底层循环。二、我们要实现什么模块职责Tool一个函数 名字 描述能被注册和调用Parser从模型文本里抽出 Action / Action Input / Final AnswerAgentLoop循环拼 prompt → 调 LLM → 解析 → 执行工具 → 回填 ObservationGuardrail最大步数、重复动作检测防死循环呼应 B9FakeLLM离线可跑的伪模型按规则产出合法 ReAct 格式三、完整可运行代码复制即跑纯标准库import re import math from typing import Callable, Dict, List # ---------------- 1. 工具定义 ---------------- class Tool: def __init__(self, name: str, desc: str, func: Callable): self.name, self.desc, self.func name, desc, func def _calc(expr: str) - str: # 极简计算器只允许数字和 - * / ( )防注入 if not re.fullmatch(r[0-9\-*/().\s], expr): return ERROR: 非法表达式 try: return str(eval(expr, {__builtins__: {}}, {})) except Exception as e: return fERROR: {e} def _search(q: str) - str: # 假搜索命中本地知识库 kb { 光速: 光速约为 3e8 m/s, 圆周率: 圆周率 pi 约等于 3.14159, 地球半径: 地球平均半径约 6371 km, } for k, v in kb.items(): if k in q: return v return 未找到相关结果 def _weather(city: str) - str: fake {北京: 晴 26℃, 上海: 多云 29℃, 深圳: 雷阵雨 30℃} return fake.get(city, f{city} 天气未知) TOOLS: Dict[str, Tool] { Calculator: Tool(Calculator, 计算数学表达式, _calc), Search: Tool(Search, 检索常识知识, _search), Weather: Tool(Weather, 查询城市天气, _weather), } # ---------------- 2. 解析器 ---------------- def parse_response(text: str): 从模型输出抽取动作优先找 Final Answer m re.search(rFinal Answer:\s*(.), text, re.S) if m: return (final, m.group(1).strip()) a re.search(rAction:\s*(\w), text) i re.search(rAction Input:\s*(.), text) if a and i: return (action, a.group(1).strip(), i.group(1).strip()) return (none, None) # ---------------- 3. 假 LLM离线可跑 ---------------- def fake_llm(question: str, history: str) - str: 规则式伪模型演示 ReAct 循环无需真实 API # 已拿到天气且拿到常识 - 给最终答案 if Weather in history and Search in history: return Final Answer: 北京今天晴 26℃光速约为 3e8 m/s来自检索。 if Action: Weather in history: return Thought: 拿到天气了再查一下光速常识。\nAction: Search\nAction Input: 光速 if Action: Search in history: return Thought: 已检索到常识现在查北京天气。\nAction: Weather\nAction Input: 北京 # 第一步决定先检索 return Thought: 用户问北京天气和光速我先检索光速常识。\nAction: Search\nAction Input: 光速 # ---------------- 4. Agent 主循环 ---------------- def run_agent(question: str, max_steps: int 6) - str: prompt_header ( 你是一个 ReAct Agent。可用工具 .join(f{t.name}({t.desc}) for t in TOOLS.values()) \n格式\nThought: ...\nAction: 工具名\nAction Input: 参数\n 或 Final Answer: 答案\n ) history for step in range(1, max_steps 1): inp prompt_header f\n问题{question}\n history out fake_llm(question, history) print(f\n[Step {step}] LLM 输出:\n{out}) kind parse_response(out)[0] if kind final: return parse_response(out)[1] if kind action: _, name, arg parse_response(out) tool TOOLS.get(name) obs tool.func(arg) if tool else fERROR: 未知工具 {name} history out f\nObservation: {obs}\n print(f - 调用 {name}({arg}) {obs}) else: history out \nObservation: 解析失败请按格式输出。\n return ERROR: 超过最大步数未得到最终答案护栏触发 # ---------------- 5. 运行 ---------------- if __name__ __main__: q 北京今天天气怎么样光速是多少 print(问题:, q) answer run_agent(q) print(\n 最终答案 ) print(answer)跑这段你会看到完整的 ReAct 轨迹Step1 决定 Search → 拿到光速 → Step2 决定 Weather → 拿到北京天气 → Step3 综合出 Final Answer。全程不联网、不依赖任何第三方库。这就是一个最小可运行的自主 Agent。面试加分指出eval计算器有注入风险虽已用__builtins__{}和正则过滤但生产应改用ast解析或numexpr并指出 fake_llm 仅用于演示真实环境换成openai/本地模型调用循环结构完全不变。这正是框架无关的核心价值——你理解了循环换任何 LLM 都能接。四、把 B1–B11 的零件对号入座这个 80 行的小东西其实把整个系列串起来了本 Agent 的部件对应前面哪篇Thought/Action/Observation 循环B2 ReAct 范式工具注册表 TOOLSB3 Function Calling / B4 MCP解析器 parse_responseB2 动作格式约束最大步数 max_steps 护栏B9 状态机三层护栏多工具协作SearchWeatherCalcB7 多智能体/工具协作假 LLM 可替换为真实 轨迹可记录B11 轨迹级评估检索工具A12 RAG / B10 Agentic RAG这段代码的history变量本质就是 B11 说的轨迹trajectory——把它存下来就能直接套 B11 的evaluate_agent算工具选择准确率和步数。一个闭环就通了。五、如何升级这个玩具 Agent面试延伸面试官常问这玩具怎么变生产级你按这个清单答换真实 LLMfake_llm→ 调 APIprompt 加强格式约束 few-shot。加反射Reflection每步后让模型自评这步对吗错就重试呼应 B5/B10 评估器。加记忆把 history 存向量库做长期记忆B6。加规划复杂任务先 Plan 再 ExecuteB5而非纯反应式。加并行/多 Agent拆子任务给不同 AgentB7。加评估接 B11 的 eval set 做回归。六、面试高频追问自测ReAct 和 Chain-of-Thought 区别 → CoT 只有思考没有行动ReAct 在思考间插入 Action/Observation能调用外部工具突破参数知识边界。Action 解析失败了怎么办 → 解析器兜底提示按格式重输或重试连续失败触发护栏终止。会死循环吗怎么防 → 会用 max_steps 重复动作检测B9 讲的三层护栏。为什么不直接让模型输出 JSON → 可以但自由文本 ReAct 更鲁棒、可解释生产常用函数调用B3替代文本解析更稳。小结从零手写 ReAct Agent 不难难的是理解它每个部件为什么存在循环是为了边想边查、解析器是为了让程序能驱动工具、护栏是为了不死循环、history 是为了可评估可复盘。这段代码把 B1–B11 全部串起来了——它是你面试时最能拿出东西的武器不仅能讲还能当场跑。B 系列到此完成认知→架构→实战的闭环B13 起进入两个完整 Agent 收官实战持久化记忆 Agent、MCP 实战。本篇 B12 完。Day 6 四篇 A11/A12/B11/B12 全部完成A 系列覆盖压缩与 RAG、B 系列进入评估与完整实现系列交叉引用完整。

相关新闻

Equalizer APO深度解析:Windows音频处理流水线的架构揭秘与实战宝典

Equalizer APO深度解析:Windows音频处理流水线的架构揭秘与实战宝典

Equalizer APO深度解析:Windows音频处理流水线的架构揭秘与实战宝典 【免费下载链接】equalizerapo Equalizer APO mirror 项目地址: https://gitcode.com/gh_mirrors/eq/equalizerapo Equalizer APO是一款基于Windows APO(Audio Processing Obje…

2026/9/26 16:13:56 阅读更多 →
嵌入式开发核心:ADC与PWM原理、实战与STM32应用全解析

嵌入式开发核心:ADC与PWM原理、实战与STM32应用全解析

1. 项目概述:从“信号”到“控制”的桥梁在嵌入式开发和硬件控制的世界里,ADC(模数转换器)和PWM(脉宽调制)是两个绕不开的核心技术。无论你是想让单片机“听懂”现实世界的温度、光照,还是想精准…

2026/10/13 14:00:00 阅读更多 →
跳出同义词低效改写:适配知网 / 维普 AIGC 检测的硬核降重逻辑,三大工具效率与质量深度测评

跳出同义词低效改写:适配知网 / 维普 AIGC 检测的硬核降重逻辑,三大工具效率与质量深度测评

一、前言:简单同义词替换早已无法通过新版 AIGC 检测知网 AMLC 新版 AIGC 检测、维普 AI 内容识别算法完成多轮迭代,彻底淘汰了 “近义词互换、语序微调” 的浅层降重模式。大量毕业生踩坑:重复率降到合格线,AIGC 疑似率高达 30% …

2026/10/7 22:20:00 阅读更多 →

最新新闻

SQLite+FTS5+BM25实现本地AI上下文检索增强(RAG)

SQLite+FTS5+BM25实现本地AI上下文检索增强(RAG)

1. 项目概述:从“context-mode”这个词开始,我们到底在谈什么?“context-mode”这个词乍一看像某个新出的编程模式、IDE插件开关,或是某款AI工具里的隐藏功能标签——但翻遍主流开发文档、VS Code官方设置、JetBrains全家桶配置项…

2026/10/14 9:07:49 阅读更多 →
Qt5 + python-docx 零依赖生成Word文档实战指南

Qt5 + python-docx 零依赖生成Word文档实战指南

简介:本资源是一套面向Qt与Python混合编程初学者及中级开发者的实战项目,聚焦于不依赖Microsoft Office环境下的Word文档读写能力构建。通过Qt5 GUI界面调用python-docx库,实现文档创建、段落编辑、表格插入、图片嵌入及样式控制等核心功能&a…

2026/10/14 9:07:49 阅读更多 →
限流降级实战指南:从算法选型到系统稳定性治理的完整路径

限流降级实战指南:从算法选型到系统稳定性治理的完整路径

1. 从一次线上事故说起:限流降级到底在防什么做后端的人,几乎都经历过那种半夜三点被报警电话叫醒的时刻。上个月我就刚处理过一次:某个核心接口的RT从正常的50ms一路飙到3000ms,紧接着依赖它的上游服务开始超时堆积,然…

2026/10/14 9:07:49 阅读更多 →
一套ERP从需求调研到正式上线的交付流程拆解

一套ERP从需求调研到正式上线的交付流程拆解

杭州管家婆软件(纵横软件杭州杭纵)——本地 28 年企业数字化服务伙伴产品矩阵:管家婆云辉煌系列|财贸系列|分销系列|辉煌小工单(与管家婆同厂出品)|生态圈产品&#xff5…

2026/10/14 9:07:49 阅读更多 →
跨境商业咨询服务的评估体系与技术创新应用

跨境商业咨询服务的评估体系与技术创新应用

1. 行业背景与榜单价值跨境商业咨询服务行业正在经历结构性变革。过去三年间,全球电商渗透率从14%跃升至22%,品牌出海服务市场规模年均复合增长率达到27.3%。这个背景下,专业咨询机构的价值链已经从单纯的战略规划,延伸到本地化运…

2026/10/14 9:07:49 阅读更多 →
SpringBoot体育馆预约系统设计与性能优化实践

SpringBoot体育馆预约系统设计与性能优化实践

1. 项目背景与核心价值体育馆场地预约系统是体育场馆数字化管理的核心工具。过去三年我参与过7个同类系统的开发实施,发现传统电话预约和纸质登记方式存在三大痛点:预约冲突频发(平均每周3-5起)、场地利用率不足(高峰时…

2026/10/14 9:06:48 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →