LangGraph范式-web

06-01 1293阅读

Web Voyager是一个基于多模态大模型(Multi-modal Agent)的AI Agent,旨在通过浏览器API与网页交互,完成用户提出的任务。其核心功能是根据用户的“问题、图像或请求”(Question, Image, or Request),生成网页操作的“工具响应”(Tool Responses),并最终返回“最终答案”(Final Answer)。

它的工作原理是查看每次轮次带注释的浏览器屏幕截图,然后选择下一步操作。该代理架构是一个基本的推理和行动 (ReAct) 循环。该代理的独特之处在于:

它使用类似标记集的图像注释作为代理的 UI 功能。

它通过使用工具控制鼠标和键盘,在浏览器中实现应用。

整体设计如下所示:

从示意图来看,其流程包括:

  • 输入:用户提供问题、图像或请求。
  • 处理:
    • 多模态Agent(Multi-modal Agent)接收输入,分析网页内容(Webpage Object)。
    • Agent通过工具模式(Tool Modes)生成下一步操作(Type、Scroll、Click、Wait、Jump to Search、GoBack)。
    • 借助浏览器API执行操作,获取新的网页状态。
    • 输出:最终答案。

      LangGraph范式-web

      定义状态(State)

      LangGraph的工作流需要定义一个状态对象,用于在节点之间传递信息。Web Voyager的状态可能包括:

      • 当前网页的截图(base64编码)。
      • 用户的请求。
      • 当前的操作历史(Trajectory)。
      • 工具调用的结果。
        from typing import TypedDict, List
        class WebVoyagerState(TypedDict):
            user_request: str  # 用户的请求
            webpage_screenshot: str  # 当前网页截图(base64编码)
            trajectory: List[str]  # 操作历史
            tool_response: str  # 工具调用的响应
            final_answer: str  # 最终答案
        (3) 定义工具(Tools)

        Web Voyager的核心是工具模式(Tool Modes),包括 Type、Scroll、Click 等操作。这些操作通过浏览器API(如Playwright)实现。

        @tool
        async def click_element(element_id: str) -> str:
            """点击网页中的某个元素"""
            async with async_playwright() as p:
                browser = await p.chromium.launch()
                page = await browser.new_page()
                # 假设已经在某个页面上
                await page.click(f"#{element_id}")
                screenshot = await page.screenshot()
                await browser.close()
                return base64.b64encode(screenshot).decode("utf-8")
        @tool
        async def type_text(text: str, element_id: str) -> str:
            """在网页的某个元素中输入文本"""
            async with async_playwright() as p:
                browser = await p.chromium.launch()
                page = await browser.new_page()
                await page.fill(f"#{element_id}", text)
                screenshot = await page.screenshot()
                await browser.close()
                return base64.b64encode(screenshot).decode("utf-8")
        @tool
        async def scroll_page(direction: str) -> str:
            """滚动网页"""
            async with async_playwright() as p:
                browser = await p.chromium.launch()
                page = await browser.new_page()
                if direction == "down":
                    await page.evaluate("window.scrollBy(0, window.innerHeight)")
                screenshot = await page.screenshot()
                await browser.close()
                return base64.b64encode(screenshot).decode("utf-8")
        # 其他工具:wait、jump_to_search、go_back 等
        (4) 定义多模态Agent

        多模态Agent基于用户请求和网页截图,决定下一步操作。它通常使用一个提示模板(PromptTemplate)来引导模型推理。

        定义提示模板
        prompt = PromptTemplate(
            input_variables=["user_request", "webpage_screenshot", "trajectory"],
            template="""
            你是一个网页导航Agent。用户请求:{user_request}
            当前网页截图(base64编码):{webpage_screenshot}
            操作历史:{trajectory}
            
            基于当前网页状态,决定下一步操作。可能的工具包括:
            - click_element(element_id): 点击某个元素
            - type_text(text, element_id): 输入文本
            - scroll_page(direction): 滚动页面
            - wait(): 等待
            - jump_to_search(): 跳转到搜索
            - go_back(): 返回上一页
            
            返回下一步操作的工具调用,例如:{{"tool": "click_element", "args": {{"element_id": "button1"}}}}
            如果任务已完成,返回最终答案,例如:{{"final_answer": "任务完成"}}
            """
        )
        # 初始化多模态模型
        llm = ChatOpenAI(model="gpt-4o", temperature=0)  # 使用支持多模态的模型
        agent = llm.bind_tools([click_element, type_text, scroll_page])
        (5) 定义LangGraph工作流

        LangGraph的工作流由节点和边组成。Web Voyager可能包含以下节点:

        • agent_node:调用多模态Agent,生成下一步操作。
        • tool_node:执行工具操作,更新网页状态。
        • end_node:输出最终答案。
          定义图
          workflow = StateGraph(WebVoyagerState)
          # 节点:Agent决策
          def agent_node(state: WebVoyagerState) -> WebVoyagerState:
              response = agent.invoke({
                  "user_request": state["user_request"],
                  "webpage_screenshot": state["webpage_screenshot"],
                  "trajectory": state["trajectory"]
              })
              if "final_answer" in response:
                  state["final_answer"] = response["final_answer"]
                  return state
              state["tool_response"] = response
              return state
          # 节点:工具执行
          async def tool_node(state: WebVoyagerState) -> WebVoyagerState:
              tool_call = state["tool_response"]
              tool_name = tool_call["tool"]
              args = tool_call["args"]
              
              if tool_name == "click_element":
                  screenshot = await click_element(args["element_id"])
              elif tool_name == "type_text":
                  screenshot = await type_text(args["text"], args["element_id"])
              elif tool_name == "scroll_page":
                  screenshot = await scroll_page(args["direction"])
              # 其他工具调用...
              
              state["webpage_screenshot"] = screenshot
              state["trajectory"].append(f"执行工具:{tool_name},参数:{args}")
              return state
          # 添加节点
          workflow.add_node("agent", agent_node)
          workflow.add_node("tool", tool_node)
          # 添加边
          workflow.set_entry_point("agent")
          workflow.add_conditional_edges(
              "agent",
              lambda state: "end" if state.get("final_answer") else "tool",
              {"end": END, "tool": "tool"}
          )
          workflow.add_edge("tool", "agent")
          # 编译图
          app = workflow.compile()

          Paragoger衍生者AI训练营

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码