Agent基本架构
先谈谈Agent基本架构概念,如果看得云里雾里,等看完本篇之后,再回头看就会豁然开朗的,而我尽量写得更易懂: ) 这里面会穿插着上一篇的内容,请大家记得往回翻翻,传送门:
AI菜鸟向前飞 — LangChain系列之十四 - Agent系列:从现象看机制(上篇)
-
AgentAction
其中,两个重要属性(其实、还有tool_call_id,以后用到再介绍)
-
-
tool:可理解成“函数名”
-
tool_input:可理解成“函数参数”
-
为了好理解,我这样写
func_ret = {"search_article": search_article()}[each.tool].invoke(each.tool_input)
其实,如果按照更正规的写法应该这样
# 注意,这里我用了observation(“观察”),可参考我的上一篇文章进行回顾
observation = {tool.name: tool for tool in tools}[each.tool].invoke(each.tool_input)
-
AgentFinish
可以通过这个key:return_values获得结果内容
intermediate_steps = []
while not isinstance(res := agent.invoke({"input": "AI菜鸟向前飞系列文章出自哪里?", "intermediate_steps": intermediate_steps}), AgentFinish):for each in res:observation = {tool.name: tool for tool in tools}[each.tool].invoke(each.tool_input)intermediate_steps.append((each, observation))# 请注意这里:)
print(res.return_values)
-
Intermediate Steps (中间步骤)
感觉称它为“之前”的步骤,更易懂
记录之前AgentAction的内容和结果
intermediate_steps.append((each, func_ret.content))
在下一次调用的时候,一定要带上它
agent.invoke({"input": "AI菜鸟向前飞系列文章出自哪里?", "intermediate_steps": intermediate_steps}
-
AgentInput
所需要输入的intermediate_steps,上面介绍了👆
-
AgentOutput
所要采取的下一步行动(Action)或发送给用户的最终响应结果(return_values),即:AgentAction或AgentFinish.
现在,相信你更懂它了,对吧?
让我们稍微深入了解它们,官方资料如是说:
next_action = agent.get_action(...)
while next_action != AgentFinish:
observation = run(next_action)
next_action = agent.get_action(..., next_action, observation)
return next_action
但是也是浮于表面,例如:什么时候才真正的AgentFinish?Tool与LLM的交互到底是怎样的?先看这张图吧, 让我们通过源码分析吧。
不会真的看代码吧,那太复杂了,当然不会,请看图吧: )
Agent运行机制
抽丝剥茧~ 看以下两张图就懂了,不懂可找我: )
-
图一:(是不是很熟悉,这就是LCEL,同时也是Agent的创建方式)
请参考:
AI菜鸟向前飞 — LangChain系列之六 - 深入浅出LCEL与Chain(上篇)
AI菜鸟向前飞 — LangChain系列之七 - 深入浅出LCEL与Chain(中篇)
AI菜鸟向前飞 — LangChain系列之八 - 深入浅出LCEL与Chain(下篇)
-
图二:(重点来了,一个Agent的“旅行”)
看完之后是不是清晰多了,但还不够,例如:
-
-
tool_calls是如何与Agent执行结果以及和LLM交互之后,可以找到正确的结果的
-
这里面没提到的ToolCall、ToolMessage 以及它们之间的关系
-
过程对象,如:ChatResult、LLMResult,它们各是指什么?
-
还有,各种XXChunks是什么?各代表什么含义?
-
additional_kwargs的用处是什么?
-
…………
-
若大家对这方面感兴趣,可持续关注我,有需要我还会“娓娓道来”,再给大家做深入介绍:)