乐于分享
好东西不私藏

从零手写一个 AI Agent:核心原理与 ReAct 实现

从零手写一个 AI Agent:核心原理与 ReAct 实现

本文是 AI Agent 系统性学习系列的第 1 篇。我们从最基础的问题出发:Agent 到底是什么?它和普通的 LLM 对话有什么区别?然后亲手用 Python 实现一个最小的 ReAct Agent,再用 smolagents 框架拆解 Agent 内部的每一个环节。

前置要求:Python 基础、知道 LLM(大语言模型)是什么。

配套代码:phase-1-fundamentals/


1. AI Agent 到底是什么

1.1 LLM 和 Agent 的核心区别

你用过 ChatGPT 或者 DeepSeek 对话,它们能写文章、翻译、写代码。但你让它"帮我查一下今天北京的天气,然后订一家评分最高的餐厅"——它做不到。

为什么?因为 LLM 本质上只做一件事:输入文本,输出文本。它没有手,不能上网查天气,不能调用订餐 API,甚至不知道"现在"是几点。

Agent 解决的就是这个问题。一句话概括:

LLM 是一个只能说话的大脑,Agent 是一个能思考、能动手、能从结果中学习的完整系统。

LLM
Agent
能力
生成文本
生成文本 + 调用工具 + 观察结果
状态
无状态(每次对话独立)
有记忆(记住之前做了什么)
决策
一次性回答
多步推理,自主决定下一步
边界
训练数据截止日期内的知识
可以访问实时数据和外部系统

1.2 Agent 的四大支柱

一个完整的 Agent 系统由四个核心组件构成:

                    ┌─────────────┐                    │   用户任务    │                    └──────┬──────┘                           ▼              ┌────────────────────────┐              │         LLM            │              │    (大脑 / 推理引擎)    │              └────────────────────────┘               ▲     ▲      ▲      ▲               │     │      │      │         ┌─────┘  ┌──┘   ┌──┘   ┌──┘         ▼        ▼      ▼      ▼    ┌────────┐┌──────┐┌─────┐┌──────────┐    │  规划   ││ 记忆  ││ 工具 ││ 行动循环  │    │Planning││Memory││Tools││Action Loop│    └────────┘└──────┘└─────┘└──────────┘
  • 规划(Planning):把复杂任务拆解成可执行的步骤
  • 记忆(Memory):记住之前的对话和操作结果
  • 工具(Tools):扩展 LLM 的能力边界——计算器、搜索引擎、API 调用
  • 行动循环(Action Loop):把上面三者串起来的执行引擎,也就是 ReAct 循环

1.3 为什么现在 Agent 变得实用了

Agent 的概念并不新,但直到最近才真正可用,原因有三:

  1. LLM 能力跃升:GPT-4、Claude、DeepSeek 等模型的推理能力足够强,能可靠地遵循复杂指令和工具调用格式
  2. 工具调用标准化:OpenAI 的 Function Calling、Anthropic 的 Tool Use、以及 MCP 让工具集成有了统一接口
  3. 框架生态成熟:LangChain、LangGraph、smolagents、CrewAI 等框架大幅降低了构建 Agent 的门槛

理论讲够了,我们来写代码。


2. 手写一个最小 ReAct Agent

2.1 ReAct 是什么

ReAct 来自 2022 年 Yao et al. 的论文 "ReAct: Synergizing Reasoning and Acting in Language Models"。核心思想极其简单:

让 LLM 交替进行"思考"和"行动",每次行动后观察结果,再决定下一步。

┌──────────────────────────────────────────────────┐│                   用户任务                         │└──────────────────────┬───────────────────────────┘                       ▼                ┌─────────────┐           ┌───▶│   Thought   │  LLM 思考:我需要做什么?           │    └──────┬──────┘           │           ▼           │    ┌─────────────┐           │    │   Action    │  LLM 决定:调用哪个工具?           │    └──────┬──────┘           │           ▼           │    ┌─────────────┐           │    │ Observation │  执行工具,拿到结果           │    └──────┬──────┘           │           ▼           │      还需要更多     ──── 是 ────┐           │      步骤吗?                    │           │           │                     │           │          否                     │           │           ▼                     │           │    ┌─────────────┐              │           │    │ Final Answer│              │           │    └─────────────┘              │           └─────────────────────────────────┘

为什么这比让 LLM 一次性回答更好?因为每一步都有真实的观察结果来"校准"推理。LLM 不是在凭空想象答案,而是基于实际数据一步步推导。

2.2 纯 Python 实现 ReAct 循环

下面这段代码不依赖任何 Agent 框架,只用 Python + LLM API,实现一个完整的 ReAct Agent。注意 calculator 中的 eval() 仅用于学习演示,生产环境必须使用沙箱:

  1. """
  2. minimal_react.py — 纯手写 ReAct Agent(不依赖任何框架)
  3. """
  4. import json, re
  5. from litellm import completion
  6. # ── 第一步:定义工具 ──────────────────────────────────
  7. def calculator(expr: str)-> str:
  8. """安全受限的计算器(生产环境应使用 AST 解析或沙箱)"""
  9. import ast, operator
  10.     allowed ={ast.Add: operator.add, ast.Sub: operator.sub,
  11.                ast.Mult: operator.mul, ast.Div: operator.truediv, ast.Pow: operator.pow}
  12.     tree = ast.parse(expr, mode="eval")
  13. def _eval(node):
  14. if isinstance(node, ast.Expression):return _eval(node.body)
  15. if isinstance(node, ast.Constant):return node.value
  16. if isinstance(node, ast.BinOp):return allowed[type(node.op)](_eval(node.left), _eval(node.right))
  17. raiseValueError(f"不支持的操作: {ast.dump(node)}")
  18. return str(_eval(tree))
  19. def weather(city: str)-> str:
  20. return{"北京":"晴 22°C","上海":"多云 26°C"}.get(city,"未知城市")
  21. tools ={"calculator": calculator,"weather": weather}
  22. tool_desc ="\n".join(f"- {name}: 调用方式 {name}(参数)"for name in tools)
  23. # ── 第二步:设计 System Prompt ─────────────────────────
  24. SYSTEM_PROMPT = f"""你是一个 ReAct Agent。收到任务后,按以下格式交替输出:
  25. Thought: <你的思考过程>
  26. Action: <工具名>(<参数>)
  27. 等待系统返回 Observation 后,继续思考。
  28. 当你得出最终答案时,输出:
  29. Thought: 我已经得到了答案。
  30. Final Answer: <最终答案>
  31. 可用工具:
  32. {tool_desc}
  33. """
  34. # ── 第三步:ReAct 循环 ─────────────────────────────────
  35. def react_agent(task: str, max_steps: int =5)-> str:
  36.     messages =[
  37. {"role":"system","content": SYSTEM_PROMPT},
  38. {"role":"user","content": task},
  39. ]
  40. for step in range(max_steps):
  41.         response = completion(model="deepseek/deepseek-chat", messages=messages)
  42.         output = response.choices[0].message.content
  43. print(f"\n── Step {step} ──\n{output}")
  44. if"Final Answer:"in output:
  45. return output.split("Final Answer:")[-1].strip()
  46.         action_match = re.search(r"Action:\s*(\w+)\((.+?)\)", output)
  47. if action_match:
  48.             tool_name, arg = action_match.group(1), action_match.group(2).strip("\"'")
  49.             observation = tools[tool_name](arg)if tool_name in tools else"未知工具"
  50. print(f"Observation: {observation}")
  51.             messages.append({"role":"assistant","content": output})
  52.             messages.append({"role":"user","content": f"Observation: {observation}"})
  53. else:
  54.             messages.append({"role":"assistant","content": output})
  55. return"达到最大步数,未得出答案"
  56. # ── 运行 ──────────────────────────────────────────────
  57. answer = react_agent("北京今天天气怎么样?如果气温超过 20 度,计算 20 * 3.14 的值。")
  58. print(f"\n最终答案: {answer}")

这段代码只有 ~50 行,但它包含了一个 Agent 的全部核心要素:

要素
对应代码
工具注册
tools
 字典
System Prompt
告诉 LLM 用 Thought/Action/Observation 格式
ReAct 循环
forstepinrange(max_steps)
工具调用
正则解析 Action,执行对应函数
记忆
messages
 列表累积对话历史
终止条件
检测 FinalAnswer: 或达到 max_steps

2.3 手写的局限性

这个最小实现能跑,但离生产可用差得远:

  • 解析脆弱:靠正则匹配 Action:tool(arg),LLM 稍微变一下格式就挂了
  • 没有沙箱:即使用了 AST 解析,复杂场景下仍有安全隐患
  • 错误处理缺失:工具调用失败、LLM 输出格式错误都没处理
  • 不支持复杂工具:多参数、嵌套调用、异步工具都搞不定

这就是为什么我们需要框架。接下来用 smolagents 看看同样的事情怎么做。


3. 用 smolagents 10 行代码跑起来

上面我们手写了 50 行代码实现 ReAct。smolagents 把这些全部封装好了——模型适配、Prompt 模板、循环控制、工具解析、错误恢复——你只需要关心业务逻辑。

  1. from smolagents importCodeAgent,LiteLLMModel
  2. model =LiteLLMModel(model_id="deepseek/deepseek-chat", temperature=0.7)
  3. agent =CodeAgent(tools=[], model=model, add_base_tools=True)
  4. result = agent.run("斐波那契数列的第 20 项是多少?请同时告诉我计算过程。")
  5. print(result)

三个核心要素,和手写版一一对应:

手写版
smolagents
completion()
 调用 LLM
LiteLLMModel
 封装模型调用
tools
 字典 + 正则解析
CodeAgent
 自动管理工具
forstepinrange(max_steps)
Agent 内部的 ReAct 循环

关键区别:smolagents 的 CodeAgent 不是让 LLM 输出 Action:tool(arg) 这种文本格式,而是让 LLM 直接写 Python 代码。LLM 可以用循环、条件判断、变量赋值——表达力远超文本格式。

add_base_tools=True 会添加内置工具(如 PythonInterpreterTool),让 Agent 即使没有自定义工具也能通过写代码来解决问题。


4. 深入 ReAct 内部机制

框架帮我们封装了细节,但理解内部机制才能在出问题时知道怎么调试。这一节我们拆开 smolagents 的 Agent,看看每一层发生了什么。

4.1 System Prompt — LLM 看到了什么

Agent 的行为由 System Prompt 决定。smolagents 使用 Jinja2 模板,在初始化时把工具描述、managed_agents 信息注入进去:

  1. agent =CodeAgent(tools=[], model=model, add_base_tools=True)
  2. # 查看 System Prompt 模板
  3. system_prompt = agent.prompt_templates["system_prompt"]
  4. print(f"System prompt 长度: {len(system_prompt)} 字符")
  5. print(system_prompt[:500])

这个 System Prompt 告诉 LLM:

  1. 你是一个 Agent,要按 Thought → Code → Observation 的格式工作
  2. 你可以使用这些工具(自动列出每个工具的名称、描述、参数类型)
  3. 当你得出最终答案时,调用 final_answer() 函数

你还可以通过 instructions 参数追加自定义指令,不需要修改模板:

  1. custom_agent =CodeAgent(
  2.     tools=[], model=model, add_base_tools=True,
  3.     instructions="你是一个数学教授。回答问题时,请用通俗易懂的方式解释推理过程。",
  4. )
  5. result = custom_agent.run("为什么 0.1 + 0.2 不等于 0.3?")

4.2 Agent 执行日志 — 逐步拆解 ReAct 循环

agent.logs 记录了每一步的详细信息。我们用一个斐波那契工具来观察:

  1. from smolagents import tool
  2. @tool
  3. def fibonacci(n: int)-> str:
  4. """
  5.     计算斐波那契数列的第 n 项。
  6.     Args:
  7.         n: 要计算的项数(从第 1 项开始)
  8.     """
  9. if n <=0:
  10. return"n 必须是正整数"
  11.     a, b =0,1
  12. for _ in range(-1):
  13.         a, b = b, a + b
  14. return f"斐波那契数列第 {n} 项是 {b}"
  15. log_agent =CodeAgent(tools=[fibonacci], model=model, max_steps=5)
  16. result = log_agent.run("斐波那契数列第 10 项和第 20 项分别是多少?它们的比值接近什么数?")

运行后查看日志:

  1. for i, step in enumerate(log_agent.logs):
  2. if hasattr(step,"model_output"):
  3. print(f"\n--- Step {i} ---")
  4. print(f"LLM 输出: {step.model_output[:200]}...")
  5. if hasattr(step,"observations"):
  6. print(f"观察结果: {step.observations[:200]}...")

你会看到类似这样的执行过程:

  1. ──Step0──
  2. LLM 输出:Thought:我需要分别计算第10项和第20项,然后算比值...
  3. Code:
  4.   result_10 = fibonacci(10)
  5.   result_20 = fibonacci(20)
  6. print(result_10, result_20)
  7. 观察结果:斐波那契数列第10项是55斐波那契数列第20项是6765
  8. ──Step1──
  9. LLM 输出:Thought:比值是6765/55123,这接近黄金比例的幂...
  10. Code:
  11.   ratio =6765/55
  12.   final_answer(f"第10项=55, 第20项=6765, 比值≈{ratio:.2f}")

注意 CodeAgent 在一步内就调用了两次 fibonacci(用 Python 变量存储结果),这是它比 ToolCallingAgent 高效的原因。

4.3 Agent 的记忆 — writememoryto_messages()

Agent 的"记忆"就是对话历史。每一步的 LLM 输出和工具观察结果都会被追加到消息列表中,作为下一步的上下文:

  1. messages = log_agent.write_memory_to_messages()
  2. print(f"总消息数: {len(messages)}")
  3. for msg in messages:
  4. print(f"  {str(msg.content)[:100]}...")

这个方法做了两件事:

  1. 把 System Prompt 转成消息格式
  2. 把每个执行步骤( memory.steps)转成消息追加进去

这就是 Agent 能"记住"之前做了什么的原因——所有历史都在 messages 里,每次调用 LLM 时一起发送。


5. 工具系统入门

5.1 为什么需要工具

LLM 有三个硬伤:不知道实时信息、不能精确计算、不能操作外部系统。工具就是给 LLM 装上的"手":

LLM 做不到的
工具解决方案
不知道现在几点
时间查询工具
算不准浮点数
计算器工具
不能查数据库
数据库查询工具
不能发邮件
邮件 API 工具

工具的本质是一个函数,它有名称、描述、输入参数类型和返回值。LLM 通过阅读工具描述来决定什么时候用、怎么用。

5.2 @tool 装饰器 — 最简单的定义方式

  1. from smolagents import tool
  2. @tool
  3. def get_current_time(timezone: str ="Asia/Shanghai")-> str:
  4. """
  5.     获取指定时区的当前时间。
  6.     Args:
  7.         timezone: 时区名称,如 "Asia/Shanghai", "US/Eastern", "Europe/London"
  8.     """
  9. from datetime import datetime
  10. import zoneinfo
  11.     zone = zoneinfo.ZoneInfo(timezone)
  12.     now = datetime.now(zone)
  13. return now.strftime("%Y-%m-%d %H:%M:%S %Z")

三个关键点:

  1. 函数名就是工具名——LLM 在代码中直接调用 get_current_time()
  2. docstring 是 LLM 理解工具的唯一依据——写不清楚,Agent 就不会正确使用
  3. 类型注解告诉 LLM 参数类型—— timezone:str 让 LLM 知道要传字符串

5.3 Tool 子类 — 复杂工具的定义方式

当工具需要初始化状态(比如数据库连接)或有复杂的输入结构时,用子类更合适:

  1. from smolagents importTool
  2. classUnitConverter(Tool):
  3.     name ="unit_converter"
  4.     description ="单位换算工具,支持长度、重量、温度的常见单位转换"
  5.     inputs ={
  6. "value":{"type":"number","description":"要转换的数值"},
  7. "from_unit":{"type":"string","description":"原始单位,如 km, mile, kg, lb"},
  8. "to_unit":{"type":"string","description":"目标单位"},
  9. }
  10.     output_type ="string"
  11.     conversions ={
  12. ("km","mile"):lambda v: v *0.621371,
  13. ("mile","km"):lambda v: v *1.60934,
  14. ("celsius","fahrenheit"):lambda v: v *9/5+32,
  15. ("fahrenheit","celsius"):lambda v:(-32)*5/9,
  16. }
  17. def forward(self, value: float, from_unit: str, to_unit: str)-> str:
  18.         key =(from_unit.lower(), to_unit.lower())
  19. if key in self.conversions:
  20.             result = self.conversions[key](value)
  21. return f"{value} {from_unit} = {result:.4f} {to_unit}"
  22. return f"不支持从 {from_unit} 到 {to_unit} 的转换"

两种方式的选择很简单:简单无状态用 @tool,复杂有状态用 Tool 子类

5.4 Agent 自主选择工具

把多个工具交给 Agent,它会根据任务自动选择合适的工具——你不需要告诉它用哪个:

  1. @tool
  2. def weather_lookup(city: str)-> str:
  3. """
  4.     查询城市的天气信息(模拟数据)。
  5.     Args:
  6.         city: 城市名称,如 "北京", "上海", "东京"
  7.     """
  8.     mock_weather ={
  9. "北京":{"temp":22,"condition":"晴","humidity":35},
  10. "上海":{"temp":26,"condition":"多云","humidity":65},
  11. "东京":{"temp":20,"condition":"小雨","humidity":78},
  12. }
  13. if city in mock_weather:
  14.         w = mock_weather[city]
  15. return f"{city}: {w['condition']}, 温度 {w['temp']}°C, 湿度 {w['humidity']}%"
  16. return f"暂无 {city} 的天气数据"
  17. agent =CodeAgent(
  18.     tools=[get_current_time, weather_lookup,UnitConverter()],
  19.     model=model,
  20. )
  21. # Agent 自动选择 weather_lookup + 推理
  22. agent.run("北京和东京今天哪个城市更适合户外活动?请给出理由。")
  23. # Agent 自动选择 UnitConverter
  24. agent.run("100 公里换算成英里是多少?")

这就是 Agent 的"自主决策"能力——它读了每个工具的描述,理解了任务需求,然后自己决定调用哪些工具、以什么顺序调用。

工具生态的更多内容——从 Hub 加载工具、集成 LangChain 工具、连接 MCP Server、工具设计最佳实践——我们在下一篇《AI Agent 工具调用系统设计》中详细展开。


6. CodeAgent vs ToolCallingAgent

smolagents 提供两种 Agent,代表两种截然不同的执行范式:

  1. ┌─────────────────┬──────────────────────────────────────┐
  2. CodeAgent LLM 生成Python代码,直接执行
  3. 支持循环、条件、变量更灵活
  4. 研究表明比 JSON 方式少30%步骤
  5. ├─────────────────┼──────────────────────────────────────┤
  6. ToolCallingAgent LLM 生成 JSON 格式的工具调用
  7. 类似OpenAIFunctionCalling
  8. 更安全可控,但表达力有限
  9. └─────────────────┴──────────────────────────────────────┘

用同一个任务对比:

  1. from smolagents importCodeAgent,ToolCallingAgent
  2. tools =[lookup_population, lookup_gdp]
  3. task ="比较中国、美国和日本的人口和 GDP,哪个国家的人均 GDP 最高?"
  4. # CodeAgent:一步搞定
  5. code_agent =CodeAgent(tools=tools, model=model)
  6. result = code_agent.run(task)
  7. # LLM 写了一个 for 循环,一次查完 3 个国家的数据,直接算出结果
  8. # ToolCallingAgent:需要多步
  9. tc_agent =ToolCallingAgent(tools=tools, model=model)
  10. result = tc_agent.run(task)
  11. # LLM 每次只能调一个工具:查中国人口 → 查中国GDP → 查美国人口 → ...

CodeAgent 的执行过程(1-2 步):

  1. # LLM 生成的代码(一步内完成)
  2. countries =["中国","美国","日本"]
  3. for c in countries:
  4.     pop = lookup_population(c)
  5.     gdp = lookup_gdp(c)
  6. print(f"{c}: 人口={pop}, GDP={gdp}")
  7. # 然后直接计算人均 GDP,给出答案

ToolCallingAgent 的执行过程(6+ 步):

  1. Step0:调用 lookup_population("中国")"14.1 亿"
  2. Step1:调用 lookup_gdp("中国")"17.8 万亿美元"
  3. Step2:调用 lookup_population("美国")"3.3 亿"
  4. Step3:调用 lookup_gdp("美国")"25.5 万亿美元"
  5. Step4:调用 lookup_population("日本")"1.25 亿"
  6. Step5:调用 lookup_gdp("日本")"4.2 万亿美元"
  7. Step6:计算并给出答案

选择建议:

  • 学习和原型阶段 → CodeAgent(更灵活高效)
  • 生产环境 → ToolCallingAgent(更安全可控),或 CodeAgent + 沙箱

7. 多 Agent 协作初探

当任务足够复杂时,一个 Agent 搞不定。smolagents 支持 Manager-Worker 模式:

  1. ┌──────────────┐
  2. Manager接收用户任务,决定分发给谁
  3. Agent
  4. └──────┬───────┘
  5. 分发任务
  6. ┌──────┴───────┐
  7. ┌────────┐┌────────────┐
  8. SearchAnalyst
  9. AgentAgent
  10. 搜索信息│分析推理
  11. └────────┘└────────────┘
  1. # Worker 1:搜索 Agent
  2. search_agent =CodeAgent(
  3.     tools=[search_tech_news, search_company_info],
  4.     model=model,
  5.     name="search_agent",
  6.     description="搜索 Agent:负责搜索科技新闻和公司信息。当需要查找事实性信息时,交给它。",
  7. )
  8. # Worker 2:分析 Agent
  9. analyst_agent =CodeAgent(
  10.     tools=[], model=model,
  11.     name="analyst_agent",
  12.     description="分析 Agent:负责数据分析、趋势判断和撰写报告。当需要对信息进行深度分析时,交给它。",
  13.     add_base_tools=True,
  14. )
  15. # Manager:管理两个 Worker
  16. manager =CodeAgent(
  17.     tools=[],
  18.     model=model,
  19.     managed_agents=[search_agent, analyst_agent],
  20. )
  21. result = manager.run(
  22. "请帮我分析当前 AI 行业的竞争格局。"
  23. "先搜索 AI 领域的最新新闻和主要公司(OpenAI、Anthropic、Google)的信息,"
  24. "然后基于这些信息写一份简短的行业分析报告。"
  25. )

Manager 把 Worker 当作"工具"来使用——它读 Worker 的 description,决定把子任务分给谁。Worker 执行完后把结果返回给 Manager,Manager 汇总后给出最终答案。

多 Agent 的核心价值:专业分工。搜索 Agent 专注信息检索,分析 Agent 专注推理总结,各司其职。


8. Agent 调控三板斧

8.1 max_steps — 防止无限循环

Agent 可能陷入死循环(反复尝试同一个失败的操作)。 max_steps 是安全阀:

  1. limited_agent =CodeAgent(tools=[fibonacci], model=model, max_steps=2)
  2. # 给一个需要很多步的任务,但只允许 2 步
  3. result = limited_agent.run("计算斐波那契第 5、10、15、20、25、30 项,画出增长趋势。")
  4. # Agent 会在 2 步内尽力完成,超出则停止

默认值通常是 6-10 步。简单任务设小一点(2-3),复杂任务设大一点(8-10)。

8.2 instructions — 定制 Agent 人设

不需要修改 System Prompt 模板,直接追加指令:

  1. agent =CodeAgent(
  2.     tools=[], model=model, add_base_tools=True,
  3.     instructions="你是一个数学教授。回答时用通俗易懂的方式解释,就像给学生上课。",
  4. )

instructions 会被追加到 System Prompt 末尾,是最简单的定制方式。

8.3 planning_interval — 定期反思

复杂任务中,Agent 可能走偏。 planning_interval 让它每 N 步暂停,更新已知事实、反思进展、调整计划:

  1. planning_agent =CodeAgent(
  2.     tools=[search_database, get_user_budget],
  3.     model=model,
  4.     planning_interval=2,# 每 2 步反思一次
  5.     max_steps=8,
  6. )

这三个参数覆盖了 80% 的 Agent 调优需求。


9. 生产环境注意事项

CodeAgent 让 LLM 生成并执行代码,这意味着安全风险。在部署到生产环境前,需要了解四类威胁:

威胁类型
说明
风险等级
LLM 自身错误
LLM 无意中生成有害命令
供应链攻击
使用被篡改的 LLM 模型
Prompt 注入
Agent 浏览网页时遇到恶意指令
公开暴露
恶意用户构造对抗性输入

smolagents 提供多种沙箱方案:

方案
安全级别
适用场景
Local(默认)
AST 沙箱
开发/学习
E2B
云端隔离
云端生产环境
Docker
容器隔离
本地生产环境
Blaxel
云端 VM
低延迟生产

开发阶段用默认的 Local executor 足够。生产阶段必须上 E2B 或 Docker 沙箱,加上输入验证和输出过滤。


10. 总结与下一步

这篇文章我们走过了 Agent 的完整认知路径:

  1. Agent = LLM + 工具 + 循环。LLM 是大脑,工具是手,ReAct 循环是行动引擎。
  2. ReAct = Thought + Action + Observation。交替思考和行动,每步都有真实观察来校准推理。
  3. 我们从 50 行纯 Python 手写了一个 ReAct Agent,理解了底层原理;再用 smolagents 框架看到了工业级实现。
  4. CodeAgent 写代码更灵活,ToolCallingAgent 调 JSON 更安全。多 Agent 实现专业分工。

下一篇:《AI Agent 工具调用系统设计:从原理到代码》——深入工具生态,包括 Hub 工具加载、LangChain 集成、MCP Server 连接、工具设计最佳实践。


本文配套代码在 phase-1-fundamentals/ 目录下,每个脚本都可以独立运行。建议边读边跑代码,修改参数观察变化。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-04-25 09:10:23 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/551467.html
  2. 运行时间 : 0.098105s [ 吞吐率:10.19req/s ] 内存消耗:4,824.30kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=70b2f32166f4fc046632a81616e58799
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000691s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000845s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000373s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000293s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000484s ]
  6. SELECT * FROM `set` [ RunTime:0.000212s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000716s ]
  8. SELECT * FROM `article` WHERE `id` = 551467 LIMIT 1 [ RunTime:0.000608s ]
  9. UPDATE `article` SET `lasttime` = 1777079423 WHERE `id` = 551467 [ RunTime:0.002626s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000227s ]
  11. SELECT * FROM `article` WHERE `id` < 551467 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000445s ]
  12. SELECT * FROM `article` WHERE `id` > 551467 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.003636s ]
  13. SELECT * FROM `article` WHERE `id` < 551467 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000688s ]
  14. SELECT * FROM `article` WHERE `id` < 551467 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002999s ]
  15. SELECT * FROM `article` WHERE `id` < 551467 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004828s ]
0.099810s