AI开发-python-langchain框架(--langchain与milvus的结合 )

1.概述

在人工智能快速发展的今天,AI不再仅仅是回答问题的聊天机器人,而是正在演变为能够主动完成复杂任务的智能代理。OpenAI的Codex CLI就是这一趋势的典型代表------一个跨平台的本地软件代理,能够在用户的机器上安全高效地生成高质量的软件变更。

2.内容

如果你只把 Codex 当成"更会写代码的 ChatGPT",那你只理解了它 10% 的价值。真正让 Codex 不同的,是它背后那套完整、可运行、可反复思考的 Agent Loop(智能体循环)系统。

2.1 Codex 到底和普通大模型有什么区别?

我们先看一个最普通的大模型交互流程:

你:帮我写一个 Python 脚本

模型:给你一段代码

结束

这是一次性生成,模型:

不知道代码能不能运行

不知道有没有报错

更不知道"下一步该干什么"

  1. Codex 的真实工作方式完全不同

Codex 的思路更像一个新手工程师坐在你电脑前:

复制代码

1 看需求

2 写点代码

3 运行一下

4 报错了?看看错误

5 改代码

6 再运行

7 直到成功

复制代码

这个「反复尝试」的过程,就是 Codex Agent Loop。

2.2 什么是 Agent Loop?

Agent Loop = 让模型在一个循环里,不断思考 → 行动 → 看结果 → 再思考。Codex CLI 的核心不是"一次推理",而是反复展开这个循环,模型不是直接给答案,而是每一轮只决定:我下一步该干什么?

  1. 先忘掉「大模型」,把 Codex 当成一个"新人程序员"

想象一个刚入职的初级工程师,你给他一个任务:

"帮我把这个项目跑起来,并写一个 README。"

他会怎么做?一定不是:

"我闭上眼睛,一次性把所有事情做对。"

而是更接近下面这个过程:

复制代码

1 先看看项目目录结构

2 猜一猜怎么运行

3 真的运行一下

4 发现报错

5 根据报错改代码

6 再运行

7 直到跑通

8 最后再总结,写 README

复制代码

注意:

这个过程中,每一步都依赖上一步的结果。这,就是 Agent Loop 的直觉来源。

2.普通 ChatBot VS Agent:根本区别在哪?

普通 ChatBot 的工作方式

复制代码

输入问题

模型"想一想"

一次性输出答案

结束

复制代码

它的特点是:

只能"想",不能"做"

没有真实世界的反馈

更像是在考试答题

Codex Agent 的工作方式

复制代码

目标

想一小步

做一小步

看结果

再想一小步

......

完成

复制代码

它的特点是:

每一轮只解决一个非常小的问题

每一步都基于真实执行结果

更像是在真实工作

Agent Loop,本质上就是把"一次性回答问题",拆成了"多轮小决策"。

  1. 「Loop」这个词,为什么这么重要?

我们先看一个不展开的情况:

模型在脑子里想 10 步

一次性输出最终答案

这种方式的问题是:

中间哪一步想错了,你完全不知道

没有机会修正

对复杂任务非常不稳定

而 Agent Loop 是把这 10 步"摊开":

复制代码

第 1 步:我该不该看目录?

第 2 步:我该不该运行测试?

第 3 步:这个报错是什么意思?

第 4 步:我该改哪个文件?

复制代码

这就是 unrolling the loop 的含义:把模型原本"在脑子里一次性完成的思考",拆成一轮一轮、可执行、可观察的步骤。

4.为什么说「模型不是直接给答案」?

复杂问题,没有人能在"看都没看现场"的情况下,一次就给出完美答案。Agent Loop 的设计,正是承认了这一点。所以 Codex 的策略是:

不追求"一次答对"

而是追求:

每一步都有依据

每一步都能被验证

每一步错了都能修

假设你的项目现在是这样:

"一个 Node 项目,运行 npm start 会报错"

Codex 的内心独白,并不是一句话,而是类似这样一轮一轮展开:

1 我不知道项目结构,我需要先看看 → 调用工具:ls

2 看起来是 Node 项目,我应该试着运行 → 调用工具:npm start

3 报错说缺依赖 → 调用工具:npm install

4 再运行一次 → npm start

5 现在跑通了,我可以总结了 → 输出最终回答

2.3 把 Agent Loop 拆成 5 个步骤

2.3.1 接收用户目标(不是马上干活)

1 用户输入 ≠ 模型直接思考的内容

当你在 Codex CLI(或任何 Agent 系统)里输入一句话,比如:

"帮我给这个项目补一个 README。"

很多人会误以为:

这句话直接被送进模型,然后模型开始思考。

但实际上,在 Agent 系统里,这句话的角色更接近于:

"任务目标(Goal)"

也就是说,它只是告诉系统:

最终你要把事情做到什么状态

2 为什么要把"目标"和"过程"分开?

因为 Agent Loop 的设计理念是:

目标是稳定的

过程是动态变化的

举个生活化的例子:

你的目标是"把房间收拾干净"

你并不会一开始就决定:

先扫地还是先整理桌子

垃圾有多少

要不要换垃圾袋

你只是知道:最后要干净

Codex 也是一样。

用户输入只负责定义"终点",不负责定义"路径"。

2.3.2 构造当前上下文(Prompt)

1.Prompt 是"模型看世界的全部信息"

这是 Agent Loop 里最关键、也最容易被低估的一步。

我们先说一句非常重要的话:

对模型来说,它并不知道"刚刚发生了什么",

除非你把这些信息放进 Prompt。

所以,每一轮 Agent Loop,都会重新构造一个 Prompt。

2.Prompt 里通常包含哪些东西?

一个完整的 Prompt,通常包含:

你是谁(系统设定)

你是一个 coding agent

你可以修改文件、运行命令

你能用什么工具

shell

文件读写

测试运行

用户目标

比如:补 README

到目前为止发生了什么

我刚才运行了什么命令

输出结果是什么

有没有报错

对模型来说,这些内容就是它的"记忆"。

3.为什么每一轮都要"重新构造" Prompt?

举个例子:

第一轮:你还没看过项目结构

第二轮:你已经知道有哪些文件

第三轮:你已经看到测试报错

如果 Prompt 不更新,模型就会:

永远以为自己什么都不知道

所以 Agent Loop 的一个核心动作就是:

把"刚刚发生的现实结果",翻译成模型能理解的文字,再塞回 Prompt。

2.3.3 让模型做"下一步决策"

1.模型在这一轮,只回答一个问题

这是 Agent Loop 的灵魂所在。

模型不会在这一轮里把所有事情想完。

它只做一个非常具体、非常有限的判断:

"在当前信息条件下,我下一步该做什么?"

2.这个"下一步",通常只有两种可能

情况一:我还需要更多信息 / 行动

模型会说类似:

"我需要看看目录结构"

"我需要跑一下测试"

"我需要打开某个文件看看内容"

在系统层面,这会被表达为:

Tool Call(工具调用)

情况二:信息已经够了,可以结束

模型会说类似:

"现在我可以写 README 了"

"问题已经修复完成"

这时,它会直接输出最终回答,Agent Loop 结束。

3.为什么要限制成"只想一步"?

因为这是控制复杂度的关键。

如果模型一次性想 10 步:

中间哪一步错了,你不知道

无法插入真实反馈

很难纠正

而"一步一想"的好处是:

每一步都可以被验证

错了就马上修

对复杂任务更稳

2.3.4 如果要干活 → 调工具

1.模型自己"不会干活"

模型 ≠ 能执行命令的程序,模型只能输出文字(或结构化指令),但:

它不能真的运行 ls

不能真的执行 npm install

不能真的写文件

2.Tool 的作用:把"建议"变成"现实动作"

当模型说:"我需要运行 ls 看看目录",Agent 系统会:

1 解析模型输出

2 发现这是一个 tool call

3 在真实环境里执行命令

4 收集真实输出

2.3.5 把结果塞回上下文,继续循环

1.这是 Agent Loop 最"反直觉"的一步

很多人会以为:工具执行完,模型"就知道结果了",其实不然。模型并不知道工具执行结果,除非你把结果写进 Prompt。

2.现实 → 文本 → Prompt

Agent 会把刚才的执行结果,转成类似这样的内容:

你刚刚运行了 ls

输出是:

src/

package.json

然后:

把这段文字加入 Prompt

再发起下一轮模型推理

这一步完成后,新的一轮 Loop 开始。

我们现在可以把这 5 步,用一句非常生活化的话说清楚:

1 把当前情况告诉模型

2 让模型决定下一小步

3 把真实结果反馈回去

4 直到模型觉得"可以收工了"

3.Agent Loop代码示例

前面我们讲了很多概念:

Agent Loop、目标、Prompt、工具、反馈......

现在我们用一段最小但完整的代码,把这些概念全部落到实处。

复制代码

class SimpleAgent:

def init(self, llm):

self.llm = llm

self.history = []

def run(self, goal):

while True:

prompt = self.build_prompt(goal)

response = self.llm(prompt)

如果模型说"完成了"

if response["type"] == "final":

print(response["text"])

break

如果模型要用工具

if response["type"] == "tool_call":

result = self.execute_tool(response)

self.history.append(result)

def build_prompt(self, goal):

return {

"goal": goal,

"history": self.history

}

def execute_tool(self, call):

if call["name"] == "shell":

return os.popen(call["command"]).read()

复制代码

这段代码不是生产级,但它100%体现了 Agent Loop 的本质结构。下面我们从整体 → 局部 → 每一行的"为什么"来拆。

1.先整体理解:这段代码在干什么?

它在做一件事:

不断把"当前状态"交给模型,让模型决定下一步,

然后根据结果更新状态,直到模型说"可以结束了"。

可以理解为:"你先想一步 → 我帮你干 → 把结果告诉你 → 你再想一步"

2.class SimpleAgent:Agent 不是模型,而是"调度者"

Agent ≠ 模型(LLM)

llm:负责"思考 / 决策"

Agent:负责"循环 / 执行 / 状态管理"

Agent 的角色更像是一个项目经理 + 执行助理。

3.init:Agent 的"长期记忆"在哪里?

self.llm 是什么?

它是一个函数或对象

输入:Prompt

输出:模型的"下一步决策"

你可以把它理解成:

response = 大模型(prompt)

4.self.history 为什么这么重要?

这是整个 Agent Loop 的核心状态。

history 里存的不是聊天记录,而是:

你刚刚执行了什么命令

命令输出了什么

有没有报错

它是"现实世界发生过的事情"的文本化记录

如果没有 history:

模型每一轮都会"失忆"

永远不知道自己刚才干过什么

5.run 方法:Agent Loop 的真正入口

def run(self, goal):

这里的 goal,就是你输入的那句:

"帮我给这个项目加一个 README"

它只做一件事:定义终点,不定义路径。

6.while True:为什么 Agent 必须是"死循环"?

这行代码非常关键。

很多人一看到"死循环"会下意识觉得不优雅,但在 Agent 里:

没有循环,就没有 Agent

为什么?

因为 Agent 的工作模式是:

不知道要循环多少轮

不知道什么时候信息才"足够"

只能一轮一轮试

结束条件不是写死的,而是由模型决定的。

7.build_prompt:模型"看到的世界"是怎么来的?

prompt = self.build_prompt(goal)

这是 Agent Loop 中最容易被忽略,但最重要的一步。

def build_prompt(self, goal):

return {

"goal": goal,

"history": self.history

}

它做的事情非常简单,但意义非常大:把"目标 + 已发生的事实"打包,交给模型。

8.response = self.llm(prompt):模型只做一件事

response = self.llm(prompt)

这一行,看似简单,其实决定了整个 Agent 的风格。

模型在这里不会:

写完整代码

一次性解决所有问题

它只回答一个问题:

"在当前 prompt 条件下,我下一步该做什么?"

我们用一句完整的流程复述:

Agent 把目标 + 历史交给模型

模型说:"下一步干这个"

Agent 去真实执行

Agent 把结果记录下来

回到第 1 步

直到模型说:

"可以结束了。"

4.总结

Codex Agent 的真正价值,并不在于它"写代码有多快",而在于它被设计成一个可以反复思考和行动的系统。通过 Agent Loop,模型不再试图一次性给出完美答案,而是像真实工程师一样:先尝试、再观察、再修正,逐步推进目标完成。这种"思考 → 执行 → 反馈 → 再思考"的循环机制,让复杂问题被自然拆解成一连串可验证的小步骤,也让错误变成系统的一部分,而不是失败的终点。倮继擅俚

相关推荐
UMD5rVHPd3 小时前
Springboot 实现多数据源(PostgreSL 和 SL Server)连接
分享
SS4L4t7ZZ3 小时前
一文学习 Spring 声明式事务源码全流程总结
分享
超帅的花瓣3 小时前
macos简单配置openclaw
分享
超级何处染秋霜4 小时前
CodeMagicianT
分享
GU8NnqNxZ4 小时前
Jenkins 学习总结
分享
想人陪的大叔4 小时前
Jenkins 学习总结
分享
超级何处染秋霜4 小时前
Jenkins 学习总结
分享
HE7Nxdlq74 小时前
万字拆解 LLM 运行机制:Token、上下文与采样参数
分享