首页 > 其他分享 >AI菜鸟向前飞 — LangChain系列之十四 - Agent系列:从现象看机制(上篇)

AI菜鸟向前飞 — LangChain系列之十四 - Agent系列:从现象看机制(上篇)

时间:2024-05-26 23:06:08浏览次数:24  
标签:search 系列 AI 菜鸟 tool None article

上一篇介绍了Agent与LangGraph的基础技能Tool的必知必会

AI菜鸟向前飞 — LangChain系列之十三 - 关于Tool的必知必会

前面已经详细介绍了Prompt、RAG,终于来到Agent系列(别急后面还有LangGraph),大家可以先看下这张图:    看完我这系列就都懂了:)

图片

牛刀初试

    由于本篇是入门,我们直接边看程序边熟悉整个过程吧 先以BaseTool的方式实现一个Tool,代码如下:

class search_article(BaseTool):
    name = "search_article"
    description = "查询所有的文章来源"
    def _run(self, topic: str):
        return chain_rag.invoke({"question": topic})

关于chain_rag的内容,请参考我的这篇公众号文章

LangChain实战技巧之二:RunnablePassthrough.assign的两则妙用

我们看看两种Agent的“书写”方式

  • 第一种

agent = (
    RunnablePassthrough.assign(agent_scratchpad=lambda x: format_to_tool_messages(x["intermediate_steps"])
    )
    | hub.pull("hwchase17/openai-tools-agent")
    | model.bind_tools(tools=[search_article()])
    | ToolsAgentOutputParser()
)
  • 第二种

agent = create_tool_calling_agent(prompt=hub.pull("hwchase17/openai-tools-agent"), llm=model, tools=[search_article()])

你喜欢哪种呢?

接下来你是不是想执行看看效果,结果会让你大跌眼镜、你没有眼镜的话配一个 先~

res = agent.invoke({"input": "AI菜鸟向前飞系列文章出自哪里?", "intermediate_steps": []})

这里为什么要加这个"intermediate_steps",不加会报错,不信你试试,若要知道这个机制请看下篇:)

输出结果

# 输出了这样一坨
[ToolAgentAction(tool='search_article', tool_input={'topic': 'AI菜鸟向前飞'}, log="\nInvoking: `search_article` with `{'topic': 'AI菜鸟向前飞'}`\n\n\n", message_log=[AIMessage(content='', additional_kwargs={'documents': None, 'citations': None, 'search_results': None, 'search_queries': None, 'is_search_required': None, 'generation_id': 'd12bfa56-e394-48a0-bff1-97f76dabe92f', 'tool_calls': [{'id': '5617aa7b3ed74d1789befac4b6a9d573', 'function': {'name': 'search_article', 'arguments': '{"topic": "AI\\u83dc\\u9e1f\\u5411\\u524d\\u98de"}'}, 'type': 'function'}], 'token_count': {'output_tokens': 12}}, response_metadata={'documents': None, 'citations': None, 'search_results': None, 'search_queries': None, 'is_search_required': None, 'generation_id': 'd12bfa56-e394-48a0-bff1-97f76dabe92f', 'tool_calls': [{'id': '5617aa7b3ed74d1789befac4b6a9d573', 'function': {'name': 'search_article', 'arguments': '{"topic": "AI\\u83dc\\u9e1f\\u5411\\u524d\\u98de"}'}, 'type': 'function'}], 'token_count': {'output_tokens': 12}}, id='run-592cded4-3fb7-48d3-99d7-87166d7bb232-0', tool_calls=[{'name': 'search_article', 'args': {'topic': 'AI菜鸟向前飞'}, 'id': '092624d480bd461daacc54fdda64c7b5'}])], tool_call_id='092624d480bd461daacc54fdda64c7b5')]

直截了当看结果

    通常的教法,应该是你需要引入AgentExecutor,而如果我也是这样跟大家介绍的话,就不是我这个系列的风格了:)

    如果用AgentExecutor的话,代码如下:

agent_executor = AgentExecutor(agent=agent, tools=[search_article()], verbose=True)
# 然后再invoke就能得到你想要的
agent_executor.invoke("AI菜鸟向前飞系列文章出自哪里?")

    直截了当

{'input': 'AI菜鸟向前飞系列文章出自哪里?', 'output': 'AI菜鸟向前飞系列文章出自Song榆钱儿的公众号。'}

(换个方式)直奔Agent

    但是跑题了,我们主要讲的是Agent,而不是AgentExecutor,也就是说如果仅用Agent呢?

    看到输出内容

[ToolAgentAction(tool='search_article', tool_input={'topic': 'AI菜鸟向前飞'}, ……

    聪明的小伙伴可以用Python去解决问题,如下:

# 为啥这里要用这个,因为它是列表啊,为啥是列表,以后再介绍
for each in res:
    result = {"search_article": search_article()}[each.tool].invoke(each.tool_input)
    print(result)

    最后它确实被执行,结果如下:

content='AI菜鸟向前飞系列文章是出自公众号"Song榆钱儿"的原创作品。截至目前,该系列已经有20多篇原创文章,并且拥有109名关注者。' additional_kwargs={'documents': None, 'citations': None, 'search_results': None, 'search_queries': None, 'is_search_required': None, 'generation_id': 'f12940a2-38de-4bba-a7b0-254f40c90596', 'token_count': {'input_tokens': 156, 'output_tokens': 44}} response_metadata={'documents': None, 'citations': None, 'search_results': None, 'search_queries': None, 'is_search_required': None, 'generation_id': 'f12940a2-38de-4bba-a7b0-254f40c90596', 'token_count': {'input_tokens': 156, 'output_tokens': 44}} id='run-f7cc290b-34f8-4eca-bcfa-85c3bcf2b74e-0'

也就是都是RAG的“功劳”,上面代码提到的:

………………
return chain_rag.invoke({"question": topic})

柳暗花明

    各位看官会想,这跟我单独执行Tool函数有啥区别,绕了一个大圈子,这秘密就存在于"intermediate_steps"当中(卖个关子,后面介绍)先看如下代码:

intermediate_steps = []
while not isinstance(
    res := agent.invoke({"input": "AI菜鸟向前飞系列文章出自哪里?", "intermediate_steps": intermediate_steps}), AgentFinish):

    for each in res:
        func_ret = {"search_article": search_article()}[each.tool].invoke(each.tool_input)
        intermediate_steps.append((each, func_ret.content))

    是不是感觉跟用AgentExecutor一样了:)

简述ReAct

    最后分享一个聊到Agent 大部分博文都会提到的ReAct (Reason Act),以一个示例来演示下吧,各处重要内容,我都加上了注释来为大家解释:)

> Entering new AgentExecutor chain...
# 思考
Thought: I can answer this question by searching for the source of the "AI菜鸟向前飞" series.

# 行动
Action: search_article
Action Input: AI菜鸟向前飞

# 观察
Observation content='AI菜鸟向前飞系列文章是出自Song榆钱儿的公众号。该系列文章目前已经有20多篇原创文章,并且已有109人关注。' additional_kwargs={'documents': None, 'citations': None, 'search_results': None, 'search_queries': None, 'is_search_required': None, 'generation_id': 'e07bf920-967a-4269-bae0-6acd4358a90f', 'token_count': {'input_tokens': 158, 'output_tokens': 38}} response_metadata={'documents': None, 'citations': None, 'search_results': None, 'search_queries': None, 'is_search_required': None, 'generation_id': 'e07bf920-967a-4269-bae0-6acd4358a90f', 'token_count': {'input_tokens': 158, 'output_tokens': 38}} id='run-efd02271-a86f-4dee-bd0e-0e9133efd7b7-0'
# 找到正解
Final Answer: AI菜鸟向前飞系列文章出自Song榆钱儿的公众号。该系列文章目前已经有20多篇原创文章,并且已有109人关注。

> Finished chain.
{'input': 'AI菜鸟向前飞系列文章出自哪里?', 'output': 'AI菜鸟向前飞系列文章出自Song榆钱儿的公众号。该系列文章目前已经有20多篇原创文章,并且已有109人关注。'}

原理过程图:关于这张图,后面若大家有需要我再详细深入讲解

图片

敬请期待下一篇:)

标签:search,系列,AI,菜鸟,tool,None,article
From: https://blog.csdn.net/soukingang/article/details/139206619

相关文章

  • 彻底火了!《AIGC 面试宝典》圈粉无数!
    2022年下半年以来,文本生成图像快速出圈,多款应用持续火爆。国外文生图代表:Midjourney、StableDiffusion、OpenAI的DALL-E:海外模型SD开源,进一步促进了国内大厂的研究热情和应用落地:随着多模态技术迭代,图像生成、视频生成、3D生成、音频生成等AIGC应用加速落地,相关岗......
  • AI菜鸟向前飞 — LangChain系列之十二 - RAG(下篇):Index和Retriever
    AI菜鸟向前飞—LangChain系列之十-RAG(上篇)AI菜鸟向前飞—LangChain系列之十一-RAG(中篇)先分享个问题的解法#在使用Chroma实例化过程中,可能会出现如下报错AttributeError:typeobject'hnswlib.Index'hasnoattribute'file_handle_count'当使用代码遇到如上问......
  • Web系列-前端游戏
    Web系列-前端游戏在CTF比赛web题目中,出题人为了添加趣味性,常有将web小游戏作为题目的,本篇博客会将自己遇到的web前端游戏题目记录在这里。[NewStarCTF2023公开赛道]游戏高手是一个飞机大战的游戏题目说100000分就给flag,F12看看游戏游戏代码在app_v2.js中找到关键代码//......
  • KubeSphere系列---【离线安装kubeSphere时报错:failed: [k8s_node02] failed to conne
    1.报错信息[root@k8s_masterkubesphere-3.4.1-1.23.15-offline-package]#./kkinitregistry-fconfig-sample.yaml-akubesphere.tar.gz_______||//||||//||//__||_____||//_____......
  • 基于深度学习的入侵检测系统综述文献概述——AI科研之路
    1、研究方向的背景是什么?(1)互联网发展迅速,网络安全态势严重(2)现在的入侵检测准确率不够高,不能适应现在的需求2、前人做了哪方面的工作获得了什么成果?近代:将网络作为入侵来源之后发展(基于异常网络的检测技术):(1)基于数据挖掘与机器学习的入侵检测算法(2)基于深度学习的入侵检测......
  • 【免费Web系列】大家好 ,今天是Web课程的第六天点赞收藏关注,持续更新作品 !
        这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r后端Web实战(IOC+DI)前言Web开发的基础知识,包括Tomcat、Servlet、HTTP协议等,我们都已经学习完毕了,那接下来,我们就要进入Web开发的实战篇。在实战篇中,我们将通过一个案例,来讲解Web开发的核心......
  • [AIGC] flink sql 消费kafka消息,然后写到mysql中的demo
    这是一个使用FlinkSQL从Kafka中消费数据并写入MySQL的示例。在这个示例中,我们将假设有一个Kafka主题“input_topic”,它产生格式为(user_id:int,item_id:int,behavior:string,timestamp:long)的数据,我们需要把这些数据写入名为"output_table"的MySQL表......
  • [AIGC] mac os 中 .DS_Store 是什么
    .DS_Store是在MacOS系统中由Finder应用程序创建和维护的一种隐藏文件,用于保存有关其所在目录的自定义属性,例如图标位置或背景颜色。“.DS_Store”是“DesktopServicesStore”的缩写。.DS_Store的作用.DS_Store文件在每个MacOSX文件夹中都存在,用于储存这......
  • have my hair cut
    标题致敬传奇抗压王裤子。今天去剪了头发。体验很好,老师帅。但是还是一直很不安我们i人剪了头发是这样的剪头发不是换发型但大概率得换而且很快会剪短乌龟的壳换了形状或是变薄肯定不安一直觉得理发师是个很好的职业与头脑有关又是纯技术活脑袋是用来思想的地方我......
  • Codeforces Round 947 (Div. 1 + Div. 2) E. Chain Queries
    本来决定开摆养生不打的,但11点半的时候点进去看到这个题是个疑似DS,写题的欲望瞬间高涨,然后就40min写了这个题然而赛中并不能提交,只好等到第二天早上再交一发,没想到还WA了一发才过首先这题如果我们能确定当前黑色点集的链的两个端点\(x,y\)的话,这个题就非常显然了只需要求出\((x......