当前位置: 首页 > news >正文

网站优化长沙正规代加工项目

网站优化长沙,正规代加工项目,公司网页设计业务介绍,郴州市官网一、python环境 相关库版本信息 代码运行在 conda 创建的python环境下#xff0c;python和相关库的版本信息如下#xff1a; $ python --version Python 3.12.3$ pip list | grep langchain langchain 0.3.15 langchain-community 0.3.15 lang…一、python环境 相关库版本信息 代码运行在 conda 创建的python环境下python和相关库的版本信息如下 $ python --version Python 3.12.3$ pip list | grep langchain langchain 0.3.15 langchain-community 0.3.15 langchain-core 0.3.31 langchain-groq 0.2.3 langchain-text-splitters 0.3.5 langgraph 0.2.64 langgraph-checkpoint 2.0.10 langgraph-sdk 0.1.51 langsmith 0.2.11导入需要用的库 import os import json from langchain_community.tools.tavily_search import TavilySearchResults from typing import Annotated from typing_extensions import TypedDict from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages from langchain_groq import ChatGroq from langchain_core.messages import ToolMessage(若不确定相关库是否有缺失可以先运行根据库缺失等报错信息进行 pip install) 安装 langchain pip install langchain 安装 langgraph pip install -U langgraph 安装 langchain-groq pip install langchain-groq 二、申请 API Key 本次代码运行需要用到三个不同的 API Key GROQ_API_KEY用于借助groq云平台实现高效LLM推理申请页面TAVILY_API_KEY专为大型语言模型LLMs和检索增强生成RAG应用设计的搜索引擎在本次代码示例中作为LLM可使用的Tool获取页面LANGCHAIN_API_KEY为了使用LangSmith需要用到LangSmith可以帮助我们清晰直观地跟踪搭建的LangGraph的每一次状态变化过程申请页面 获取完以上 API Key 之后可以将它们统一放在代码同级的 .env 文件中进行管理并使用 python-dotenv 库在运行时加载这些环境变量。因为我使用该方法时有点问题所以我还是直接把环境变量写在代码里了。 因为我们要使用LangSmith用于调试和跟踪涉及到另外一个环境变量 LANGCHAIN_TRACING_V2默认为 false设置为 true 就可以开启跟踪功能。 os.environ[TAVILY_API_KEY] TAVILY_API_KEY os.environ[LANGCHAIN_API_KEY] LANGCHAIN_API_KEY # Get this from smith.langchain.com os.environ[LANGCHAIN_TRACING_V2] true os.environ[GROQ_API_KEY] GROQ_API_KEY三、Graph功能描述 Graph图如下所示 我们主要想实现的功能就是用户可以不断提问LLM将根据用户提问内容判断是否需要使用作为外部搜索引擎的tavily API服务获取更多信息若需要则结合这些信息对用户提问做出回答。 Graph处理逻辑流程描述 用户输入问题chatbot 节点接收用户输入并更新 Graph 的状态信息通过 conditional edge根据相应的代码逻辑判断 Graph 的下一步操作决定是进入 tools 节点调用工具还是直接跳转至 END 节点结束流程如果进入 tools 节点则执行工具调用逻辑通过调用 Tavily API 服务进行联网检索。在获取返回结果后更新 Graph 的状态信息然后通过与 chatbot 节点之间的有向边返回 chatbotchatbot 接收更新后的状态信息作为 LLM 的输入进行推理。如果推理结果不需要再次调用工具则通过 conditional edge 判断后直接进入 END 节点否则继续执行直到流程到达 END 节点完成一次 Graph 的迭代。 四、核心代码详解 以下代码全部来自 Langgraph 官方教程文档 。 1. 定义用于保存graph状态的数据结构 首先创建一个继承自 TypedDict 类的子类 State且 State 类定义了一个 messages 键用于定义描述graph状态的数据结构。messages 键的类型被指定为 list意味着该键的值是一个列表用于存储Graph状态变化时产生的消息。Annotated 则是用来为 messages 类型列表添加额外的元数据 add_messages以此控制 messages 键的列表值的更新方式为追加而不是默认的覆盖。即当graph的状态也就是消息列表被更新时上一次的消息列表不会被新产生的消息列表所覆盖而是会将新消息追加到上一次的消息列表中以达到每一次graph流迭代时所有产生的状态都会保存在消息列表中。 # 定义状态 class State(TypedDict):# Messages have the type list. The add_messages function# in the annotation defines how this state key should be updated# (in this case, it appends messages to the list, rather than overwriting them)messages: Annotated[list, add_messages]2. 定义 tool 节点 2.1 创建工具列表 # 创建tavily搜索引擎工具max_results用来设置返回检索结果的数量 tool TavilySearchResults(max_results2) # 放入列表中 tools [tool]2.2 定义tool节点类 该类的主要作用是执行上一个 AI 消息中请求的工具并返回执行结果。 class BasicToolNode:A node that runs the tools requested in the last AIMessage.def __init__(self, tools: list) - None:self.tools_by_name {tool.name: tool for tool in tools}def __call__(self, inputs: dict):if messages : inputs.get(messages, []):message messages[-1]else:raise ValueError(No message found in input)outputs []for tool_call in message.tool_calls:tool_result self.tools_by_name[tool_call[name]].invoke(tool_call[args])outputs.append(ToolMessage(contentjson.dumps(tool_result),nametool_call[name],tool_call_idtool_call[id],))return {messages: outputs}更为详细的代码解释如下ChatGPT生成 BasicToolNode 类是一个工具节点它的主要作用是执行上一个 AI 消息中请求的工具并返回执行结果。下面是对类中每个部分的详细解释 类的总体作用该类的核心功能是接收输入信息通常是包含工具请求的消息找到对应的工具执行工具然后将执行结果以消息的形式返回。它主要处理与工具相关的操作通过调用不同的工具来完成任务。 __init__ 方法 构造函数 __init__(self, tools: list) 用于初始化 BasicToolNode 实例。tools: list 是传递给该类的一个工具列表。每个工具都有一个 name 属性工具的名称并且可以通过 invoke() 方法被调用。self.tools_by_name 是一个字典将工具名称与工具对象映射在一起方便后续根据名称快速查找对应的工具。 self.tools_by_name {tool.name: tool for tool in tools}例如如果有一个名为 calculator 的工具它就会被存储为 {calculator: calculator}以便根据名称查找工具并调用。 __call__ 方法 该方法允许将类实例当作函数来调用。接收一个字典 inputs 作为参数执行工具请求并返回工具执行结果。 具体流程如下 一、获取消息 if messages : inputs.get(messages, []):message messages[-1] else:raise ValueError(No message found in input)首先检查 inputs 字典中是否有键 messages。如果存在则提取 messages 列表的最后一条消息即最近的一条 AIMessage。如果找不到消息则抛出错误 ValueError(No message found in input)防止后续操作出错。 二、执行工具请求 for tool_call in message.tool_calls:tool_result self.tools_by_name[tool_call[name]].invoke(tool_call[args])该消息包含了 tool_calls即消息中请求的工具列表。tool_calls 列表中的每一项代表一次工具调用里面有工具名称 name 和调用参数 args。根据工具名称 tool_call[name]从 self.tools_by_name 中找到相应的工具并调用它的 invoke 方法将调用参数 args 传递给工具。 三、保存工具执行结果 outputs.append(ToolMessage(contentjson.dumps(tool_result),nametool_call[name],tool_call_idtool_call[id],) )工具执行完成后将结果存储到 outputs 列表中。每个执行结果通过 ToolMessage 封装包含以下内容 content工具的执行结果使用 json.dumps() 将其转换为 JSON 格式。name工具名称用于标识是哪一个工具产生的结果。tool_call_id工具调用的唯一 ID用于追踪工具调用。 四、返回结果 return {messages: outputs}最后返回一个字典 {messages: outputs}其中 messages 是包含所有工具执行结果的列表。 总结 BasicToolNode 类的作用是接收带有工具请求的消息提取出工具请求后调用相应的工具执行操作并将执行结果打包为消息返回。它可以被视为一个工具执行器自动根据消息中的请求调用工具并返回相应的结果。 2.3 创建 tool 节点类的对象 # define a tool node tool_node BasicToolNode(toolstools)3. 定义 chatbot 节点 3.1 创建绑定工具列表的LLM 使用的模型是 mixtral-8x7b-32768如果想尝试其他模型可以在 Groq 官网提供的模型列表 中进行选择。llm 调用的 bind_tools() 函数是可以将一组工具与 llm 进行绑定关联以此扩展语言模型的功能使llm 在对话或推理过程中可以根据上下文选择合适的工具并调用它们。 llm ChatGroq(temperature0.8, model_namemixtral-8x7b-32768) llm_with_tools llm.bind_tools(tools)3.2 定义 chatbot 节点 chatbot 节点的定义比较简洁就是一个调用LLM进行推理并将生成内容以State数据格式返回的函数。 def chatbot(state: State):llm_response llm_with_tools.invoke(state[messages])return {messages: [llm_response]}4. 定义 conditional edge 当graph流走到chatbot节点并执行完成后将根据 route_tools 函数作为conditional edge决定下一步去向。 def route_tools(state: State, ):Use in the conditional_edge to route to the ToolNode if the last messagehas tool calls. Otherwise, route to the end.if isinstance(state, list):ai_message state[-1]elif messages : state.get(messages, []):ai_message messages[-1]else:raise ValueError(fNo messages found in input state to tool_edge: {state})if hasattr(ai_message, tool_calls) and len(ai_message.tool_calls) 0:return toolsreturn END更为详细的代码解释如下ChatGPT生成 route_tools 函数的作用是决定工作流的路由方向当收到一条消息时检查其中是否有工具调用tool_calls。如果有工具调用路由到工具节点否则路由到结束END。 一、函数参数: state: State传递进来的 state 是一个状态对象通常包含有关当前对话或任务的上下文信息尤其是消息历史等。这个 state 可以是一个 list 或者是一个包含 messages 的字典。 二、函数逻辑概述: 该函数首先尝试从 state 中提取最近的一条消息ai_message。然后检查该消息是否包含工具调用tool_calls。如果发现有工具调用则返回 tools表示应该转到工具节点执行工具如果没有工具调用则返回 END表示任务已完成或不需要调用工具。 三、详细解释: 从 state 提取最近的消息 if isinstance(state, list):ai_message state[-1] elif messages : state.get(messages, []):ai_message messages[-1] else:raise ValueError(fNo messages found in input state to tool_edge: {state})首先检查 state 是否是一个列表。如果是列表直接取 state 的最后一个元素作为最近的消息ai_message state[-1]。如果 state 不是列表则假定它是一个字典并尝试获取键 messages 对应的消息列表messages : state.get(messages, [])同样从中提取最后一条消息 messages[-1]。如果 state 既不是列表也没有包含消息列表则抛出一个错误提示找不到有效的消息。 检查消息是否包含工具调用 if hasattr(ai_message, tool_calls) and len(ai_message.tool_calls) 0:return tools return END一旦成功提取到 ai_message该部分逻辑检查这条消息中是否有 tool_calls 属性。如果消息中包含 tool_calls 属性并且它的长度大于 0即有工具请求则函数返回 tools表示将工作流引导至工具节点执行工具。如果没有工具调用函数返回 END表示流程可以结束或不需要再进行工具调用。 route_tools 的主要功能是根据对话状态中的最后一条消息检查是否存在工具调用并动态路由到相应的节点。有工具调用时路由到工具节点执行工具没有工具调用时路由到结束节点表示任务不需要进一步的工具执行。 5. 创建并编译状态图 在定义好状态图所需的chatbot和tool这两个节点以及路由到下一个节点的condition edge函数后我们来构建Graph代码注释由 ChatGPT 生成。 # 创建一个状态图对象初始状态为 State 类型 graph_builder StateGraph(State)# 在状态图中添加一个 chatbot 节点 graph_builder.add_node(chatbot, chatbot) # 在状态图中添加一个 tools 节点表示调用工具的节点 graph_builder.add_node(tools, tool_node)# 定义初始边状态图开始时进入 chatbot 节点 graph_builder.add_edge(START, chatbot) # 在聊天机器人节点设置条件边根据不同条件决定路由 graph_builder.add_conditional_edges(chatbot, # 源节点聊天机器人节点route_tools, # 条件函数用于判断是否需要调用工具{ # 条件函数的返回值与目标节点的映射tools: tools, # 如果 route_tools 返回 tools跳转到工具节点END: END # 如果 route_tools 返回 END表示结束流程} ) # 定义一个边当工具节点完成任务后返回到 chatbot 节点以决定下一步操作 graph_builder.add_edge(tools, chatbot)# 编译状态图将节点、边和条件函数转换成可执行的状态机 graph graph_builder.compile()6. 用户无限问答实现 最后我们来实现上一次构建并编译好的graph的运行。 6.1 定义推理函数 stream_graph_updates 函数的主要作用是基于用户输入通过状态图graph进行推理并实时输出 AI 助手的对话回应以实现一种流式对话交互的效果代码注释由 ChatGPT 生成。 def stream_graph_updates(user_input: str):根据用户输入更新对话状态并实时流式输出 AI 助手的回应。参数:user_input (str): 用户输入的消息内容作为对话的开始。返回:None: 通过打印助手的响应实时输出消息。# 调用状态图的 stream 方法将用户输入传递给图进行处理并获取对话事件的流式更新for event in graph.stream({messages: [{role: user, content: user_input}]}):# 遍历每个事件中的所有值。一个事件可能包含多个值例如多个工具调用或消息for value in event.values():# 取出最新一条助手的回复消息并输出内容# messages 是一个列表[-1] 表示列表中的最后一条消息最新消息# content 是消息的实际文本内容print(Assistant:, value[messages][-1].content)6.2 实现用户无限输入模式 我们可以让这个对话无限进行下去只到用户输入 “quit”, “exit”, “q” 中的任何一个字符串以终止对话。 while True:try:user_input input(User: )if user_input.lower() in [quit, exit, q]:print(Goodbye!)breakstream_graph_updates(user_input)except:# fallback if input() is not availableuser_input What do you know about LangGraph?print(User: user_input)stream_graph_updates(user_input)break五、效果演示 因为 stream_graph_updates 做了循环打印所以每到一个节点产生的新的message都会被打印出来。 User: 英伟达现在的股价是多少 Assistant: Assistant: [{url: https://companiesmarketcap.com/nvidia/marketcap/, content: Market cap history of NVIDIA from 2001 to 2023\nEnd of year Market Cap\nEnd of Day market cap according to different sources\nOn Dec 16th, 2023 the market cap of NVIDIA was reported to be:\nMarket capitalization for similar companies or competitors\nThe market capitalization sometimes referred as Marketcap, is the value of a publicly listed company.\n The market capitalization, commonly called market cap, is the total market value of a publicly traded companys outstanding shares and is commonly used to measure how much a company is worth.\n Market capitalization of NVIDIA (NVDA)\nMarket cap: $1.207 Trillion\nAs of December 2023 NVIDIA has a market cap of $1.207 Trillion.\n CompaniesMarketCap is receiving financial compensation for Delta App installs.\nCompaniesMarketCap is not associated in any way with CoinMarketCap.com\nStock prices are delayed, the delay can range from a few minutes to several hours.\n In January 1999, Nvidia was included in the NASDAQ (NVDA) and delivered the ten millionth graphics chip in the same year.}, {url: https://stockanalysis.com/stocks/nvda/market-cap/, content: NVIDIA has a market cap or net worth of $3.37 trillion as of January 17, 2025. Its market cap has increased by 187.03% in one year. Market Cap 3.37T. Enterprise Value ... Market capitalization, also called net worth, is the total value of all of a companys outstanding shares. It is calculated by multiplying the stock price by the number of}] Assistant: Nvidias market cap was reported to be $1.207 trillion on December 16th, 2023, according to CompaniesMarketCap. However, as of January 17, 2025, NVIDIA has a market cap or net worth of $3.37 trillion, according to StockAnalysis. Therefore, the market cap of NVIDIA has significantly increased by 187.03% in one year.我们最终要看的是最后一个输出内容这是 LLM 基于tavily搜索引擎工具拿到的返回内容生成的回复。(根据回复内容可以看出tavily索引到的结果也不是那么实时) Assistant: Nvidias market cap was reported to be $1.207 trillion on December 16th, 2023, according to CompaniesMarketCap. However, as of January 17, 2025, NVIDIA has a market cap or net worth of $3.37 trillion, according to StockAnalysis. Therefore, the market cap of NVIDIA has significantly increased by 187.03% in one year.相关阅读 [1] 又一AI搜索引擎开源了 以上就是本篇博客全部内容大家一起玩起来吧用 LangGraph 开发出更多有趣实用的LLM智能体。 PS关于 LangSmith 的使用我将在后续的博客中介绍大家感兴趣可以自行了解或关注follow后续更新。
http://www.w-s-a.com/news/985752/

相关文章:

  • 建什么类型的网站访问量比较大哪些外包公司比较好
  • php网站地图外贸建站哪家强外贸网站怎么做
  • 宁波五金网站建设中国建筑网官网投诉查询
  • 哪个网站注册域名便宜免费流程图制作网站
  • 潍坊做网站南宁网站seo优化公司
  • 网站建设的基本技术步骤无网站营销
  • 我国旅游网站的建设网站开发 混合式 数据库
  • 淘宝客网站域名家居网站开发项目计划书
  • 网站打不开显示asp苏州注册公司需要多少钱
  • 凡科建站登录官网wordpress主题有什么用
  • 西安双语网站建设怎么做网页动图
  • 宝安自适应网站建设无锡新区企业网站推广
  • 肇庆建设局网站cpanel 安装wordpress
  • 长春启做网站多少怎样换wordpress域名
  • 山西网站建设情况汇总vs2010 c 建设网站
  • 网站推广策划书 精品深圳市住建局和建设局官网
  • 住房和城乡建设部干部学院网站一般做公司网站需要哪几点
  • 网站制作流程详解(学做网站第一步)免费个人网站模版ps
  • 狮山网站建设公司微信平台软件开发
  • 绥芬河网站建设学网站开发的能找什么工作
  • 网站域名申请之后如何做网站微信公众号网页版登录入口
  • 网站优化图片省级精品课程网站
  • 婚纱摄影的网站模板怎么做网站自己当站长
  • 江西建设部网站wordpress弹出式广告
  • 工商年检在哪个网站做中国建设银行个人登录
  • seo做网站郑州巩义网站建设
  • 建设银行网站机构特点业务发展网站推广工作计划
  • 国家信用信息系统年报seo推广赚钱
  • 公司建设网站价格表广州免费拍卖公司
  • 知行网站建设wordpress文章半透明