恭喜 Manus 被 Meta 收购。这对 AI 行业从业者来说是一剂强心剂。Manus 目前被视为通用 agent 的代表,但其实很多人还并不知道什么是 agent,或者说,不了解 agent 与非 agent 之间的区别,我自己也困惑了很久。在今年 3 月 Manus 正式上线之前,整个行业对于 agent 的使用确实很混乱,我经常问的一个问题:“chatGPT 算不算 agent?”,答案也不统一。可以说是,一千个创业者口中有一千种 agent 含义了。但当下我们在 AI 相关的语境下提到 agent 时,它的含义已经显著的收敛了,在这点上确实得感谢 Manus 。
Agent 的含义倒在其次,agent 到底是怎么运行的?为什么好像 agent 就比 ChatGPT 厉害呢?今天就借着 Manus 的例子,用非技术化的语言,解释一下“当我们使用 agent 时,它内部发生了什么”这件事。
先认识三个角色
为了更好的理解,我们先说明一下 agent 中最重要的3 个“角色”,分别是:用户、服务端、LLM(大语言模型,下文简称模型)。
用户最好理解,就是提出问题、需求的角色。
模型是一个“你给我一些文本,我就会吐出来一些文本”的机器。最简单的就是用文本形式给它输入一个问题,它会以文本形式输出回答。例如你给它的输入:“苹果是什么”。它可能会输出:“苹果是一种水果。在另外的语境下,它也代指一家科技公司。”
它只能做这件事,但是在做这件事的时候它表现的还算智能。 并且最重要的事,它的智力水平在快速提升。尽管如此,模型也还是有些“问题”,“回答的“不是很好。
值得注意的是,哪怕是你的输入是完全一致的,它的输出也可能是不完全一致的。这不是指语义上的不一致,而是指文本内容(token)上的不一致。这种不一致并不是数学层面上的必然不一致,而是很多因素可能会导致不一致,这里不展开介绍了。
在用户和模型之间建立桥梁完成所有其余必要工作的,我们统称为服务端,服务端至少要处理:
- 接受用户的信息
- 提供给模型的输入
- 接受模型的输出
- 提供给用户的反馈信息
一个 Chatbot 的工作流程
好的,我们现在可以正式开始了,还是采用上一篇中的《9.11 和 9.8 谁大》的例子吧,没看过的朋友可以从这里进入: 《第 2 篇 · 上下文工程就是把没明说的都明说出来》 。我们先假定模型的水平还是之前那种,不能直接正确回答小数的大小比较的问题。
一个 chatbot 中发生的流程是这样的:
用户输入:{比较 9.11 和9.8的大小}
服务端收到用户的输入,然后加上 system prompt,加上安全策略提示等等打包一起拼成了一个新的给模型的输入:
{
system prompt: 你是一个智能助手,你调用你的知识认真回答用户的每一个问题。
在回答问题时,要避免输出涉及危险或暴力的内容。
以下是用户的问题:“比较 9.11 和 9.8 的大小”
}服务端接收到模型的输出(假定模型水平是不会比小数大小的):{ 因为 11 比 8 大,所以 9.11 比 9.8 大。}
服务端把信息发送给用户:{ 因为 11 比 8 大,所以 9.11 比 9.8 大。}
怎样让回答更准确
通过这个流程我们可以想象,要想让模型能正确回答小数大小比较的问题,有几种解决方法:
一、用户提高自身水平
在 1 中的用户输入变成:{ 按照以下逻辑执行数值大小比较: 比较两个数的大小的时候,首先要比较最高相同数位的数值的大小,如果相同再比较下一数位的数值的大小,比较小数点后面的数值大小时,应该将小数点后的所有数字作为一个整体,然后比较大小。 比较 9.11 和9.8的大小。}
这显然不合适,不能指望所有用户都有你的水平。
二、system 提示词优化
在 2 中服务端给模型的输入时,增加一些内容:
{
system prompt: 你是一个智能助手,你调用你的知识认真回答用户的每一个问题。
在回答问题时,要避免输出涉及危险或暴力的内容。
你在回答小数大小比较类的问题时采用以下逻辑: 比较两个数的大小的时候,首先要比较最高相同数位的数值的大小,如果相同再比较下一数位的数值的大小,比较小数点后面的数值大小时,应该将小数点后的所有数字作为一个整体,然后比较大小。
以下是用户的问题:“比较 9.11 和 9.8 的大小”
}
这个就是提示词工程,但这么做了有个问题,就是不管用户发什么,都得加这么一段 system prompt,用户问:“苹果是什么”,服务端给模型发的还是:
{
system prompt: 你是一个智能助手,你调用你的知识认真回答用户的每一个问题。
在回答问题时,要避免输出涉及危险或暴力的内容。
你在回答小数大小比较类的问题时采用以下逻辑: 比较两个数的大小的时候,首先要比较最高相同数位的数值的大小,如果相同再比较下一数位的数值的大小,比较小数点后面的数值大小时,应该将小数点后的所有数字作为一个整体,然后比较大小。
以下是用户的问题:“苹果是什么”
}
不仅是每个问题都加这么一段固定的,甚至你跟他继续对话中的每次消息,它都加了这么一段。这就很呆了。每次都增加 token 消耗都是小事了,用这种方法能优化这么一个问题,那有两个要优化的问题怎么办?十个一百个怎么办?于是 agent 应运而生:
Agent 采用了新的流程
agent 采用了新的流程:
用户输入:{ 比较 9.11 和9.8的大小 }
服务端给模型的输入 :
{
这是用户需求:“比较 9.11 和9.8的大小”
这是你可以使用的工具:
list_file {列出全部文件列表}
read_file {读取特定文件内容}
write_file {在特定文件中写入内容}、
create_file {创建文件}
回复用户特定内容
……
请回复下一步的操作是什么?
}模型回复:{执行list_file 操作,列出全部文件列表}
服务端收到模型回复后运行函数后再次给模型输入:
{
这是用户需求:“比较 9.11 和9.8的大小”
这是你可以使用的工具:
list_file {列出全部文件列表}
read_file {读取特定文件内容}
write_file {在特定文件中写入内容}、
create_file {创建文件}
回复用户特定内容
……
目前已存在的文件有:
比较数值大小的方法.md
xxx.md
yyy.md
zzz.json
……
请回复下一步的操作是什么?
}模型回复:{ 执行 read_file 操作,读取 比较数值大小的方法.md }
服务端收到模型回复后运行函数后再次给模型输入:
{
这是用户需求:“比较 9.11 和9.8的大小”
这是你可以使用的工具:
list_file {列出全部文件列表}
read_file {读取特定文件内容}
write_file {在特定文件中写入内容}、
create_file {创建文件}
回复用户特定内容
……
目前已存在的文件有:
比较数值大小的方法.md
xxx.md
yyy.md
zzz.json
……
这是读取到的文件内容:
「比较两个数的大小的时候,首先要比较最高相同数位的数值的大小,如果相同再比较下一数位的数值的大小,比较小数点后面的数值大小时,应该将小数点后的所有数字作为一个整体,然后比较大小。」
请回复下一步的操作是什么?
}模型回复:{
回复用户: 根据《 比较数值大小的方法.md 》中提供的方法,用户的问题"比较 9.11 和9.8的大小" 的答案是:9.11 <9.8
}服务端给用户返回结果:“9.11 <9.8”
关键是工具,以及不断追问“然后呢?”
这就是 agent 的核心设计思路。这里面最最重要的事情是,定义好可以被使用的工具。至于每次要使用什么工具,我们就相信模型的判断。然后不停的把使用了工具之后的结果加进来,再去问模型。像个小孩子一样,不听的问,“然后呢?”,直到模型告诉你可以了,我们可以给用户结论了。
这个过程看似繁琐,但其实是个还挺精妙的设计,它接纳了模型不是万能的,它不能自己一次性解决问题,但模型又是有点水平的,所以我们通过各种方式来给模型提供它不知道的信息,从而充分利用模型的水平,以最大程度的满足用户的需求。
产品与工程的发挥空间
这样的结构也给 agent 开发者,尤其是其中的产品经理们提供了发挥空间 —— 在模型能力不提升的情况下,也能有办法提高产品的效果。比如更好的工具定义、更垂直的知识库、更好的自动化流程等等。我前面描述的结构其实是个过于简陋的结构,事实上,在面对用户提出的诸如“分析特斯拉近期财报”等相对复杂问题时,模型都会先使用流程规划的工具,先创建个 ToDo.md 并写入内容,再基于这个文件不停追踪进展。
工程上的优化空间也非常大。可以想象,这种流程必然带来 token 消耗的爆炸增长。如何有效控制成本就是一个大课题。以及记忆外部化、上下文卸载等等基于这个新结构新流程所衍生出来的技术方案,都为 agent 开发打开了新思路。
当然,除了这个结构以外,模型本身的水平也至关重要,因为这里的判断和决策几乎都相信模型给的结果。在对工具的使用,尤其是长跨度任务规划中,claude sonnet 3.5 模型的水平至关重要。不得不说,Manus 和 cursor 这些知名 agent 产品都是 claude sonnet 3.5 的受益者。但也不得不说,模型的能力在当时当下的时间点差不多就会到达这个水平,不是 claude 也会是别人。
技术的洪流滚滚向前,任何人都无法阻挡,只能参与。
欢迎关注本人公众号 产品狗的马后炮 。