AgentLoop分享(上): 让 AI 真正“自主干活“-Day15

配套代码:simpleAgent 项目 agentloop/01_while_loop.py(手写 AgentLoop)

一、一个关键转变:从"问一句"到"干一件事"

用 ChatGPT 时我们是"一问一答":问一句,它答一句。

但真实工作不是这样------"把收容所的小猫领养出去"这个任务,需要一连串动作:

  • 第 1 步:先看看收容所有哪些宠物? (工具:列出目录)
  • 第 2 步:找到猫咪小花,把它移走 (工具:移动文件)
  • 第 3 步:再确认一下现在剩下什么 (工具:列出目录)
  • 第 4 步:向用户汇报结果 (输出总结)

AI 要完成这类任务,不能只答一句话,它需要反复地"思考 → 动手 → 看结果 → 再思考"

这个循环,就是 AgentLoop(Agent 主循环)

一句话:AgentLoop = 反复执行"模型提建议 + 程序执行(ToolCall) + 结果回传",直到模型认为任务完成。

二、为什么"工具执行权"必须在我们手里?

这是 Agent 设计最重要的安全原则:

  • 模型只会说:"我想调用 move_file 工具,参数是 inbox/猫咪小花.txt → archive/"

  • 真正移动文件的是我们的代码

  • 我们可以在执行前做任何检查(路径是否合法、权限是否足够、要不要人工确认)

    模型输出文字:"我要调 move_file(猫咪小花.txt, archive)"


    代码:校验 → 执行 → 返回结果


    结果放回历史 → 模型看到结果 → 决定下一步

这也是为什么 Agent 的能力边界 = 我们给了它多少工具。给它的工具越多、越安全,

它能干的事越多,但风险也越大------工具就是 Agent 的手

三、AgentLoop 的 4 步本质(手写版,一眼看懂)

参考代码:agentloop/01_while_loop.py,核心只有这几步:

python 复制代码
for turn in range(1, 8):                    # ① 限定最多 8 轮,防死循环
    response = llm.invoke(messages)         # ② 让模型思考(基于全部历史)
    messages.append(response)               #    模型的话放回历史

    if not response.tool_calls:             # ③ 模型没要求调工具?
        print(response.content)             #    那就是最终回答,结束
        break

    tool_call = response.tool_calls[0]      # ④ 模型要求调工具:
    result = tool_map[tool_call["name"]].invoke(tool_call["args"])  # 执行!
    messages.append(ToolMessage(            #    结果放回历史(带 tool_call_id)
        content=str(result),
        tool_call_id=tool_call["id"],
    ))                                      #    → 回到 ②,模型继续思考

这 4 步就是所有 Agent 框架的底层原语。

后面学 LangGraph,你会发现它只是把这 4 步"画"成了一张开源的图。

三个必须记住的细节

  1. 历史要全量回传:每一轮都要把完整对话历史发给模型,模型才能"记得"前面做过什么。
  2. tool_call_id 要对上号:工具结果必须带模型给的 id,模型才知道"这个结果回应的是哪个调用"。
  3. 必须有最大轮数 :模型可能陷入死循环(反复调同一个工具),for range(8) 就是保险丝。

四、核心概念:ReAct(推理 + 行动)

Agent 边思考边行动的经典范式叫 ReAct(Reasoning + Acting):

  • Reasoning(推理):模型观察当前状态,决定"下一步该干嘛"
  • Acting(行动):调用一个工具,观察结果,再推理下一步
txt 复制代码
Thought: 我需要先看看收容所有哪些宠物
Action:  list_files("inbox")
Observation: 有猫咪小花、狗狗旺财、仓鼠球球

Thought: 找到了猫咪小花,现在领养它
Action:  move_file("inbox/猫咪小花.txt", "archive/")
Observation: 移动成功

Thought: 任务完成,可以汇报了
Answer:  已领养猫咪小花......

我们的手写循环就是 ReAct 的代码化。模型输出里的"Thought / Action / Observation"不一定是显式文字------现在的大模型通过结构化的 tool_calls 字段直接表达"我要行动",而观察结果由我们回传。

五、动手体验(10 分钟)

bash 复制代码
cd ~/simpleAgent
source .venv/bin/activate
# 配置 .env 里的 API_KEY(DeepSeek 注册送额度)

cd agentloop
python3 01_while_loop.py

运行后你会亲眼看到每一轮的过程:

txt 复制代码
--- 第 1 轮:模型思考 ---
模型决定调用工具:list_files({"path": "inbox"})
工具返回 = - inbox/猫咪小花.txt ...

--- 第 2 轮:模型思考 ---
模型决定调用工具:move_file({"source": "inbox/猫咪小花.txt", "target": "archive/"})
工具返回 = 已移动 ...

--- 第 3 轮:模型思考 ---
✅ 最终回答:已完成领养......

推荐练习

  1. 把任务改成"领养仓鼠球球"------观察模型怎么自己调整工具参数
  2. 在代码里故意去掉 ToolMessage 回传------看模型会"失忆"
  3. range(1, 8) 改成 range(1, 2)------看模型来不及完成任务

六、小结

概念 一句话
AgentLoop 反复"思考 → 执行工具 → 回传结果"直到任务完成的循环
ReAct 推理 + 行动交替的经典范式
tool_calls 模型表达"想调工具"的结构化字段(name / args / id)
执行权 永远在我们代码手里,模型只提议
最大轮数 防止死循环的保险丝
相关推荐
2601_962100548 小时前
python包和模块的内容整理
python·模块·导入·虚拟环境·
甲维斯8 小时前
Gemini锐评GPT6:我要泼冷水扒底裤!
人工智能
二进制漫游记8 小时前
FastAPI项目集成 Qdrant向量数据库+阿里云Embedding完整实战(工具封装+业务调用)
数据库·python·阿里云·embedding
2501_928996228 小时前
GPT-4o换DeepSeek迁移成本多少?中科热备解析API聚合平台技术账本
前端·数据库·人工智能
敢敢のwings9 小时前
ACT-2 深度解析:家用机器人如何把“会做”推进到“可靠地做”
人工智能·机器人
DM今天肝到几点?9 小时前
AI 安全进入「攻防同频」:Gemini 3.8 Flash Cyber 上线、Astra 触及关键级、HiddenLayer 融资 1 亿美元
网络·人工智能·深度学习·安全·语言模型·开源·知识图谱
-今昭-9 小时前
《V2V 迁移实战:将 VMware 虚拟机转为 OpenStack 可用 Glance qcow2 镜像》
开发语言·python
智购科技自动贩卖机9 小时前
自动售货机嵌入式状态机设计实战:从45个事件源到层次型状态机的工程重构
大数据·人工智能·stm32·物联网·重构·硬件架构
乐迪信息9 小时前
智慧港口船舶AI算法实现在线状态监测
大数据·人工智能·深度学习·算法·计算机视觉
markvivv9 小时前
读《OpenViking:上下文数据库架构介绍》有感
人工智能·上下文工程