Langgraph 的 Planning Agent 深度解析

news2024/11/17 1:26:36

        在人工智能领域,智能代理(agent)的设计愈发重要。尤其在面对复杂任务时,规划(planning)技术成为智能代理的核心能力之一。Langgraph 是一个专为构建智能代理而设计的框架,结合了自然语言处理(NLP)与规划技术,旨在帮助开发者快速构建具有语言理解能力和决策能力的智能代理。本文将深入探讨 Langgraph 中的 planning agent,包括其设计理念、核心功能、实际应用及详细的代码示例,帮助开发者全面了解这一强大的工具。

目录

1. Langgraph 简介

1.1 什么是 Langgraph

1.1.1 与其他智能代理框架的比较

1.2 Langgraph 的核心组件

1.2.1 语言理解模块

代码示例:基本的语言理解模型配置

1.2.2 知识库

代码示例:如何创建和查询知识库

1.2.3 规划模块

代码示例:简单的计划生成算法

2. Planning Agent 概述

2.1 什么是 Planning Agent

2.2 Planning Agent 的工作流程

2.2.1 目标识别

代码示例:用户输入的处理

2.2.2 环境感知

代码示例:获取和处理环境数据

2.2.3 计划生成

代码示例:计划生成算法的实现

2.2.4 执行与反馈

代码示例:动态调整计划的实现

3. Langgraph 中的 Planning Agent

3.1 规划模块设计

3.1.1 状态表示

3.1.2 计划生成的核心算法

代码示例:计划生成算法的实现

3.2 规划模块的实现

4. 实际应用案例

4.1 任务管理助手

用户输入示例

代理处理过程

代码示例:任务管理助手

5.完整代码示例

5.1 项目架构

5.2 .env文件配置

5.3 agent.py

5.4 graph.py

 5.5 plan.py

5.6 运行

6. 未来发展方向

结论


1. Langgraph 简介

1.1 什么是 Langgraph

Langgraph 是一个集成化的框架,旨在简化智能代理的开发过程。它通过提供语言理解、知识管理和规划能力,使开发者能够创建能够与用户进行自然语言交流的智能代理。Langgraph 采用模块化设计,使得每个功能组件都可以独立配置和扩展。

1.1.1 与其他智能代理框架的比较

与其他框架(如 Rasa、Dialogflow)相比,Langgraph 强调规划能力的集成。这意味着在 Langgraph 中,开发者不仅可以处理用户的输入,还能为代理生成复杂的行动计划。例如,在 Rasa 中,虽然可以处理对话流,但在执行多个任务时,往往需要额外的逻辑支持。而 Langgraph 的规划模块能够动态生成行动计划,使得智能代理在面对复杂场景时表现得更为灵活。

1.2 Langgraph 的核心组件

Langgraph 的核心组件包括语言理解模块、知识库和规划模块。

1.2.1 语言理解模块

语言理解模块负责解析用户的自然语言输入,将其转化为可供计算机处理的结构化信息。这一模块使用先进的自然语言处理技术,如意图识别和实体抽取,帮助代理理解用户的需求。

功能与实现方式

  • 意图识别:识别用户希望完成的任务,例如“预定酒店”或“查询天气”。
  • 实体抽取:从用户的输入中提取关键信息,例如时间、地点、数量等。
代码示例:基本的语言理解模型配置
from langgraph.nlp import LanguageUnderstandingModel

# 创建语言理解模型
lu_model = LanguageUnderstandingModel()

# 配置模型参数
lu_model.set_intent_recognition(['book_hotel', 'check_weather'])
lu_model.set_entity_extraction(['location', 'date', 'time'])

# 示例输入
user_input = "我想在明天预定一家酒店"
parsed_result = lu_model.parse(user_input)

print(parsed_result)  # 输出:{'intent': 'book_hotel', 'entities': {'date': '明天'}}

1.2.2 知识库

知识库用于存储和管理智能代理所需的知识信息。通过知识图谱的形式,代理能够快速查询相关信息并为用户提供准确的答案。

知识库的结构与管理

  • 知识存储:以图结构存储信息,使得关系查询更加高效。
  • 查询接口:提供灵活的查询接口,支持复杂的知识检索。
代码示例:如何创建和查询知识库
from langgraph.knowledge import KnowledgeBase

# 创建知识库
knowledge_base = KnowledgeBase()

# 添加知识
knowledge_base.add_fact('hotel_in_paris', {'name': '巴黎酒店', 'location': '巴黎', 'rating': 5})
knowledge_base.add_fact('weather_in_paris', {'condition': '晴', 'temperature': '25°C'})

# 查询知识
hotel_info = knowledge_base.query('hotel_in_paris')
print(hotel_info)  # 输出:{'name': '巴黎酒店', 'location': '巴黎', 'rating': 5}
1.2.3 规划模块

规划模块是 Langgraph 的核心,负责根据用户的目标生成相应的行动计划。它结合了多种规划算法,使代理能够根据环境变化实时调整计划。

规划的基本原理

  • 状态表示:定义环境状态和目标的表示方式。
  • 计划生成:根据当前状态和目标生成行动计划。
代码示例:简单的计划生成算法
from langgraph.planning import PlanningAgent

# 创建规划代理
planning_agent = PlanningAgent()

# 设置初始状态和目标
initial_state = {'user_intent': 'book_hotel', 'available_hotels': ['巴黎酒店', '伦敦酒店']}
goal_state = {'action': 'book', 'hotel': '巴黎酒店'}

# 生成计划
plan = planning_agent.generate_plan(initial_state, goal_state)
print(plan)  # 输出:['查询酒店', '确认预定', '发送确认信息']

2. Planning Agent 概述

2.1 什么是 Planning Agent

Planning agent 是一种智能代理,能够根据特定目标生成可执行的行动计划。与传统的基于规则的代理相比,planning agent 具备更高的灵活性和适应性,能够处理复杂的决策和动态环境。

2.2 Planning Agent 的工作流程

Planning agent 的工作流程可以分为以下几个步骤:

  1. 目标识别:解析用户输入,识别需要达成的目标。
  2. 环境感知:收集当前环境状态的信息,包括可用资源和限制条件。
  3. 计划生成:基于目标和环境状态,生成可行的行动计划。
  4. 执行与反馈:执行计划并根据执行结果进行调整。
2.2.1 目标识别

在目标识别阶段,planning agent 解析用户输入,确定用户的意图和期望的目标。这一过程依赖于语言理解模块的准确性。

代码示例:用户输入的处理
user_input = "我想在周末去巴黎旅行"
parsed_input = lu_model.parse(user_input)

# 从解析结果中提取意图
user_intent = parsed_input['intent']
print(user_intent)  # 输出:'book_travel'
2.2.2 环境感知

环境感知阶段,planning agent 收集当前的环境状态信息。这包括可用的资源、外部条件和限制。

代码示例:获取和处理环境数据
# 假设环境数据包含可用酒店和天气信息
environment_data = {
    'available_hotels': ['巴黎酒店', '伦敦酒店'],
    'weather': {'condition': '晴', 'temperature': '25°C'}
}

# 代理收集环境状态
planning_agent.set_environment(environment_data)
2.2.3 计划生成

计划生成是 planning agent 的核心任务。基于目标和当前环境状态,生成一系列可行的行动计划。

代码示例:计划生成算法的实现
# 生成计划
goal_state = {'action': 'book', 'destination': '巴黎'}
plan = planning_agent.generate_plan(environment_data, goal_state)

print(plan)  # 输出:['查询可用酒店', '选择酒店', '确认预定']
2.2.4 执行与反馈

执行阶段,planning agent 根据生成的计划逐步执行,并根据反馈调整计划。例如,如果用户选择了不同的酒店,代理需要实时更新计划。

代码示例:动态调整计划的实现
# 执行第一个行动
action = plan[0]  # '查询可用酒店'
response = execute_action(action)  # 假设这是执行行动的函数

# 根据用户的反馈调整计划
if response == '用户选择了不同的酒店':
    plan = planning_agent.update_plan(new_hotel_choice='伦敦酒店')

3. Langgraph 中的 Planning Agent

3.1 规划模块设计

Langgraph 的规划模块使用多种算法来生成和优化计划。以下是其主要设计思路。

3.1.1 状态表示

规划模块首先需要定义状态表示。状态可以是一个复杂的数据结构,包含当前任务的所有相关信息,例如用户输入、当前环境状态等。

3.1.2 计划生成的核心算法

计划生成采用启发式搜索和图搜索等方法,使得生成的计划更加高效。启发式算法能够通过评估可能的行动,优先考虑最有希望的路径,而图搜索则能够全面探索状态空间。

代码示例:计划生成算法的实现

以下是一个简单的计划生成算法的代码示例:

class PlanningAgent:
    def __init__(self, initial_state, goal_state):
        self.initial_state = initial_state
        self.goal_state = goal_state

    def heuristic(self, state):
        # 计算当前状态与目标状态的差异
        return abs(state - self.goal_state)

    def a_star_search(self):
        open_set = {self.initial_state}
        came_from = {}
        g_score = {self.initial_state: 0}
        f_score = {self.initial_state: self.heuristic(self.initial_state)}

        while open_set:
            current = min(open_set, key=lambda x: f_score.get(x, float('inf')))
            if current == self.goal_state:
                return self.reconstruct_path(came_from, current)

            open_set.remove(current)
            for neighbor in self.get_neighbors(current):
                tentative_g_score = g_score[current] + self.cost(current, neighbor)
                if tentative_g_score < g_score.get(neighbor, float('inf')):
                    came_from[neighbor] = current
                    g_score[neighbor] = tentative_g_score
                    f_score[neighbor] = g_score[neighbor] + self.heuristic(neighbor)
                    open_set.add(neighbor)

        return None  # 如果没有找到路径

    def get_neighbors(self, state):
        # 返回当前状态的邻居状态
        # 这部分逻辑依赖于具体应用
        pass

    def cost(self, current, neighbor):
        # 计算从当前状态到邻居状态的成本
        return 1  # 简化示例,假设每个步骤成本相同

    def reconstruct_path(self, came_from, current):
        total_path = [current]
        while current in came_from:
            current = came_from[current]
            total_path.append(current)
        return total_path[::-1]  # 反转路径

3.2 规划模块的实现

规划模块的实现包含多个步骤,从定义状态到执行计划。开发者可以根据具体需求,定制状态表示、成本函数和邻居生成逻辑。

4. 实际应用案例

4.1 任务管理助手

一个常见的应用场景是任务管理助手。用户可以通过自然语言与代理交互,要求代理为他们安排会议、提醒待办事项等。

用户输入示例
  • “帮我安排一个明天的会议。”
  • “提醒我下午三点开会。”
代理处理过程
  1. 目标识别:解析用户请求,识别出“安排会议”和“设置提醒”。
  2. 环境感知:查询用户日历,确定可用时间。
  3. 计划生成:根据用户的需求生成行动计划,例如在日历中添加事件。
  4. 执行与反馈:执行计划,并向用户反馈结果。

代码示例:任务管理助手

以下是任务管理助手的简单实现:

class TaskManagerAgent(PlanningAgent):
    def __init__(self, initial_state, goal_state, calendar):
        super().__init__(initial_state, goal_state)
        self.calendar = calendar  # 用户的日历

    def identify_goal(self, user_input):
        # 识别用户的目标
        if "安排会议" in user_input:
            return "schedule_meeting"
        elif "提醒我" in user_input:
            return "set_reminder"
        return None

    def execute_task(self, task):
        if task == "schedule_meeting":
            # 具体的安排逻辑
            print("会议已安排在:", self.goal_state)
        elif task == "set_reminder":
            print("提醒已设置在:", self.goal_state)

# 示例用法
calendar = {}  # 用户的日历
task_manager = TaskManagerAgent(initial_state=None, goal_state="2024-09-30 10:00", calendar=calendar)
task_manager.execute_task(task_manager.identify_goal("帮我安排一个明天的会议。"))

5.完整代码示例

根据官方博客:Plan-and-Execute (langchain-ai.github.io)
以及GitHub代码地址:主要的 langgraph/docs/docs/tutorials/plan-and-execute/plan-and-execute.ipynb ·langchain-ai/语言图 ·GitHub的

完整的运行文件如下:

5.1 项目架构

5.2 .env文件配置

OPENAI_API_KEY=sk-proj-tfV9dwAWhKhtI7pjT2U3T3BlbkFJvnYXOW8AHhh3cVgO370I
TAVILY_API_KEY=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
LANGSMITH_API_KEY=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

其中第二个是Tavily搜索的api key,需要创建账号并自己申请;第三个是检控LangChain运行的api key,课查看官方博客了解具体作用。

5.3 agent.py

import os  # 导入操作系统模块

from langchain_core.messages import HumanMessage  # 从 langchain_core 导入 HumanMessage 类

# 设置 API 密钥
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()


from langchain import hub  # 从 langchain 导入 hub 模块
from langchain_openai import ChatOpenAI  # 从 langchain_openai 导入 ChatOpenAI 类
from langgraph.prebuilt import create_react_agent  # 从 langgraph.prebuilt 导入 create_react_agent 函数
from langchain_community.tools.tavily_search import TavilySearchResults  # 从 langchain_community.tools 导入 TavilySearchResults 类

# 创建 LLM 实例
llm = ChatOpenAI(model="gpt-4-turbo-preview")  # 实例化 ChatOpenAI,使用 gpt-4-turbo-preview 模型

# 定义工具,使用 Tavily 搜索工具
tools = [TavilySearchResults(max_results=3)]  # 设置最大结果为 3
search_agent_executor = create_react_agent(llm, tools, state_modifier="你是一个有用的Agent,可以在线搜索")  # 创建代理执行器


# 可选:调用代理并打印响应
# response = search_agent_executor.invoke({"messages": [("user", "who is the winner of the us open")]})  # 调用代理,询问 US Open 胜者
# print(response)  # 打印响应

5.4 graph.py

import asyncio
from typing import Literal
from agent import search_agent_executor
from plan import PlanExecute, replanner, Response, planner
from langgraph.graph import StateGraph, START
# 设置 API 密钥
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()


async def execute_step(state: PlanExecute):
    plan = state["plan"]  # 获取当前的计划
    plan_str = "\n".join(f"{i+1}. {step}" for i, step in enumerate(plan))  # 将计划格式化为字符串
    task = plan[0]  # 获取当前的任务
    task_formatted = f"""For the following plan:
{plan_str}\n\nYou are tasked with executing step {1}, {task}."""  # 构造执行任务的提示
    agent_response = await search_agent_executor.ainvoke(
        {"messages": [("user", task_formatted)]}  # 发送消息给代理执行任务
    )
    return {
        "past_steps": [(task, agent_response["messages"][-1].content)],  # 返回过去的步骤
    }

async def plan_step(state: PlanExecute):
    plan = await planner.ainvoke({"messages": [("user", state["input"])]})  # 调用 planner 获取计划
    return {"plan": plan.steps}  # 返回计划步骤

async def replan_step(state: PlanExecute):
    output = await replanner.ainvoke(state)  # 调用 replanner 进行重新规划
    if isinstance(output.action, Response):  # 如果输出是响应
        return {"response": output.action.response}  # 返回响应
    else:
        return {"plan": output.action.steps}  # 返回新的计划步骤

def should_end(state: PlanExecute) -> Literal["agent", "__end__"]:  # 判断流程是否结束
    if "response" in state and state["response"]:  # 检查是否有响应
        return "__end__"  # 如果有,结束流程
    else:
        return "agent"  # 否则继续代理

# 创建状态图
workflow = StateGraph(PlanExecute)

# 添加计划节点
workflow.add_node("planner", plan_step)

# 添加执行步骤
workflow.add_node("agent", execute_step)

# 添加重新规划节点
workflow.add_node("replan", replan_step)

workflow.add_edge(START, "planner")  # 从起始节点到计划节点

# 从计划节点到执行节点
workflow.add_edge("planner", "agent")

# 从执行节点到重新规划节点
workflow.add_edge("agent", "replan")

workflow.add_conditional_edges("replan", should_end)  # 添加条件边,判断是否结束

# Finally, we compile it!
# This compiles it into a LangChain Runnable,
# meaning you can use it as you would any other runnable
app = workflow.compile()

# 可视化状态图
img_path = "graph.png"
graph_image = app.get_graph(xray=True).draw_mermaid_png()  # 直接获取图像数据

with open(img_path, "wb") as img_file:
    img_file.write(graph_image)  # 保存为文件

from IPython.display import Image, display
display(Image(img_path))  # 读取并显示文件



# 运行应用程序
config = {"recursion_limit": 50}
inputs = {"input": "what is the hometown of the mens 2024 Australia open winner?"}


# 处理事件流
async def main():
    async for event in app.astream(inputs, config=config):
        for k, v in event.items():
            if k != "__end__":
                print(v)


# 运行主程序
if __name__ == "__main__":
    asyncio.run(main())

 5.5 plan.py

# 导入所需的库
import operator
import os
from typing import Annotated, List, Tuple, TypedDict
from langchain_openai import ChatOpenAI  # 导入OpenAI的聊天模型
# 设置 API 密钥
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

# 定义状态类
class PlanExecute(TypedDict):
    input: str  # 用户输入
    plan: List[str]  # 计划的步骤列表
    past_steps: Annotated[List[Tuple], operator.add]  # 已执行的步骤
    response: str  # 最终响应

from pydantic import BaseModel, Field  # 导入Pydantic用于数据模型

# 定义计划模型
class Plan(BaseModel):
    """Plan to follow in future"""  # 用于未来执行的计划

    steps: List[str] = Field(
        description="different steps to follow, should be in sorted order"  # 描述计划的步骤,应该是有序的
    )

from langchain_core.prompts import ChatPromptTemplate  # 导入提示模板

# 定义规划提示模板
planner_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            """For the given objective, come up with a simple step by step plan. \
This plan should involve individual tasks, that if executed correctly will yield the correct answer. Do not add any superfluous steps. \
The result of the final step should be the final answer. Make sure that each step has all the information needed - do not skip steps.""",
        ),
        ("placeholder", "{messages}"),
    ]
)

# 创建规划实例
planner = planner_prompt | ChatOpenAI(
    model="gpt-4o", temperature=0  # 使用OpenAI的GPT模型,设置温度为0以确保一致性
).with_structured_output(Plan)

# 调用规划器生成计划
planner.invoke(
    {
        "messages": [
            ("user", "what is the hometown of the current Australia open winner?")  # 用户询问的问题
        ]
    }
)

# 重新规划部分
from typing import Union  # 导入Union类型

# 定义响应类
class Response(BaseModel):
    """Response to user."""  # 响应用户的类

    response: str  # 响应内容

# 定义动作类
class Act(BaseModel):
    """Action to perform."""  # 要执行的动作类

    action: Union[Response, Plan] = Field(
        description="Action to perform. If you want to respond to user, use Response. "
        "If you need to further use tools to get the answer, use Plan."  # 描述动作的类型
    )


# 定义重新规划的提示模板
replanner_prompt = ChatPromptTemplate.from_template(
    """For the given objective, come up with a simple step by step plan. \
This plan should involve individual tasks, that if executed correctly will yield the correct answer. Do not add any superfluous steps. \
The result of the final step should be the final answer. Make sure that each step has all the information needed - do not skip steps.

Your objective was this:
{input}

Your original plan was this:
{plan}

You have currently done the follow steps:
{past_steps}

Update your plan accordingly. If no more steps are needed and you can return to the user, then respond with that. Otherwise, fill out the plan. Only add steps to the plan that still NEED to be done. Do not return previously done steps as part of the plan."""
)


replanner = replanner_prompt | ChatOpenAI(
    model="gpt-4o", temperature=0
).with_structured_output(Act)

5.6 运行

直接运行graph.py文件就行啦,更改输入也是在graph.py文件中~

6. 未来发展方向

Langgraph 提供了一个强大的框架,用于构建具有规划能力的智能代理。通过灵活的设计和强大的功能,开发者能够快速实现复杂的任务规划。本文详细探讨了 planning agent 的概念、构建过程和实际应用,旨在帮助开发者深入理解这一技术。随着人工智能的持续发展,Langgraph 和 planning agent 也将迎来更多可能,值得持续关注和研究。

结论

Langgraph 的 planning agent 提供了一种强大的方式来构建智能代理。通过有效的规划和动态调整,智能代理能够在复杂的任务中表现出色。本文详细介绍了 Langgraph 的核心组件、规划模块的设计以及实际应用案例,为开发者在构建智能代理时提供了实用的参考。

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

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

相关文章

2024年项目经理不容错过的资源:全面测试管理工具指南与精选实例

随着软件开发的快速发展&#xff0c;测试管理工具在项目经理的日常工作中扮演着越来越重要的角色。2024年&#xff0c;哪些测试管理工具是项目经理不能错过的呢&#xff1f;本文将为您带来一份全面指南&#xff0c;帮助您找到最佳选择。 在软件开发过程中&#xff0c;测试是确保…

鸿蒙开发(NEXT/API 12)【硬件(接入手写套件)】手写功能开发

接入手写套件后&#xff0c;可以在应用中创建手写功能界面。界面包括手写画布和笔刷工具栏两部分&#xff0c;手写画布部分支持手写笔和手指的书写效果绘制&#xff0c;笔刷工具栏部分提供多种笔刷和编辑工具&#xff0c;并支持对手写功能进行设置。接入手写套件后将自动开启一…

机器学习方法实现水果分类(零基础小白向),手工提取水果图片特征,不一样的特征提取方法

文章目录 零、前言&#xff1a;一、什么是特征向量&#xff1f;二、数据准备三、构建数据集1、什么是数据集&#xff1f;2、图片对应的标签&#xff1f;3、特征提取方法&#xff08;1&#xff09;生成固定正方形&#xff08;2&#xff09;特征提取实现 四、建立模型五、自定义数…

【Python】遇见的问题:为项目选择的 Python 解释器无效

一、问题说明 导入项目文件后&#xff0c;提示“为项目选择的 Python 解释器无效” 二、问题原因 暂时不知道 三、解决办法 第一步&#xff1a;添加本地解释器 第二步&#xff1a;点击确定 位置&#xff1a;当前项目所在目录 基础解释器&#xff1a;python.exe所在目录 第三…

五子棋双人对战项目(2)——登录模块

目录 一、数据库模块 1、创建数据库 2、使用MyBatis连接并操作数据库 编写后端数据库代码 二、约定前后端交互接口 三、后端代码编写 文件路径如下&#xff1a; UserAPI&#xff1a; UserMapper&#xff1a; 四、前端代码 登录页面 login.html&#xff1a; 注册页面…

C++语法—引用

引用变量 概念 简单理解就是对一个已存在的变量起别名&#xff0c;与那个已存在的变量共用一块内存空间。 用法&#xff1a;已存在变量的类型 & 引用变量名 &#xff08;引用实体&#xff09;已存在变量 int main() {int a 1;int& b a;return 0; }在上面这个示例…

minio 快速入门+单机部署+集群

目录 原理 概念 名词解释 Set /Drive 的关系 MinIO部署 单机 单机单盘 单机多盘 集群 多机单盘 多机多盘 配置负载均衡 调优 原理 MinIO是一个S3兼容的高性能对象存储&#xff0c;其主要特点如下&#xff1a; 适合存储大容量非结构化的数据&#xff0c;如图片&…

骨传导耳机品牌排行榜分享:360度实测分析10款抢手骨传导耳机!

随着科技的不断进步和人们生活方式的变化&#xff0c;骨传导耳机以其独特的传声方式和开放式设计&#xff0c;逐渐成为运动爱好者、户外活动家以及听力障碍人士的新宠。不同于传统耳机将声音直接导入耳道&#xff0c;骨传导耳机通过振动颅骨将声音传递至内耳&#xff0c;不仅能…

数据结构与算法——Java实现 20.习题——二叉树层序遍历

认真的人改变自己&#xff0c;执着的人改变命运 —— 24.9.27 102. 二叉树的层序遍历 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例 2&#xff1a; 输入&#xff1a;root [1] 输出&#xff1a;[[1]]示例 3&…

Java单体服务和集群分布式SpringCloud微服务的理解

单体应用存在的问题 1.随着业务的发展开发变得越来越复杂。 2.修改或者新增&#xff0c;需要对整个系统进行测试、重新部署。 3.一个模块出现问题&#xff0c;很可能导致整个系统崩溃。 4.多个开发团队同时对数据进行管理&#xff0c;容易产生安全漏洞。 5.各个模块使用同…

Spring Session学习

系列文章目录 JavaSE基础知识、数据类型学习万年历项目代码逻辑训练习题代码逻辑训练习题方法、数组学习图书管理系统项目面向对象编程&#xff1a;封装、继承、多态学习封装继承多态习题常用类、包装类、异常处理机制学习集合学习IO流、多线程学习仓库管理系统JavaSE项目员工…

如何在算家云搭建MVSEP-MDX23(音频分离)

一、MVSEP-MDX23简介 模型GitHub网址&#xff1a;MVSEP-MDX23-music-separation-model/README.md 在 main ZFTurbo/MVSEP-MDX23-音乐分离模型 GitHub 上 在音视频领域&#xff0c;把已经发布的混音歌曲或者音频文件逆向分离一直是世界性的课题。音波混合的物理特性导致在没有…

快消品海外仓应该如何选择合适WMS仓储系统?

快消品的“快”属性天然契合海外仓&#xff0c;快消品大部分是必需品&#xff0c;库存周转快&#xff0c;需保持一定量的安全库存&#xff0c;及时、稳定补货尤为重要&#xff1b;快消品最适合全渠道销售&#xff0c;线上线下等&#xff0c;比较考验备货和统筹能力&#xff1b;…

基于RustDesk自建远程桌面服务

最近向日葵越来越难用了&#xff0c;官方好像限制了免费用户的带宽&#xff0c;但是限制的有点过头了&#xff0c;卡的基本没法用。 向日葵的平替todesk对于免费用户又有时长限制&#xff0c;对于经常用的小伙伴不大友好。 咱也不是说非得白嫖&#xff0c;但是向日葵和todesk这…

观测云链路追踪分析最佳实践

背景 如果要在开发、运维和工程层面持续改进一个涉及多服务的应用&#xff0c;以链路追踪、日志检索、指标收集、用户体验监测、性能剖析、关联分析等作为代表性技术的可观测性必不可少&#xff0c;这一看法已成为共识&#xff0c;但在采用这项技术的过程中&#xff0c;如何分…

msvcr100.dll丢失的解决方法,六种解决msvcr100.dll丢失使用技巧

在使用计算机的过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcr100.dll丢失”。这个问题可能会让我们感到困惑和无助&#xff0c;但是不用担心&#xff0c;本文将为大家介绍六种实用的解决方法&#xff0c;帮助你轻松解决这个问题。 一&#xff…

【JAVA报错已解决】Java.lang.NullPointerException

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

朋友圈信息流广告投放,曝光成本是多少?

微信作为国内最流行的社交平台之一&#xff0c;其朋友圈广告凭借精准的用户画像和强大的社交属性&#xff0c;成为了众多品牌商家进行市场推广的重要渠道。云衔科技推出了专业的微信朋友圈广告开户及代运营服务&#xff0c;旨在帮助企业轻松跨越技术门槛&#xff0c;精准触达目…

【Verilog学习日常】—牛客网刷题—Verilog企业真题—VL64

时钟切换 描述 题目描述&#xff1a; 存在两个同步的倍频时钟clk0 clk1,已知clk0是clk1的二倍频&#xff0c;现在要设计一个切换电路&#xff0c;sel选择时候进行切换&#xff0c;要求没有毛刺。 信号示意图&#xff1a; 波形示意图&#xff1a; 输入描述&#xff1a; …

D20【python接口自动化学习】-python基础之内置数据类型

day20 内置数据类型的常见错误 学习日期&#xff1a;20240927 学习目标&#xff1a;内置数据类型--29 内置数据类型的常见错误 学习笔记&#xff1a; 访问错误 不同数据类型之间的操作报错 解决错误的方法 对只读类型进行写入报错 解决错误的方法 引用错误 解决错误的方法 …