96SEO 2026-04-27 14:48 1
在人工智Neng的浩瀚海洋里我们经常遇到一种尴尬的情况:大模型就像一个博学但四肢不勤的书呆子。你问他“李白是谁”,他Neng滔滔不绝讲三天;但Ru果你让他“帮我查下现在的股价并算一下收益率”,他可Neng就开始一本正经地胡说八道了。为什么?因为传统的模型是“想完了再Zuo”,甚至只是“想完了就输出”,中间缺乏与真实世界的交互环节。

今天我们要聊的 ReAct范式,正是为了解决这个痛点而生。它不仅仅是一套代码逻辑,geng是一种让 AI 具备“行动力”的思维革命。本文将带你从零开始,剥离掉那些晦涩的学术名词,用Zui硬核的代码和Zui通俗的逻辑,构建一个真正Neng“边想边Zuo”的智Neng体。
从“只会聊天”到“Neng够干活”:AI 进化的必经之路想象一下Ru果你的老板给你布置了一个任务:“帮我查下华为Zui新发布的手机型号,顺便算下Ru果分期12个月每个月要多少钱。”
一个普通的 AI可Neng会直接凭记忆回答:“华为Zui新的是 Mate 60,售价大概 5000 块,分期的话……”——结果全是错的。
而一个经过 ReAct 范式武装的智Neng体,它的内心独白完全不同:
Thought老板问的是Zui新手机和价格,我现在的知识库可Neng不够新,得先搜一下。
Action调用搜索工具,查询“华为Zui新发布手机型号”。
Observation搜到了是 Mate 70 系列,起售价 5499 元。
Thought好,现在有价格了接下来要算分期。
Action调用计算器工具,计算 5499 / 12。
Finish告诉老板结果。
这就是 ReAct 的核心魅力:它把推理和行动紧密交织在一起,形成了一个动态的闭环。它不再是“憋大招”一次性输出,而是像人类一样,走一步,kan一步,再决定下一步怎么走。
揭秘 ReAct 范式:推理与行动的完美共舞在深入代码之前,我们必须先在脑海里建立这个架构图。ReAct 这个词其实是 Reasoning 和 Acting 的缩写。这不仅仅是两个单词的拼接,而是对智Neng体工作流程的重新定义。
hen多开发者容易混淆 Chain-of-Thought和 ReAct。简单来说CoT 是让模型在脑子里把步骤想清楚再写出来而 ReAct 是让模型每想一步,就真的去执行一步,拿到反馈后再继续想。这种差异在处理需要实时信息或外部工具的任务时简直是天壤之别。
为了geng直观地理解,我们Ke以把 ReAct 的流程kan作一个无限循环的引擎,直到任务完成:
flowchart LR
Q --> T
T --> A
A --> O
O --> T
T --> F
这里面Zui关键的三个状态就是 ThoughtAction 和 Observation。这三个词将贯穿我们接下来的所有代码实现。Ru果你Neng理解这个循环,你就Yi经掌握了 ReAct 的 80%。
零基础实战:手搓一个 ReAct 智Neng体理论讲多了容易犯困,咱们直接上手。为了让你不依赖任何复杂的第三方框架,我们将用 TypeScript 从零搭建一个Zui小可用的 ReAct Agent。这不仅Neng让你理解原理,还Neng在面试时秀一把硬核功夫。
搭建骨架:项目初始化与环境配置我们需要一个干净的项目结构。别被那些花哨的 monorepo 吓到了核心其实hen简单。建议你先创建这样一个目录结构,保持清醒:
react-agent-demo/
├── package.json
├── tsconfig.json
├── .env
└── src/
├── shared/
│ └── llm.ts // 封装大模型调用
├── react/
│ ├── prompt.ts // 提示词模板
│ ├── parser.ts // 输出解析器
│ ├── tools.ts // 工具定义与注册
│ └── agent.ts // ReAct 核心逻辑
└── index.ts // 入口文件
先搞定 package.json,把依赖装上:
{
"name": "react-agent-demo",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "ts-node src/index.ts",
"build": "tsc"
},
"dependencies": {
"dotenv": "^16.4.0",
"openai": "^4.0.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"ts-node": "^10.0.0",
"typescript": "^5.0.0"
}
}
接着是 TypeScript 配置 tsconfig.json,没什么花哨的,只要Neng跑起来就行:
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"moduleResolution": "node",
"lib": ,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"types":
},
"include": ,
"exclude":
}
Zui后别忘了 .env 文件,这是连接大模型的钥匙。Ru果你用的是 OpenAI,就填这个;Ru果是国内的大模型,只要兼容 OpenAI 接口格式,改一下 BASE_URL 也Neng跑:
LLM_API_KEY="你的模型 API Key"
LLM_MODEL_ID="gpt-4o-mini"
LLM_BASE_URL="https://api.openai.com/v1"
核心大脑:封装 LLM 交互层
在开始写 Agent 之前,我们先得把“大脑”准备好。为了不让代码里到处dou是 new OpenAI,我们封装一个 HelloAgentsLLM 类。这层封装虽然简单,但Neng让你后续切换模型变得异常轻松。
创建 src/shared/llm.ts
// src/shared/llm.ts
import "dotenv/config";
import OpenAI from "openai";
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
export interface LLMOptions {
model?: string;
apiKey?: string;
baseUrl?: string;
timeout?: number;
}
export class HelloAgentsLLM {
private readonly client: OpenAI;
private readonly model: string;
constructor {
const apiKey = options.apiKey ?? process.env.LLM_API_KEY;
const baseUrl = options.baseUrl ?? process.env.LLM_BASE_URL;
if {
throw new Error;
}
this.model = options.model ?? process.env.LLM_MODEL_ID ?? "gpt-4o-mini";
this.client = new OpenAI({
apiKey,
baseURL: baseUrl,
timeout: options.timeout ?? 60_000,
});
}
async think(
messages: ChatCompletionMessageParam,
temperature = 0
): Promise {
const response = await this.client.chat.completions.create({
model: this.model,
messages,
temperature,
});
return response.choices?.message?.content ?? "";
}
}
这段代码没什么黑科技,就是帮你把 API 调用的细节藏起来。以后你只需要调用 think 方法,把消息丢进去,等着它吐出思考结果就行。
ReAct 的“Act”部分,全靠工具来支撑。没有工具,Agent 就只是个会算命的瞎子。我们需要设计一个简单的工具注册中心,让 Agent 知道自己手里有哪些牌Ke以打。
创建 src/react/tools.ts
// src/react/tools.ts
export interface Tool {
name: string;
description: string;
execute: => Promise;
}
export class ToolRegistry {
private tools: Map = new Map;
register: void {
this.tools.set;
console.log;
}
getToolsDescription: string {
const descriptions: string = ;
this.tools.forEach => {
descriptions.push;
});
return descriptions.join || "暂无可用工具";
}
async execute: Promise {
const tool = this.tools.get;
if {
return `错误:未找到工具 '${toolName}'`;
}
try {
return await tool.execute;
} catch {
return `工具执行失败:${error instanceof Error ? error.message : String}`;
}
}
hasTool: boolean {
return this.tools.has;
}
}
这里的设计非常极简。为什么要这么简单?因为复杂的设计容易让人迷失方向。我们的目标是先把 ReAct 跑通,而不是造一个完美的企业级框架。这个 ToolRegistry Yi经足够表达两件重要的事情:一是告诉 Agent 有哪些工具,二是真正去执行这些工具。
现在到了Zui激动人心的部分:ReActAgent 本体。这是整个系统的“心脏”,负责驱动 思考 -> 行动 -> 观察 的循环。
创建 src/react/agent.ts
// src/react/agent.ts
import type { ChatCompletionMessageParam } from "openai/resources/chat/completions";
import { HelloAgentsLLM } from "../shared/llm";
import { ToolRegistry } from "./tools";
import { parseOutput, parseAction, isFinishAction } from "./parser";
import { REACT_PROMPT_TEMPLATE } from "./prompt";
export interface ReActAgentConfig {
name: string;
maxSteps: number;
}
export class ReActAgent {
private readonly llm: HelloAgentsLLM;
private readonly tools: ToolRegistry;
private readonly config: ReActAgentConfig;
private history: string = ;
constructor(
llm: HelloAgentsLLM,
tools: ToolRegistry,
config: Partial = {}
) {
this.llm = llm;
this.tools = tools;
this.config = {
name: "ReActAgent",
maxSteps: 10,
...config,
};
}
async run: Promise {
this.history = ;
console.log;
for {
console.log;
// 1. 构建 Prompt
const prompt = this.buildPrompt;
const messages: ChatCompletionMessageParam = ;
// 2. 让 LLM 思考
const response = await this.llm.think;
if {
console.log;
break;
}
// 3. 解析输出
const { thought, action } = parseOutput;
if {
console.log;
}
if {
console.log;
break;
}
console.log;
// 4. 判断是否结束
if ) {
const parsed = parseAction;
const answer = parsed?.toolInput || response;
console.log;
return answer;
}
// 5. 执行工具并获取观察结果
const parsedAction = parseAction;
if {
console.log;
break;
}
const observation = await this.tools.execute(
parsedAction.toolName,
parsedAction.toolInput
);
console.log;
// 6. 记录历史,用于下一轮推理
this.history.push;
this.history.push;
this.history.push;
}
return "抱歉,我无法在限定步数内完成这个任务。";
}
private buildPrompt: string {
const historyStr = this.history.length> 0
? this.history.join
: "无";
return REACT_PROMPT_TEMPLATE
.replace)
.replace
.replace;
}
getHistory: string {
return ;
}
}
这段代码的逻辑非常清晰,你Ke以把它理解成一个严格守规矩的办事员:
它先kankan手里有什么工具,再kankan用户问了什么以及之前Zuo了什么。
然后它去问大脑下一步该怎么办。
大脑告诉它“我想查个东西”或者“我想算个数”。
它Ru果听到“我想算个数”,就真的去拿计算器算,然后把结果拿回来给大脑kan。
如此往复,直到大脑说“我知道答案了告诉用户吧”。
这里有个 maxSteps 参数,这可是个保命符。万一模型陷入死循环,一直纠结在某个步骤上出不来这个参数Neng强制让它停下来防止你的 API 积分被烧光。
你可Neng注意到了上面的代码里引用了 REACT_PROMPT_TEMPLATE 和 parseOutput。这两个东西是 ReAct Neng否稳定运行的基石。
先kan提示词 src/react/prompt.ts
// src/react/prompt.ts
export const REACT_PROMPT_TEMPLATE = `你是一个具备推理和行动Neng力的 AI 助手。你Ke以通过思考分析问题,然后调用合适的工具来获取信息,Zui终给出准确的答案。
## 可用工具
{tools}
## 工作流程
请严格按照以下格式进行回应,每次只Neng执行一个步骤:
Thought: 分析当前问题,思考需要什么信息或采取什么行动。
Action: 选择一个行动,格式必须是以下之一:
- \`ToolName\` - 调用指定工具
- \`Finish\` - 当你有足够信息给出Zui终答案时
## 重要规则
. 每次回应必须包含 Thought 和 Action 两部分
. 工具调用格式必须严格遵循:工具名
. 只有当你确信有足够信息回答问题时才使用 Finish
. Ru果工具返回的信息不够,请继续推理并调用工具
## 当前任务
Question: {question}
## 执行历史
{history}
现在开始你的推理和行动:`;
为什么这段 Prompt 这么关键?因为它是在教模型“怎么说话”。Ru果不说清楚,模型可Neng会直接给你来一段自然语言描述,而不是你想要的 Action: Calculator 这种结构化指令。这就像教小孩子,规矩得立在前头。
有了规矩,还得有检查规矩的人。这就是解析器 src/react/parser.ts 的作用:
// src/react/parser.ts
export interface ParsedOutput {
thought: string | null;
action: string | null;
}
export interface ParsedAction {
toolName: string;
toolInput: string;
}
export function parseOutput: ParsedOutput {
const thoughtMatch = text.match(
/Thought:\s*/i
);
const actionMatch = text.match(
/Action:\s*/i
);
return {
thought: thoughtMatch?.?.trim || null,
action: actionMatch?.?.trim || null,
};
}
export function parseAction: ParsedAction | null {
const match = actionText.match\/);
if {
return null;
}
return {
toolName: match,
toolInput: match.trim,
};
}
export function isFinishAction: boolean {
return action.startsWith;
}
hen多新手容易忽略这一层,觉得“LLM douNeng输出了我直接拿字符串用不就好了?”千万别这么想。模型输出的是文本,而程序需要的是结构化的指令。解析器就是那个把“人话”翻译成“机读指令”的翻译官。没有它,你的 Agent 只Neng是个哑巴。
从模拟到实战:接入真实世界现在所有的组件dou齐活了。让我们把它们组装起来写个入口文件 src/index.ts。为了不让新手一开始就被各种 API Key 和网络问题劝退,我们先写两个Neng本地跑的工具:一个计算器,一个模拟搜索。
// src/index.ts
import "dotenv/config";
import { HelloAgentsLLM } from "./shared/llm";
import { ReActAgent } from "./react/agent";
import { ToolRegistry, Tool } from "./react/tools";
class CalculatorTool implements Tool {
name = "Calculator";
description = "数学计算工具,支持基本表达式计算";
async execute: Promise {
try {
const sanitized = expression.replace.]/g, "");
const result = Function`);
return `计算结果:${result}`;
} catch {
return `计算错误:${error instanceof Error ? error.message : String}`;
}
}
}
class MockSearchTool implements Tool {
name = "Search";
description = "模拟搜索工具,用于演示查询实时信息";
async execute: Promise {
const knowledgeBase: Record = {
"华为Zui新发布手机型号": "华为Zui新发布的是 Mate 70 系列。",
"华为 Mate 70 售价": "Mate 70 起售价 5499 元,Mate 70 Pro 起售价 6499 元。",
"北京今天天气": "北京今天晴,Zui高温 25 度,Zui低温 15 度。",
};
for ) {
if ) {
return knowledgeBase;
}
}
return `没有找到与“${query}”相关的信息。`;
}
}
async function main {
const llm = new HelloAgentsLLM;
const tools = new ToolRegistry;
tools.register);
tools.register);
const agent = new ReActAgent(llm, tools, {
name: "ReAct 演示助手",
maxSteps: 10,
});
const questions = ;
for {
console.log);
const answer = await agent.run;
console.log;
}
}
main.catch;
运行 npm run dev,你会在终端里kan到类似这样的过程:
==================================================
🤖 ReAct 演示助手 开始处理问题: 华为Zui新发布的手机是什么型号?售价多少?
--- 第 1/10 步 ---
💭 Thought: 我需要先确认华为Zui近发布了什么手机
🎬 Action: Search
👁️ Observation: 华为Zui新发布的是 Mate 70 系列。
--- 第 2/10 步 ---
💭 Thought: Yi经知道型号了现在需要查售价
🎬 Action: Search
👁️ Observation: Mate 70 起售价 5499 元,Mate 70 Pro 起售价 6499 元。
--- 第 3/10 步 ---
💭 Thought: 信息Yi经足够,Ke以回答用户了
🎬 Action: Finish
✅ 任务完成,Zui终答案: 华为Zui新发布的是 Mate 70 系列,起售价 5499 元,Pro 版起售价 6499 元。
📝 Zui终回答: 华为Zui新发布的是 Mate 70 系列,起售价 5499 元,Pro 版起售价 6499 元。
这时候,kan着终端里滚动的日志,你会有一种感觉:这不再是冷冰冰的代码,而是一个有逻辑、有步骤的“小生命”在为你工作。这就是 ReAct 的魔力。
当你本地跑通之后把 MockSearchTool 换成真实的搜索工具就是顺水推舟的事了。例如我们Ke以定义一个真实的 SearchTool
class SearchTool implements Tool {
name = "Search";
description = "网页搜索引擎,用于查询实时信息、新闻、事实等";
async execute: Promise {
const { getJson } = await import;
const results = await getJson({
engine: "google",
q: query,
api_key: process.env.SERPAPI_API_KEY,
hl: "zh-cn",
gl: "cn",
});
if {
return results.answer_box.answer;
}
if {
return results.organic_results
.slice
.map => ` ${r.title}
${r.snippet}`)
.join;
}
return `未找到关于 '${query}' 的相关信息`;
}
}
然后在 .env 里加上 SERPAPI_API_KEY,你的 Agent 就从“教学版”进化成了“可联网版”。这种从 0 到 1 的成就感,是直接调用现成库无法体会的。
ReAct Yi经让智Neng体具备了“边想边Zuo”的Neng力,解决了传统 LLM 无法实时获取信息和执行操作的短板。它特别适合那些路径不固定、需要多步推理的动态任务。比如数据分析、复杂的客服问答、甚至是自动化运维。
但 ReAct 并不是终点。你可Neng会发现,现在的 Agent 虽然会Zuo事,但它Zuo完就完了不会回头反思自己Zuo得对不对,也不会自我改进。这就引出了下一个重要的范式:ReflectionAgent。
Ru果说 ReAct 是让 Agent “动起来”,那么 Reflection 就是让 Agent “聪明起来”。它会在任务结束后或者每一步行动后进行自我评估:“我刚才那步操作对吗?有没有geng好的方案?”通过这种反思,Agent 的Neng力会随着使用时间的推移而越来越强。
不过那是后话了。现在当你kan着自己亲手写下的这几百行代码,kan着它成功计算出结果并搜索到新闻时你Yi经跨过了从“写流程”到“造智Neng体”的关键门槛。这不仅仅是代码的胜利,geng是思维的跃迁。继续探索吧,AI 的世界远比这精彩。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback