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

news2024/12/26 23:25:46

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

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

前面已经详细介绍了Promp、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人关注。'}

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

图片

敬请期待下一篇:)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1695653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Centos修改系統語言

一、使用命令行修系统语言 1、显示系统当前语言环 [rootkvm-suma ~]# localectl System Locale: LANGen_US.utf8 VC Keymap: cn X11 Layout: cn 2、查看系统支持字符集 [rootkvm-suma ~]# locale -a 2、设置系统语言环境 [rootkvm-suma ~]# localectl set-locale LANGz…

2024年汉字小达人活动4个多月开赛:18道历年选择题和答案、解析

根据近年的安排,2024年第11届汉字小达人比赛还有4个多月就启动,那么孩子们如何利用这段时间有条不紊地备考呢?我的建议是两手准备:①把小学1-5年级的语文课本上的知识点熟悉,重点是字、词、成语、古诗。②把历年真题刷…

Three.js 研究:2、如何让动画线性运动

1、默认的动画含有加速度并非线性的 制作好的动画很明显是非线性的,这是一个运动环,为了让环运行线性进行如下设置。 2、设置动画成为线性动画

移动端开发 笔记01

目录 01 移动端的概述 02 移动端的视口标签 03 开发中的二倍图 04 流式布局 05 弹性盒子布局 01 移动端的概述 移动端包括:手机 平板 便携式设备 目前主流的移动端开发: 安卓设备 IOS设备 只要移动端支持浏览器 那么就可以使用浏览器开发移动端项目 开发移动端 使用…

如何修复 System has not been booted with systemd 报错信息?

如何修复 System has not been booted with systemd 报错信息? 一、问题描述: 我们在学习 linux 系统时,使用 systemd 命令(比如 sudo systemctl status ssh),可能会遇到一个报错信息: System…

HCIP-Datacom-ARST自选题库__ISIS简答【3道题】

1.IS-1S是链路状态路由协议,便用SPF算法进行路由计算。某园区同时部署了IPv4和IPV6井运行IS-IS实现网络的互联互通,如图所示,该网络IPv4和IPV6开销相同,R1和R4只支持IPV4。缺省情况下,计算形成的IPv6最短路径树中&…

Redis内存回收-内存淘汰策略

LFU的访问次数之所以叫做逻辑访问次数&#xff0c;是因为并不是每次key被访问都计数&#xff0c;而是通过运算&#xff1a; 生成0~1之间的随机数R计算 (旧次数 * lfu_log_factor 1)&#xff0c;记录为P如果 R < P &#xff0c;则计数器 1&#xff0c;且最大不超过255访问…

深度学习设计模式之桥接模式

文章目录 前言一、介绍二、详细分析1.核心组成2.实现步骤3.代码示例4.优缺点优点缺点 5.使用场景 总结 前言 桥接模式是将抽象部分与实现部分分离&#xff0c;使它们都可以独立的变化。 一、介绍 桥接模式是结构型设计模式&#xff0c;主要是将抽象部分与实现部分分离&#x…

老显示器该换了,否则会摧毁你的眼睛~

正文 大家好&#xff0c;我是bug菌~ 今天给大家带来一篇关于程序员护眼的文章&#xff0c;大部分伙计都是敲代码的&#xff0c;即使不是码农&#xff0c;也多半每天要抱着电脑处理各种事务&#xff0c;那么对眼睛来说还是挺大负担的 特别眼睛原本就不好的朋友更加不友好&#x…

[MRCTF2020]Xor

32位程序 主要逻辑 flagMSAWB~FXZ:J:tQJ"N bpdd}8g for i in range(len(flag)):print(chr(ord(flag[i])^i),end)

得帆信息PMO总监李健达受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 上海得帆信息技术有限公司aPaaS业务线副总裁、PMO总监李健达先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“AI时代的PMO工作法”。大会将于6月29-30日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#x…

如何在群晖NAS安装WPS Office并使用公网地址远程访问处理文档表格

前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊如何在群晖NAS安装WPS Office并使用公网地址远程访问处理文档表格&#xff0c;希望大家能觉得实用&#xff01; 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&a…

Manjaro linux install RedisGUI (RedisInsight)亲测2024-5-25

Arch 用户仓库(Arch User Repository)(AUR) 是用户选择 基于 Arch Linux 的系统 的一个主要理由。你可以在 AUR 中访问到大量的附加软件。 (LCTT 译注&#xff1a;AUR 中的 PKGBUILD 均为用户上传且未经审核&#xff0c;使用者需要自负责任&#xff0c;在构建软件包前请注意检…

langchain进阶一:特殊的chain,轻松实现对话,与数据库操作,抽取数据,以及基于本地知识库的问答

特殊的chain langchain中的Chain有很多,能够轻松实现部分需求,极致简化代码,但是实现效果与模型智慧程度有关 会话链 效果与LLMChain大致相同 javascript 复制代码 from langchain.chains import ConversationChain from langchain_community.llms import OpenAI conversat…

CSS语法介绍

文章目录 前言一、CSS引入方式1.行内操作2.内部操作3.外部操作 二、常用选择器1.标签选择器2.类选择器3.id选择器4.群组选择器5.后代选择器 三、字体常用设置1.字体类型2.字体大小3.字体样式4.字体粗细 四、div盒子模型1.盒子边框2.外边距3.内边距4.浮动 综合实战案例 前言 以…

基于PLC的地铁屏蔽门系统设计_kaic

摘 要 可编程序控制器&#xff08;PLC&#xff09;是近年来发展迅速的工业控制装置&#xff0c;它因为具有强大的稳定性、安全性以及维修便利等优点而应用于工业企业各个领域。地铁作为当代一二线城市最重要的公共交通工具&#xff0c;其安全性以及稳定性至关重要。 以PLC为控…

【Java】Sping Boot中使用Javax Bean Validation

目录 Javax Bean Validation在Spring Boot中集成Javax Bean Validation使用案例功能测试配置全局异常处理器重新测试返回特定形式的信息方式一方式二 Javax Bean Validation Javax Bean Validation是Java平台的一项规范&#xff0c;旨在提供一种简单且可扩展的方式来验证Java对…

提示优化 | PhaseEvo:面向大型语言模型的统一上下文提示优化

【摘要】为大型语言模型 (LLM) 制作理想的提示是一项具有挑战性的任务&#xff0c;需要大量资源和专家的人力投入。现有的工作将提示教学和情境学习示例的优化视为不同的问题&#xff0c;导致提示性能不佳。本研究通过建立统一的上下文提示优化框架来解决这一限制&#xff0c;旨…

隐私是建立人工智能信任的关键

微信关注公众号网络研究观获取更多。 谷歌的 Astra 是其首款人工智能代理 谷歌继续将生成式人工智能融入网络安全 云的复杂性是我们这个时代最大的安全威胁 云安全最受关注的问题&#xff1a;人工智能生成的代码 企业可以从人工智能中获得转型利益&#xff0c;但确保“隐…

Linux基础(六):Linux 系统上 C 程序的编译与调试

本篇博客详细分析&#xff0c;Linux平台上C程序的编译过程与调试方法&#xff0c;这也是我们后续程序开发的基础。 目录 一、第一个hello world程序 1.1 创建.c文件 1.2 编译链接 运行可执行程序 二、编译链接过程 2.1 预编译阶段 2.2 编译阶段 2.3 汇编阶段 2.4 链…