耶耶耶耶耶 发表于 2024-11-1 22:33:38

生产级AI智能体开发实践【观光规划】

在我最近的博客文章《使用 LangChain 代理创建多模式聊天机器人的开发人员指南》中,讨论了 AI 代理的作用,并演示了使用 LangChain 框架的实现。虽然它适用于概念验证 (POC),但它不恰当生产情况。
在这篇文章中,我将提供一种更恰当生产级产品的解决方案。你将学习如何创建一个可扩展、高效的系统,该系统更恰当实际应用,为你提供构建更强大的 AI 解决方案的工具。
https://i-blog.csdnimg.cn/direct/9159cdf836774a68bf147d1de3d39656.png
   NSDT工具保举: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - AI模型在线查看 - Three.js假造轴心开发包 - 3D模型在线减面 - STL模型在线切割 - 3D道路快速建模 
1、生产情况中 LangChain 代理面临的挑战

LangChain 代理面临的重要挑战是,它们通过一个大型提示将完全控制权授予单个 LLM,该提示管理整个工作流程。在生产情况中,通常需要更精细的控制,尤其是在任务发展时。
那么,我们如何才气最好地将流程分别为更小、更集中的提示,每个提示负责任务的特定部分?我在本文中讨论的这种方法使调试和微调流程中的每个单独组件变得更加容易。别的,没有一个 LLM 可以完善完成每项任务。通常,将流程分别为较小的任务并为每个任务分配最合适的 LLM 会更好,从而优化性能和成本。
2、LangGraph 如何构建可用于生产的系统

这就是 LangGraph 库的作用地点。它提供对代理流程和状态的细粒度控制,这对于构建强大的可用于生产的系统至关重要。LangGraph 通过使用循环图启用有状态、多到场者应用程序来扩展 LangChain,从而更轻松地构建复杂、可靠的代理运行时。
LangGraph 的重要关键功能包罗:


[*]循环和分支。在您的应用程序中实现循环和条件。在 LangGraph 中,每个节点代表一个 LLM 代理,边缘是这些代理之间的通信渠道。这种结构允许清楚且易于管理的工作流程,其中每个代理执行特定任务并根据需要将信息传递给其他代理。
[*]持久状态管理。在图表中的每个步骤之后自动生存状态。可随时暂停和规复图形执行,以支持错误规复、人机交互工作流、时间观光等。
[*]人机交互。停止图形执行,并让用户选择批准或编辑代理计划的以下操纵。
流式传输支持。流式传输每个节点生成的输出(包罗令牌流式传输)。
[*]与 LangChain 和 LangSmith 集成:LangGraph 与 LangChain 和 LangSmith 无缝集成(但不需要它们)。
3、我开发了什么?

我构建了一个应用程序,可资助您规划下一次假期或商务观光。输入提示,应用程序会获取实时航班和酒店选项,并将其显示在用户友好的网页上。如果需要,您也可以通过电子邮件发送此信息。
你可以在 Github 存储库中找到完整代码。
AI 观光社使用两个重要工具:


[*]与 Google Flights API 交互的工具。
[*]与 Google Hotels API 交互的工具。
别的,该应用程序使用 SendGrid API 发送电子邮件。
4、运行应用程序

比方,如果你输入以下提示:
I want to travel to Amsterdam from Madrid from 1 to 7 of October, find me flights and 4-star hotels. 该应用程序根据实时数据提供相关的航班和酒店选项:

https://img-blog.csdnimg.cn/img_convert/42d2fac3bcd7a0f634ea016319b19e1b.png
你将收到包罗徽标和链接的输出,以便于参考。
留意:结果来自 Google Flights 和 Google Hotels API,无意宣传任何特定品牌。

https://img-blog.csdnimg.cn/img_convert/1a47e10859a6cc8865dd83beea1306a6.png
尚有一个选项是通过电子邮件发送所有观光数据。我将在技术部分解释如何实现此功能(提示:它涉及人机交互功能)。

https://img-blog.csdnimg.cn/img_convert/2fa1fabe37b127f3b424b5a784dc89c3.png
哦,太好了,我把所有的观光数据都以 HTML 格式显示在一封电子邮件中:

https://img-blog.csdnimg.cn/img_convert/6e6338ae2bb614f48df412f2f30854ca.png

https://img-blog.csdnimg.cn/img_convert/d8f2d0e413d66923e4a9ffd3b0cfc660.png
5、代理如何处理观光请求?


https://img-blog.csdnimg.cn/img_convert/7911e078333748d673b456eb84799c21.png
让我们通过几个简单的步骤来分析 AI 代理如何处理用户的观光请求。假设用户输入以下提示:
“I want to travel to Amsterdam from Madrid from 1 to 7 of October, find me flights and 4-star hotels.” 接下来会发生什么:
1)用户请求发送到 AI (LLM)
请求被发送到支持工具使用的强大语言模型 (LLM)。LLM 识别请求中的两个任务:查找航班和酒店。
2)任务细分
LLM 将请求分解为两个较小的任务:


[*]查找航班:系统使用专门设计用于搜索航班的工具。
[*]查找酒店:系统还调用一个可资助查找阿姆斯特丹四星级酒店的工具。
3)激活工具
代理调用这些工具,提供准确的数据(如日期、位置等)作为参数。每个工具都会运行并以结构化格式输出航班和酒店选项。
4)处理结果
再次调用 LLM 来汇总结果并以易于阅读的格式出现。
5)电子邮件选项
然后为用户提供通过电子邮件发送此信息的选项。如果用户决定通过电子邮件发送,他们会在表单中输入详细信息(如收件人的电子邮件)。
6)电子邮件发送和流程竣事
使用之前收集的数据,代理从停止的地方继续。它调用电子邮件发送功能,将信息发送到提供的电子邮件地点。
发送电子邮件后,代理完成其任务,完成流程。
6、如何实现这种类型的代理

首先将图可视化。
使用以下代码生成 Mermaid 编辑器的输入:
print(self.graph.get_graph().draw_mermaid()) 要可视化图,请从此代码中获取输出并将其输入到在线 Mermaid 编辑器中。请留意,确切的可视化效果大概会因您使用的 LangGraph 版本而略有不同。

https://img-blog.csdnimg.cn/img_convert/087c413d613e533362f9dbdd7de5d227.png
下面的代码片段定义了一个实现代理的类,该类负责使用语言模型(LLM)管理任务和调用工具。
TOOLS =

class AgentState(TypedDict):
    messages: Annotated, operator.add]

class Agent:

    def __init__(self):
      self._tools = {t.name: t for t in TOOLS}
      self._tools_llm = ChatOpenAI(model='gpt-4o').bind_tools(TOOLS)

      builder = StateGraph(AgentState)
      builder.add_node('call_tools_llm', self.call_tools_llm)
      builder.add_node('invoke_tools', self.invoke_tools)
      builder.add_node('email_sender', self.email_sender)
      builder.set_entry_point('call_tools_llm')

      builder.add_conditional_edges('call_tools_llm', Agent.exists_action, {'more_tools': 'invoke_tools', 'email_sender': 'email_sender'})
      builder.add_edge('invoke_tools', 'call_tools_llm')
      builder.add_edge('email_sender', END)
      memory = MemorySaver()
      self.graph = builder.compile(checkpointer=memory, interrupt_before=['email_sender'])

      print(self.graph.get_graph().draw_mermaid())

    @staticmethod
    def exists_action(state: AgentState):
      result = state['messages'][-1]
      if len(result.tool_calls) == 0:
            return 'email_sender'
      return 'more_tools'

    def email_sender(self, state: AgentState):
      print('Sending email')
      email_llm = ChatOpenAI(model='gpt-4o', temperature=0.1)# Instantiate another LLM
      email_message = [-1].content)]
      email_response = email_llm.invoke(email_message)
      print('Email content:', email_response.content)

      message = Mail(from_email=os.environ['FROM_EMAIL'], to_emails=os.environ['TO_EMAIL'], subject=os.environ['EMAIL_SUBJECT'],
                     html_content=email_response.content)
      try:
            sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
            response = sg.send(message)
            print(response.status_code)
            print(response.body)
            print(response.headers)
      except Exception as e:
            print(str(e))

    def call_tools_llm(self, state: AgentState):
      messages = state['messages']
      messages = + messages
      message = self._tools_llm.invoke(messages)
      return {'messages': }

    def invoke_tools(self, state: AgentState):
      tool_calls = state['messages'][-1].tool_calls
      results = []
      for t in tool_calls:
            print(f'Calling: {t}')
            if not t['name'] in self._tools:# check for bad tool name from LLM
                print('\n ....bad tool name....')
                result = 'bad tool name, retry'# instruct LLM to retry if bad
            else:
                result = self._tools].invoke(t['args'])
            results.append(ToolMessage(tool_call_id=t['id'], name=t['name'], content=str(result)))
      print('Back to the model!')
      return {'messages': results} 7、实现代码的关键概念

让我们分解一下所提供代码的关键概念:
1)工具设置
变量 TOOLS 包罗代理可以使用的工具列表,比方 flights_finder 和 hotels_finder。这些工具代表代理可以执行的操纵,以帮助用户。我在之前的帖子中详细阐述了如何实现此类工具。
2)AgentState
AgentState 是一种以消息对象情势生存代理当前状态的状态。此列表存储代理与用户或工具之间交换的所有通信(消息)。
使用 operator.add 按顺序添加每条消息,这意味着随着对话的举行,新信息将附加到现有消息中。
3)Agent 类
Agent 类通过调用工具、处理用户输入和管理工作流来控制代理的运行方式。它设置了一个 StateGraph,这本质上是任务(或节点)如何连接和执行的蓝图。
4)初始化( __init__ 方法)
绑定工具:


[*]工具被组织成一个字典,每个工具都可以通过名称访问。
[*]代理还将这些工具绑定到语言模型 (LLM),特殊是 ChatOpenAI,以便模型可以根据用户输入决定调用哪个工具。
构建 StateGraph:
代理创建一个 StateGraph,它定义了代理将遵循的操纵流程。在 LangGraph 术语中,这是一个图,其中代理流程中的每个步骤都由一个节点表现(比方,调用工具、调用它们或发送电子邮件)。
StateGraph 有三个节点:


[*]call_tools_llm:代理调用 LLM 来根据任务决定使用哪个工具。
[*]invoke_tools:代理激活所选工具来执行特定任务,比方查找航班或酒店。
[*]email_sender:代理通过电子邮件将结果发送给用户。
起始节点是 call_tools_llm。
条件边和转换:
图表具有条件边,这意味着它根据代理的当前状态(即消息)决定下一步要做什么。比方,如果需要更多工具,它会移动到invoke_tools节点。如果不需要更多工具,它会转换到email_sender节点。
内存管理:
代理使用Checkpointer(通过MemorySaver)来生存其进度。这允许代理记着其状态并在停止时规复操纵。
8、决议和操纵方法:

exists_action 方法:
此方法检查状态中的最新消息以确定下一个操纵。如果不再需要工具调用(即消息中没有剩余的工具调用),代理将转换为发送电子邮件。否则,它将继续调用其他工具。在 LangGraph 术语中,此方法充当决议函数,以决定代理下一步应采取哪条路径(边缘)。
email_sender 方法:
此方法处理末了一步,代理发送包罗结果的电子邮件。代理实例化另一个 LLM,以资助根据状态中的末了一条消息起草电子邮件。它使用提示(模板)引导 LLM 生成电子邮件内容。然后使用 SendGridAPIClient 将电子邮件发送给用户。
call_tools_llm 方法:
在此方法中,代理向 LLM 发送消息列表,其中包罗系统消息(预定义的提示,指示 LLM 执行的操纵)和从前的消息。然后,LLM 返回一条新消息,其中包罗有关下一步调用哪个工具的说明。此新消息将添加到状态中。
invoke_tools 方法:
此方法负责根据 LLM 的指令实际调用工具。代理检查状态中的末了一条消息以查找工具调用。它循环遍历这些工具请求,确保工具有用,然后调用相应的工具。工具的结果将作为工具消息返回并附加到状态中。如果请求的工具无效,代理将提示 LLM 重试。
9、重要功能是如何实现的?

   持久状态管理:memory = MemorySaver()
self.graph = builder.compile(checkpointer=memory, interrupt_before=['email_sender']) 代理设计的一个关键部分是它可以或许记着其末了的状态。这由 MemorySaver 管理,它确保如果代理需要暂停和规复(比方,在等待用户决定发送电子邮件时),它会从准确的点开始,而无需重新开始。
在生产中可以使用多种检查点选项,比方 Postgres、MongoDB 和 Redis。
在 app.py(处理 UI 代码)中,会为每个会话生成一个唯一的 thread_id,以维护用户交互的上下文。此 thread_id 会随每次对代理的调用一起传递,确保内存状态在请求之间得到保留。
            # Create a new thread ID
            thread_id = str(uuid.uuid4())
            st.session_state.thread_id = thread_id

            # Create a message from the user input
            messages =
            config = {'configurable': {'thread_id': thread_id}}

            # Invoke the agent
            result = st.session_state.agent.graph.invoke({'messages': messages}, config=config)   人机交互代理允许在关键决议点举行人为干预:决定是否发送包罗收集的观光信息(航班、酒店等)的电子邮件。这是使用人机交互功能举行管理的,该功能会在发送电子邮件之前暂停代理的执行,让用户查看结果并提供必要的输入。
通过在 graph.compile() 函数中传递interrupt_before=[‘email_sender’] 来实现。
一旦用户决定发送电子邮件并提交数据,以下代码就会在 UI 中运行以完成该过程:
def send_email(sender_email, receiver_email, subject, thread_id):
    try:
      populate_envs(sender_email, receiver_email, subject)
      config = {'configurable': {'thread_id': thread_id}}
      st.session_state.agent.graph.invoke(None, config=config)
      st.success('Email sent successfully!')
      # Clear session state
      for key in ['travel_info', 'thread_id']:
            if key in st.session_state:
                del st.session_state   根据代理状态使用多个 LLMLangGraph 的重要优势之一是可以机动地在工作流的不同阶段使用多个 LLM,而不是依靠于单个 LLM 和一个大提示。这允许代理根据当前任务选择最合适的 LLM。比方,您可以使用一个专门用于工具调用和任务处理的 LLM,另一个更恰当生成和格式化 HTML 中的电子邮件内容的 LLM。
   与 LangChain 和 LangSmith 集成将 LangChain 集成到您的应用程序中,可以访问其全面的工具套件,用于使用语言模型构建复杂的模块化工作流。通过利用 LangChain 的功能,您可以轻松地将不同的 LLM、工具和工作流归并到代理的功能中。
要与 LangSmith 集成,只需将这些情况变量添加到您的 .env 文件中:
LANGCHAIN_API_KEY=<langchain_api_key>
LANGCHAIN_TRACING_V2=true
LANGCHAIN_PROJECT=<langchain_project_name> 10、AI 观光代理用例的关键要点

通过将任务分解为更小、更易于管理的组件,LangGraph 可以更轻松地举行调试、在工具和 LLM 集成方面具有机动性,并包罗人机交互。AI 观光代理示例可资助用户找到实时航班和酒店选项,展示了 LangGraph 处理复杂工作流程、利用多种工具和提供电子邮件功能的能力。它还突出了 LangGraph 的重要功能,比方持久状态管理、多步骤工作流程以及与 LangChain 和 LangSmith 的无缝集成,使其成为构建强大的 AI 驱动应用程序的强大框架。
原文链接:观光规划AI代理开发教程 - BimAnt

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 生产级AI智能体开发实践【观光规划】