【Langchain Agent研究】SalesGPT项目介绍(四)-CSDN博客
上节课,我们分析了一下salesGPT项目里源代码的一些问题,重新写了一个运行方法,换了一个模型并修改了一些源代码开始把项目跑起来了,我们已经可以通过console和模型进行对话了。
我们之前选的模式是不使用工具的模式,所以我们启用的是sales_conversation_utterance_chain,这节课我们尝试使用工具,也就是之前我们介绍过的sales_agent_executor和用setup_knowledge_base()方法构造的knowledge_base。
1. 运行使用工具的Agent
我们重新写一个my_test_with_tools.py的方法,其他的地方一样,注意在构造sales_agent的时候,use_tools=True,product_catalog要改一下,用你项目本地的地址:
sales_agent = SalesGPT.from_llm(
llm,
verbose=True,
use_tools=True,
product_catalog=r"C:\Users\Administrator\SalesGPT\examples\sample_product_catalog.txt",
salesperson_name="Ted Lasso",
salesperson_role="Sales Representative",
company_name="Sleep Haven",
company_business="""Sleep Haven
is a premium mattress company that provides
customers with the most comfortable and
supportive sleeping experience possible.
We offer a range of high-quality mattresses,
pillows, and bedding accessories
that are designed to meet the unique
needs of our customers.""",
)
我们运行一下这块代码,发现在我们询问产品价格后,Agent开始思考是否要使用工具(就是我们之前构造的另外一个Agent——knowledge_base,它是一个RetrievalQA类型的Chain,也可以认为是一个Agent),下面是它的思考过程,我直接用prompt模板里面的内容了:
这里能看到我和机器人对话的聊天记录(我使用的是中文询问),也能看到当我询问产品和价格后,我们启用了 sales_agent_executor,它开始思考是否使用它的工具——另外一个Agent进行QA查询。它的决定是YES,启用knowledge_base去查询价格。
我们在【Langchain Agent研究】SalesGPT项目介绍(三)-CSDN博客中留下了两个遗留问题,我们在能运行项目之后再来看一下这里面的东西就清晰了:
2. CustomPromptTemplateForTools
首先在调用CustomPromptTemplateForTools时,有三个地方需要注意,第一个是tools_getter=lambda x: tools。
prompt = CustomPromptTemplateForTools(
template=SALES_AGENT_TOOLS_PROMPT,
tools_getter=lambda x: tools,
# This omits the `agent_scratchpad`, `tools`, and `tool_names` variables because those are generated dynamically
# This includes the `intermediate_steps` variable because that is needed
input_variables=[
"input",
"intermediate_steps", #这是在调用tools时,会产生的中间变量,是一个list里面的一个tuple,一个是action,一个是observation
"salesperson_name",
"salesperson_role",
"company_name",
"company_business",
"company_values",
"conversation_purpose",
"conversation_type",
"conversation_history",
],
)
这一行的意思是,tools_getter这个lambda函数接收任意一个参数,返回tools。所以在后面的代码里,我改变了原来代码的输入,这完全不影响后续的结果:
# tools = self.tools_getter(kwargs["input"])
tools = self.tools_getter([])
第二个是input_variables里的input是没有值的,这一点困惑了我很久,后来我才发现其实这里根本不需要input应该也是不影响代码调用的,大家可以自己试试。
第三个是intermediate_steps,这是一个只有在代码运行中并调用了tools时才会产生的中间变量,我把它找了出来贴一下:
这个是一个LIST,里面有一个tuple,tuple里面又是两个tuple ,一个是action,一个是observation,我们就用action的log和observation去构造agent_scratchpad,agent_scratchpad是构造有memory的agent必要的一个组件。至此,我们就基本搞明白了CustomPromptTemplateForTools,用它的format方法把输入的参数进行一些调整、拼接,获得一个新的prompt。但是有一点我有点不太明白的是,CustomPromptTemplateForTools这个类的format方法我并没有调用过,为啥就生效呢?这个确实不太明白,可能涉及到langchain对于prompt这块的底层设计原理,我现在还接触不到。
3. SalesConvoOutputParser
我们来看一下这个输出解析器。这块也是之前遗留的一个难点,因为这个Parser处理的是sales_agent_executor执行后的结果,不看到具体的输出我们确实很难理解这块代码在干什么。
我们启动代码,然后输入查询价格的指令:
首先,stage_analyzer_chain进行阶段判断,判定到了第三个阶段:
然后,AgentExecutor开始执行,AgentExecutor在读取了历史聊天记录后开始进行分析,这个是它的输出:
到这里,我们就理解了SalesConvoOutputParser代码中:
regex = r"Action: (.*?)[\n]*Action Input: (.*)"
match = re.search(regex, text)
if not match:
## TODO - this is not entirely reliable, sometimes results in an error.
return AgentFinish(
{
"output": "I apologize, I was unable to find the answer to your question. Is there anything else I can help with?"
},
text,
)
# raise OutputParserException(f"Could not parse LLM output: `{text}`")
action = match.group(1)
action_input = match.group(2)
return AgentAction(action.strip(), action_input.strip(" ").strip('"'), text)
regex = r"Action: (.*?)[\n]*Action Input: (.*)" 是一个正则表达式,这个正则表达式可以用来匹配文本中以"Action:"开头,接着是动作内容,然后是零个或多个换行符,最后以"Action Input:"开头,接着是动作输入内容的部分。后面做的事情就是要用这个正则表达式去查询TEXT内容,去把"Action:"和"Action Input:"后面的东西提取出来,并赋值给action和action_input。
这是AgentExecutor第一轮的输出,然后到第二轮的输出:
这个时候,已经通过调用工具进行了知识库查询,获得了这段TEXT,然后我们就理解了这段代码的作用:
if f"{self.ai_prefix}:" in text:
return AgentFinish(
{"output": text.split(f"{self.ai_prefix}:")[-1].strip()}, text
)
就是如果发现了Ted Lasso:为开头的输出,那就表明AgentExecutor已经获得了执行结果,代表可以返回AgentFinish,代表这个流程结束了。
4.结束语
至此,我们就基本掌握了SalesGPT的基本原理,也了解了它的核心代码逻辑和一些有难点的地方,这对于我们理解多Agent系统,对话阶段判断和prompt与parser的内容组装调整有巨大的好处。
下一步,我们将尝试把我们之前构造的聊天机器人加入多Agent系统,让他可以根据用户对话的情况进行分析,给用户推销适配的旅游产品。