基于LangChain框架如何构建一个Kubernetes的AI Agent

在大模型时代,借助大模型的能力我们可以实现更加智能的应用,本文介绍基于LangChain框架如何构建一个Kubernetes的AI Agent。更多关于大模型的应用开发,可以参考[大模型时代]是一个基于大模型(LLM)的K8s自动运维工具,可以自动诊断问题、管理资源,效果如下:

在这里插入图片描述
Agent是什么

Agent本意是代理人,比如房屋中介,能代替人做部分事情。具体到LLM Agent目前没有一个统一的定义,常翻译为智能体,通常指能够感知环境、**「自动决策」「执行动作」**的智能实体。

下图是一个LLM Agent认可较广的架构: 在这里插入图片描述

LLM Agent可以用公式定义为:

Agent = LLM + Planning + Action + Tools + Memory

智能体能够实现复杂任务的规划,可以借助外部工具执行每一个步骤,根据执行结果不断调整,并将结果记录存储起来,最终完成任务。拆开来看:

  • LLM:LLM作为智能体的**「大脑」**,可以实现任务的规划、根据执行结果进行反思。
  • Tools: 由于LLM本身的局限,借助外部工具赋予智能体**「双手」**,可以根据任务步骤做出行动,如查询天气、执行代码、搜索内容。
  • Memory: 智能体可以**「记忆」**过去的经验,这对学习至关重要,可以根据这些先前的经验调整未来的行动。

借助智能体我们可以实现更加智能化、多步骤的任务,控制流是由LLM制定的,并不是人类经验的硬编码。使用Agent可以实现数据分析、智能个人助手、自动运维工具等。

如何实现Agent

ReAct

Agent的核心是使用LLM的规划、反思能力,开发Agent最常用的设计模式是ReAct(Reasoning + Acting),LLM生成推理轨迹、执行特定动作,然后根据执行结果不断调整计划,最终实现任务。

ReAct很像人类解决问题的过程,首先我们会做一个大体的规划,然后开始实施,根据结果不断调整,从而最终达到目的。

  • Reason Only:典型地如COT(Chain of Thought),无法感知环境,只能解决有限的问题(数学题,简单的逻辑推理)。
  • Act Only:如果只根据规划做出动作,前面步骤的失败会造成整体任务失败。

ReAct结合推理与行动,使得LLM能够根据当前的观察和过去的经历,形成一套行动计划,并在执行过程中不断调整和优化这一计划。通过将决策制定过程分解为一系列可解释的步骤,ReAct增强了系统的透明度和可理解性。

除了ReAct模式外,还有其他诸如Plan & ExecuteMulti-Agents等。

Function Calling

Agent的另一个重点是能够借助工具感知环境,比如借助搜索引擎获取最新数据、通过API来查询所需数据,甚至执行具体命令,借助工具Agent的边界会大大拓宽。

Function Calling是LLM提供一项扩展能力,是指模型在响应用户请求时,可以返回合适的预定义的函数及其参数,目前大部分模型已经支持。

比如可以预定义一个天气函数

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "Get the current weather in a given location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                    "unit": {
                        "type": "string", 
                        "enum": ["celsius", "fahrenheit"]},
                },
                "required": ["location"],
            },
        },   
    }
]

如果询问大模型_北京的天气怎么样_,会返回如下结果:

ChatCompletionMessage(content=None, role='assistant', function_call=FunctionCall(arguments='{\n  "location": "北京"\n}', name='get_current_weather'), tool_calls=None)

有了Function Calling的能力,可以无限扩展LLM。除此之外,我们也可以通过设计Prompt来让大模型返回所需要调用的工具和参数。

LangChain是什么

LangChain是一个开源的大模型应用开发框架,可以帮助开发者快速构建LLM应用。

为什么需要LangChain

有了诸如GPT4这么强大的LLMFunction Calling,为什么我们还需要大模型框架呢?想象以下问题:

  • 我要对接多个大模型怎么办,每个API都不同?
  • 怎么对接各种工具和向量数据库?
  • 输入输出怎么样结构化?
  • 如何组织复杂的LLM调用链?

这便是LangChain存在的价值,通过对接多种LLM、工具,可以方便的开发RAGAgents等大模型应用。

LangChain的缺点

LangChain为了适配各种情景,做了高度抽象,无法满足灵活的定制,而且调试和测试比较困难。对于简单的应用,复杂度较高,对于复杂的应用又缺少生产环境的验证。

构建Agent应用

接下来就是如何构建Agent,主要考虑ReAct的实现、工具,剩下的就交给LangChain了。

我们的目标是实现一个K8s智能运维工具,社区中已经有一些k8s-gptkubectl-ai等K8s生态的AI助手,但都太初级了,需要大量编码或者只能解决非常有限的场景。

Prompt

ReActAgent的灵魂,可以使用Prompt来实现:

prompt = """
You are a Kubernetes expert. A user has asked you a question about a Kubernetes issue they are facing. You need to diagnose the problem and provide a solution.

Answer the following questions as best you can. You have access to the following tools:
{tools}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}].
Action Input: the input to the action
Observation: the result of the action

... (this Thought/Action/Action Input/Observation can repeat N times)

When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:

---
Thought: Do I need to use a tool? No
Final Answer: [your response here]
---

Begin!

Previous conversation history:
{chat_history}

Question: {input}

Thought: {agent_scratchpad}
"""

  • 首先,是一段系统指令,告诉LLM应该扮演一个K8s专家的角色;
  • 其次,说明可以使用的工具集,包含相关参数;
  • 接着,使用ReAct的思想进行思考,通过多次执行Thought/Action/Action Input/Observation
  • 最后,设置中止条件,如果不需要执行工具就结束。

Tools

KubeWizard首先需要执行kubectl命令,定义一个LangChainTool,设置工具的名字、描述、参数等,核心是在_run中调用ShellTool来执行命令,具体定义如下:

class KubeInput(BaseModel):
    """Args for the k8s tool."""

    commands: str = Field(
        ...,
        example="kubectl get pods",
        description="The kubectl/helm related command to run.",
    )
    """ Kubectl commands to run."""

class KubeTool(ShellTool):
    name = "KubeTool"
    """Name of tool."""

    description = "Tool to run k8s related commands(kubectl, helm) on the Kubernetes cluster. The input is the string command to run."
    """Description of tool."""

    args_schema: Type[BaseModel] = KubeInput
    
    def _run(
        self,
        commands: str,
        run_manager: Optional[CallbackManagerForToolRun] = None,
    ) -> str:
        """Run commands and return final output."""
        commands = self._parse_commands(commands)
        return super()._run(commands)

    def _parse_commands(self, commands: str) -> str:
        """Parse commands."""
        return commands.strip().strip('"`')

另外需要获取K8s的最新信息,比如版本、API是否废弃等,就需要有搜索、阅读网页的能力,这里实现了搜索工具与请求工具。

搜索基于DuckDuckGo,API是免费但效果要比GoogleBing差一些,LangChain已经封装好了,可以直接使用

def create_search_tool():
    return DuckDuckGoSearchResults(
        description="""
        Search the web for information on a topic, there are some useful websites for k8s info:
        - https://kubernetes.io/docs/: Official Kubernetes documentation
        - https://kuberentes.io: Kubernetes community site
        - https://github.com/kubernetes/kubernetes: Kubernetes GitHub repository
        """,
        api_wrapper=DuckDuckGoSearchAPIWrapper(
            max_results=10,
            time="y",
            backend="api",
            source="text"
        )
    )

请求使用了BeautifulSouphtml2text来处理网页,如下:

class RequestsGet(RequestsGetTool):
    name = "RequestsGet"
    description = """A portal to the internet. Use this when you need to get specific
    content from a website. Input should be a url (i.e. https://www.kubernetes.io/releases).
    The output will be the text response of the GET request.
    """
    requests_wrapper = TextRequestsWrapper()
    allow_dangerous_requests = True

    parser = HTML2Text()
    parser.ignore_links = True
    parser.ignore_images = True
    parser.ignore_emphasis = True
    parser.ignore_mailto_links = True

    def _run(self, url: str, **kwargs: Any) -> str:
        response = super()._run(url, **kwargs)
        soup = BeautifulSoup(response, 'html.parser')
        for tag in soup(['header', 'footer', 'script', 'styple']):
            tag.decompose()
        data = self.parser.handle(soup.prettify())
        return data

此外,还将Human做为一个特殊工具,如果需要额外信息可以由人工提供,执行危险操作时,需要人类确认。

Agent

LangChain提供了多种Agent类型,如OpenAI ToolsJSON ChatTool Calling等,这里使用ReAct类型。创建过程如下:

# 定义工具
tools = [KubeTool(), KubeToolWithApprove(), human_console_input(), create_search_tool(), RequestsGet(allow_dangerous_requests=True)]
# 设置Prompt
prompt = PromptTemplate.from_template(REACT_PROMPT, tools=tools)

# 默认模型使用的gpt-4o-mini
def __init__(self, llm: BaseChatModel= ChatOpenAI(model="gpt-4o-mini", temperature=0.7), debug_level: Optional[int] = None):
        # 内存来记录会话
        self.memory = ConversationBufferMemory(memory_key="chat_history")

        # 创建agent
        agent = create_react_agent(llm, self.tools, self.prompt)

        verbose = False
        return_intermediate_steps = False
        
        # 创建执行器,最终来调用agent
        self.agent = AgentExecutor(
            name=self.name,
            agent=agent,
            memory=self.memory,
            tools=self.tools,
            return_intermediate_steps=return_intermediate_steps,
            handle_parsing_errors=True,
            verbose=verbose,
        )

使用时,只需要通过invoke函数来传递输入:

    def invoke(self, input: str):
        return self.agent.invoke({
            "input": input,
            "chat_history": self.get_chat_messages(),
        })


然后使用rich库构建了一个交互式终端,可以与KubeWizard交互。

效果

在文章开头提供了[例子]里面,通过创建了一个selector有问题的ServiceKubeWizard通过多次调用KubeTool获取了ServicePodPod/Log信息,最终排查到是selector有问题。并提供了修复方法,由于修复需要修改资源,所以调用KubeToolWithApprove工具请求批准,最终解决了问题,这个过程完整自动化,和我们自己排查轨迹基本一致。非常的Amazing,在之前我们比如把这些思路硬编码才能实现类似的功能。

再来看一个例子,询问_当前集群可升级到的最新patch版本_,别看这个问题简单,如果是你需要几步才能完成这个操作。

kubewizard>: 当前集群可升级到的最新patch版本

> Entering new KubeAgent chain...
To determine the latest patch version that the current Kubernetes cluster can be upgraded to, I can check the current version of the cluster and then look for available updates. 

Action: KubeTool

Action Input: kubectl version --short
Executing command:
 kubectl version --short
error: unknown flag: --short
See 'kubectl version --help' for usage.
I made an error in using the `--short` flag, which is not a valid option for the `kubectl version` command. Instead, I will run it without the flag to get the current version of the Kubernetes cluster.

Action: KubeTool

Action Input: kubectl version
Executing command:
 kubectl version
Client Version: v1.30.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.3
WARNING: version difference between client (1.30) and server (1.28) exceeds the supported minor version skew of +/-1
To find the latest patch version that the current Kubernetes cluster (version 1.28.3) can be upgraded to, I will check the available patch versions for Kubernetes 1.28. 

Action: RequestsGet

Action Input: https://kubernetes.io/releases

The Kubernetes project maintains release branches for the most recent three
...
###  1.28

Latest Release:  1.28.12 (released:  2024-07-16  )
End of Life:  2024-10-28
Patch Releases:  1.28.0  ,  1.28.1  ,  1.28.2  ,  1.28.3  ,  1.28.4  ,  1.28.5
,  1.28.6  ,  1.28.7  ,  1.28.8  ,  1.28.9  ,  1.28.10  ,  1.28.11  ,  1.28.12
...

---
Thought: Do I need to use a tool? No

Final Answer: The latest patch version that your current Kubernetes cluster (version 1.28.3) can be upgraded to is 1.28.12.
---
> Finished chain.


例子中,第一步获取版本信息失败,但第二步经过反思后就获取到版本,再通过RequestTool获取最新的版本信息,从而得到最新的patch版本是1.28.12。为什么这里不用使用搜索就知道需要访问的页面,如果在RequestTool的描述里取代K8s相关页面,就会先调用SearchTool再调用RequestTool

总结

本文介绍了Agent的概念、原理,以及如何通过LangChain来打造一个K8s魔法师自动运维工具[KubeWizard]。

曾几何时,我们也幻想过AI能否替代人类做一部分工作,大模型时代,好像未来并不遥远。展望一下未来,具有意识和情感的智能体有没有可能在不远的将来出现呢。
在这里插入图片描述

大模型&AI产品经理如何学习

求大家的点赞和收藏,我花2万买的大模型学习资料免费共享给你们,来看看有哪些东西。

1.学习路线图

在这里插入图片描述

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己整理的大模型视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

在这里插入图片描述

在这里插入图片描述

(都打包成一块的了,不能一一展开,总共300多集)

因篇幅有限,仅展示部分资料,需要点击下方图片前往获取

3.技术文档和电子书

这里主要整理了大模型相关PDF书籍、行业报告、文档,有几百本,都是目前行业最新的。
在这里插入图片描述

4.LLM面试题和面经合集

这里主要整理了行业目前最新的大模型面试题和各种大厂offer面经合集。
在这里插入图片描述

👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。
在这里插入图片描述

1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

在这里插入图片描述

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值