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)
执行权 永远在我们代码手里,模型只提议
最大轮数 防止死循环的保险丝
相关推荐
phoenix@Capricornus1 小时前
从统计决策到贝叶斯估计
人工智能·算法·机器学习
NutShell Wang1 小时前
国产全模态开源潮:从语言模型到视频模型,中国开源生态再升级
人工智能·语言模型·开源·大模型·音视频·多模态·vibe coding
薛晓刚1 小时前
信息化、数字化:智能化的基础,还是历史包袱?
人工智能
Black蜡笔小新1 小时前
从智慧社区到雪亮工程:国标GB28181公网平台EasyCVR如何构建视频“一张网”?
人工智能·自动化·easycvr
一次旅行1 小时前
Agent面试题答案整理(一)
人工智能·microsoft
Patrick在香港1 小时前
Python爬虫框架实战:优雅抓取香港政府公开API数据的通用方案
java·开发语言·爬虫·python·ai编程·数据可视化·可用性测试
AICDragon1 小时前
1.8%就够了:K3的896个MoE专家,为什么激活率这么低反而是好事?
人工智能·算法
一心只读圣贤书1 小时前
AI 辅助前端视觉回归治理:从截图基线到变更解释
前端·人工智能
paopao_djshddhdj1 小时前
AI时代:企业如何实现钉钉数字化转型
人工智能·钉钉