# LangGraph 入门(二)- ChatBot demo

news2024/10/19 10:19:29

在这个快速入门 demo 中,我们将会使用 langGraph 构建一个基本的对话机器人和可是使用网络搜索的机器人。通过这个 demo 我们来快速对 langgraph 有一定感知。

概念补充

顾名思义langGraph是基于图(Graph Theory)的,如果你学过图论那么你一定很熟悉,没学过也没关系,只需要能看懂下面的简单的示意图即可。

  • Node(a.k.a. vertex ): 图上的顶点

  • Edge: 图上点与点之间的关系

  • State: Nodes 通过在 Edge 上传递 State 来通讯。

  • Graph: 图内容的总和

开发前准备

llm

这个 demo 我们使用豆包的 function call 优化的模型,同时它也兼容 openAI 的 api,开发上更便利。如果使用其他家 AI,你需要确定模型是否支持 function call。

image.png

创建 api key

image.png

创建推理点

image.png

模型名称 ep-xxxxx

image.png

依赖安装

pip install -U langgraph langchain-openai

配置 api key

import os
# 配置你的api key
os.environ["OPENAI_API_KEY"] = os.environ.get("DOUBAO_API_KEY", "your api key")

创建 llm 对象

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="your id",  # 你的推理点id,ep-开头
    base_url="https://ark.cn-beijing.volces.com/api/v3",
)

llm.invoke("你好")
AIMessage(content='你好!有什么我可以帮助你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 10, 'total_tokens': 21, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'doubao-pro-32k-functioncall-240815', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-946e93a3-b8fd-4cc9-aaf4-12489983e79c-0', usage_metadata={'input_tokens': 10, 'output_tokens': 11, 'total_tokens': 21, 'input_token_details': {}, 'output_token_details': {}})

构建一个简单对话机器人(chat bot)

我们将构建一个简单的对话机器人,通过这个样例来熟悉最基本的概念。

graph 构建

首先我们从创建一个Stategraph开始,我们使用 StateGraph 来定义 chat bot 的结构,它就相当于我们 bot 的状态机(state machine)。我们添加 nodes 来表示增加 llm 或者功能调用,通过添加 edges 来指定 node 之间跳转。

from typing import Annotated

from typing_extensions import TypedDict

from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages


class State(TypedDict):  # 继承TypedDict就可以用dict表示了State了
    # 还记得上吗怎么介绍State的么?对,它是传递信息的载体。
    #
    # 这里我们定一个list类型State
    # 并为它添加元数据add_messages function,框架将通过这个function来reduce数据,
    # add_messages作用是将多个message list合并为一个
    messages: Annotated[list, add_messages]


# 定义graph
graph_builder = StateGraph(State)


# 使用一个function在node运行时调用
def chatbot(state: State):
    # 返回一个State dict
    return {"messages": [llm.invoke(state["messages"])]}


# 添加node
# 第一个参数为node的名称,第二个参数为node被使用时调用的方法
graph_builder.add_node("chatbot", chatbot)

# 添加一个入口
graph_builder.add_edge(START, "chatbot")
# 添加一个出口,任何node都可以指向出口
graph_builder.add_edge("chatbot", END)
# 最后如果想让我们的graph运行,我们需要将graph进行编译。它将返回一个compiledGraph
graph = graph_builder.compile()

注意 ⚠️: State 可以是 dytanic 也可以是 TypeDict,推荐继承 TypeDict,这样我们直接返回 dict 就可以,类型,编程会更加方便。

可视化 graph

langgraph 提供了很多可视化输出的工具,可以是 ascii 也可以是 png。

from IPython.display import Image, display


display(Image(graph.get_graph().draw_mermaid_png()))

运行

终于可以运行试一试了,graph 是继承了 runnable 的。这意味着我们可以,使用同步、异步的 invoke、stream 等操作。

需要注意的是 langgraph 的 stream 和 langchain 的 stream 并不等同。
langgraph 的 stream 每次 yield 产生的是一个 event,而 langchain 产生的是一个 message chunk。如果不了解 runnable,可以看一眼我之前的 langchain 的文章。

for event in graph.stream({"messages": [("user", "你好")]}):
     print(event)
{'chatbot': {'messages': [AIMessage(content='你好!有什么我可以帮助你的吗?', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 11, 'prompt_tokens': 10, 'total_tokens': 21, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'doubao-pro-32k-functioncall-240815', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-16bda42e-7ca1-4cab-a8d9-6597c5987259-0', usage_metadata={'input_tokens': 10, 'output_tokens': 11, 'total_tokens': 21, 'input_token_details': {}, 'output_token_details': {}})]}}

恭喜 🎉 我们的第一个 langgraph 应用运行起来了。后续我们将为我们的 bot 增加更多功能。

让 bot 具有使用工具能力

为了让 bot 回答原始训练数据并未包含的问题,我们将 web search 工具内嵌到 bot 中。

可以使用魔法以及英语英语场景较多的朋友,可以试试 tavily。中文环境没有太好的免费AI搜索API,我这使用coze平台的插件,它可以使用 bing 搜索、百度搜索等,单需要自己封装一下。两种方式我都会给出 demo。

tavily

tavily 是专为 LLMs 设计的 AI 搜索工具,每月有 1000 次免费搜索次数,官网。

langchain 体系对 tavily 有着较好的支持,我们可以之间引入对应 sdk。在注册账号后需要配置 API KEY。

pip install -U tavily-python langchain_community

from langchain_community.tools.tavily_search import TavilySearchResults

os.environ["TAVILY_API_KEY"] = os.environ["TAVILY_API_KEY"] or "your api key"
tool = TavilySearchResults(max_results=2)
tool.invoke("北京值得逛的景点?")
[{'url': 'https://www.visitbeijing.com.cn/article/4JN1YW7zzzc',
  'content': '如果你第一来北京旅游,不知道去哪儿里玩,这篇旅游攻略将为你提供最全面的指南,帮助你了解北京最值得去的20大景点。从故宫博物院到长城,从颐和园到天坛公园,这些景点将带你领略北京的历史、文化和风光。让我们开始这次北京之旅吧! 01故宫'},
 {'url': 'https://zhuanlan.zhihu.com/p/656674369',
  'content': '假期周末闲暇时间总要来场说走就走的旅行吧!有机会要来趟北京游玩吧!北京好玩的地方有哪些值得打卡的标志性景点呢?今天整理了10个北京值得逛的热门景点合集,附五日游路线攻略! 1、颐和园(5a) 门票:30 时间…'}]

coze

coze 是字节旗下低代码 AI 平台,官网。coze 本身也非常好用,提供一定的可视化 agent 开发能力,非常适合有一定动手能力的个人,但是如果希望开发用于生产的 agent,我们最好还是基于代码来进行开发。这里我们使用 coze 提供的工具来进行搜索。

这是我在 coze 上构建的一个 bing 搜索的工作流。

coze api 的使用方链接🔗。

我们可以定义一个 python 的 function 来作为工具。

import httpx
import json


async def search_web(
    query: Annotated[str, "The query to search for"], count: int = 2
) -> list:
    """使用搜索引擎获取资料"""
    headers = {
        "Authorization": f"Bearer {os.environ.get("COZE_KEY", "your api key")}",
        "Content-Type": "application/json",
        "Accept": "*/*",
        "Host": "api.coze.cn",
        "Connection": "keep-alive",
    }
    data = {
        "workflow_id": "your workflow_id",# 使用你自己的workflow
        "parameters": {"query": query, "count": count},
    }

    async with httpx.AsyncClient() as client:
        response = await client.post(
            "https://api.coze.cn/v1/workflow/run", headers=headers, json=data
        )
    response.raise_for_status()
    data = response.json()
    data = json.loads(data["data"])["data"]

    return json.loads(data)


await search_web("北京值得逛的景点?")
    ['北京最值得去的12个地方,你去过几个?认为值得吗?-手机网易网\n天安门广场天安门广场位于北京市中心,可容纳100万人举行盛大集会,不仅是中国的政治和文化象征,也是许多重要历史事件的发生地,广场上的主要建筑和景点包括:天安门城楼、人民英雄纪念碑、人民大会堂、中国国家博物馆、毛主席纪念堂。八达岭长城八达岭长城是万里长城的一部分,古称“居庸关之险不在关而在八达岭”,八达岭是明长城的一个隘口,为居庸关的重要前哨,八达岭长城是明长城居庸关八景之一,全国十大风景名胜之首,世界新七大奇迹之首。天坛公园天坛,是明清时期皇帝祭天、祈谷、和祈雨的场所,作为中国现存最大的祭天建筑群,天坛承载着丰富的历史和文化内涵。天坛不仅是一座建筑,更是中华民族文化传承的重要载体,正所谓冬至祭天,孟春祈谷,孟夏祭雨,都是我们需要从内心深处去传承的文化苦旅。4.故宫博物院 推开一扇窗,两朝三世六百年,故宫博物馆作为中国历史文化遗产的重要代表之一,经历了数百年的历史变迁,是在明清皇宫及其收藏基础上建立起来的大型综合性博物馆,也是中国最大的古代文化艺术博物馆,是中国现存规模最大、保存最完整的古代宫殿建筑群。5.圆明园 中国清代大型皇家园林,不仅汇集了江南若干名园胜景,还移植了西方园林建筑,集当时古今中外造园艺术之大成,堪称人类文化的宝库之一,是当时世界上最大的一座博物馆。圆明园遗址所承载的内涵是任何东西都无法替代的,具有极其特殊的历史文化价值,既是中华文明无比辉煌的象征,又是中华民族近代屈辱的纪念遗址,更是值得全人类深刻检讨和反思的文化遗存。6.什刹海 什刹海是中国级别的重点文物保护单位,也是国家AAAA级旅游景区,这里保存着大量的文物和历史建筑,同时也是京津冀地区最具文化和历史价值的景区之一,作为老北京胡同文化的重要代表,什刹海保留了许多传统建筑和街巷,展现了老北京人民的生活方式和生活习惯,它是感受北京传统文化和探索胡同历史的绝佳场所,游客可以在这里感受到浓厚的历史氛围和传统文化的魅力。\nlink:http://m.163.com/dy/article/JBLMIG1U05567KVH.html\n',
     '北京有哪些值得去玩的地方?推荐10大旅游景点,让你一次玩个痛快\n1、故宫博物院、2、天安门广场、3、长城、4、颐和园、5、圆明园:圆明园是清代的皇家园林,被誉为“万园之园”,6、北京欢乐谷、7、北京鸟巢和水立方、8、798艺术区:79...北京有哪些值得去玩的地方?推荐10大旅游景点,让你一次玩个痛快 北京有哪些值得去玩的地方?北京值得去的地方有:1、故宫博物院、 2、天安门广场、 3、长城、 4、颐和园、 5、圆明园:圆明园是清代的皇家园林,被誉为“万园之园”,6、北京欢乐谷、 7、北京鸟巢和水立方、 8、798艺术区:798艺术区是北京的一个当代艺术中心,9、南锣鼓巷:南锣鼓巷是北京的一条传统胡同,保存了很多传统的建筑和文化元素,10、北海公园:保存最完整的皇家园林之一。说到玩,咱们得直击重点:北京,这地儿,有哪些让你一去就舍不得回来的好玩之处?甭急,我这就给你细细道来。先得说说那故宫。你听说过紫禁城没?对,就是那儿!走进去,满眼都是金碧辉煌,仿佛穿越回了明清时代。那红墙黄瓦,简直就是古装的“大片现场”。还有那珍宝馆,哇塞,里面的宝贝看得你眼花缭乱。什么玉如意、金麒麟,简直比电影里的还要炫!接下来,咱得到天安门广场逛逛。站在这儿,你就站在了中国的“心脏”。每天早上看升旗仪式,那场面,比任何电影都要震撼人心。还有毛主席纪念堂,去瞻仰一下伟人的风采,也是一种别样的体验。长城呢?咱不能忘了长城!这可是咱们中国的骄傲。去爬一次长城,感受一下那种“不到长城非好汉”的豪情。站在长城上,放眼望去,山川壮美,心里那个美呀,简直无法用语言形容。颐和园也值得一去。那里面的湖光山色、亭台楼阁,简直就是一幅活生生的中国画卷。特别是那十七孔桥和昆明湖,简直就是摄影爱好者的天堂。还有圆明园遗址公园。虽然历史给它留下了些许遗憾,但正是这种残缺美,更让人感慨万分。\nlink:http://m.163.com/dy/article/IU8GCHRG0552M20P.html\n']
     ```

### 再次构建 graph

```python
from typing import Annotated

from langgraph.prebuilt import ToolNode
from typing_extensions import TypedDict

from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages


class State(TypedDict):
    messages: Annotated[list, add_messages]

graph_builder = StateGraph(State)
# 注意,这里一定要将llm和tool绑定,赋予llm工具调用能力
llm_with_tools = llm.bind_tools([search_web])


def chatbot(state: State):
    return {"messages": [llm_with_tools.invoke(state["messages"])]}

# 增加route节点
# 判断如果最新message含有tool_calls,那么将指向tool node
async def route(state: State):
    if getattr(state["messages"][-1],"tool_calls"):
        return "toolnode"
    else:
        return END

# 这里使用官方提供的ToolNode,主要封装了state内容提取,返回封装为ToolMessage等功能
tool_node = ToolNode([search_web])


graph_builder.add_node("chatbot", chatbot)

graph_builder.add_node("toolnode", tool_node)

graph_builder.add_edge(START, "chatbot")

# tools调用完之后回到chatbot node
graph_builder.add_edge("toolnode", "chatbot")

graph_builder.add_conditional_edges("chatbot", route)


graph = graph_builder.compile()
# 打印出来看看
display(Image(graph.get_graph().draw_mermaid_png()))

这种结构是最基础、最常见的 agent,实际上如果只是这种结构,我们并不需要自己写,langgraph 提供了封装,使用langgraph.prebuilt.create_react_agent即可创建 graph。

异步运行

这里使用 astream 会产生 AsyncIterator,我们可以异步运行。让我们看看每每个 node 的运行结果。

async for event in graph.astream({"messages": [("user", "查一下北京的天气")]}):
    print(event)
{'chatbot': {'messages': [AIMessage(content='\n', additional_kwargs={'tool_calls': [{'id': 'call_heh7r4f5btcv486jxcu2wqx8', 'function': {'arguments': '{"query": "北京的天气"}', 'name': 'search_web'}, 'type': 'function'}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 24, 'prompt_tokens': 78, 'total_tokens': 102, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'doubao-pro-32k-functioncall-240815', 'system_fingerprint': None, 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-932e6a29-f804-4ccd-9cb8-c3728632685e-0', tool_calls=[{'name': 'search_web', 'args': {'query': '北京的天气'}, 'id': 'call_heh7r4f5btcv486jxcu2wqx8', 'type': 'tool_call'}], usage_metadata={'input_tokens': 78, 'output_tokens': 24, 'total_tokens': 102, 'input_token_details': {}, 'output_token_details': {}})]}}
    {'toolnode': {'messages': [ToolMessage(content='["【北京天气预报15天_北京天气预报15天查询】-中国天气网\\n15天预报 北京 昨天 16日 阴 18° 阴 14° <3级 <3级 今天 17日 小雨 18° 小雨 14° <3级 <3级 周五 18日 小雨 18° 晴 5° 3-4级 3-4级 周六 19日 晴 12° 多云 3° <3级 <3级 周日 20日 小雨 10° 多云 3° <3级 <3级 周一 21日 多云 15° 晴 6° <3级 <3级 周二 22日 晴 17° 晴 5° <3级 <3级 周三 23日 晴 19° 晴 6° <3级 <3级 周四 24日 晴 19° 晴 8° <3级 <3级 周五 25日 晴 18° 晴 7° <3级 <3级 周六 26日 晴 18° 阴 9° <3级 <3级 周日 27日 阴 15° 雨 8° <3级 <3级 周一 28日 雨 15° 晴 7° <3级 <3级 周二 29日 阴 14° 阴 8° <3级 <3级 周三 30日 雨 10° 雨 8° <3级 <3级 周四 31日 雨 10° 雨 8° <3级 <3级 昨天 16日 今天 17日 周五 18日 周六 19日 周日 20日 周一 21日 周二 22日 周三 23日 周四 24日 周五 25日 周六 26日 周日 27日 周一 28日 周二 29日 周三 30日 周四 31日 <3级 <3级 3-4级 <3级 <3级 <3级 <3级 <3级 <3级 <3级 <3级 <3级 <3级 <3级 <3级 <3级\\nlink:https://m.weather.com.cn/mweather15d/999999999.shtml\\n", "翻出厚衣服!北京降雨大风和强降温天气将至 雨后最低气温仅有3℃\\n中国天气网讯 受冷空气影响,10月17日至20日,北京市将先后出现降雨、大风和强降温天气。预计明显降雨时段在17日傍晚至18日早晨,雨后大风降温将至,降温后20日最低气温仅有3℃左右,需及时添衣保暖。\\n降雨预报:预计17日下午至18日下午,北京自西向东将出现中雨天气,西部、北部局地中到大雨,高海拔山区可能出现雨夹雪。明显降雨时段在17日傍晚至18日早晨,18日下午降雨逐渐结束。\\n大风预报:18日下午至夜间,北京将有3、4级偏北风,阵风6、7级,山区局地可达8级。19日早晨风力减弱。\\n降温预报:18日夜间开始,北京市气温明显下降,气温降幅达8℃至10℃。预计20日白天,北京最高气温将降至10℃左右,夜间最低气温降至3℃左右,山区最低气温降至0℃以下。21日起气温缓慢回升。\\n中国天气网提醒,雨后道路湿滑、能见度下降,建议公众出行提前关注路况信息,特别是17日晚高峰和18日早高峰期间,提前安排出行时间,行车需减速慢行,注意交通安全。此外,雨后北风较大,外出时需注意防风,远离临时搭建设施和高大树木。气温较前期明显下降,18日夜间至20日气温偏低、体感偏冷,需及时添衣保暖,山区户外活动建议配备棉衣或羽绒服等御寒衣物,谨防感冒和心脑血管疾病。\\nlink:https://m.weather.com.cn/news/2024/10/3924847.shtml\\n"]', name='search_web', id='e56ccd74-c134-4a76-8c86-dddfabdb45fa', tool_call_id='call_heh7r4f5btcv486jxcu2wqx8')]}}
    {'chatbot': {'messages': [AIMessage(content='北京的天气情况如下:\n|日期|天气状况|最高温度|最低温度|风力等级|\n|---|---|---|---|---|\n|10月17日|小雨|18℃|14℃|<3级|\n|10月18日|小雨转晴|18℃|5℃|3-4级转<3级|\n|10月19日|晴|12℃|3℃|<3级|\n|10月20日|小雨转多云|10℃|3℃|<3级|\n|10月21日|多云转晴|15℃|6℃|<3级|\n|10月22日|晴|17℃|5℃|<3级|\n|10月23日|晴|19℃|6℃|<3级|\n|10月24日|晴|19℃|8℃|<3级|\n|10月25日|晴|18℃|7℃|<3级|\n|10月26日|晴转多云|18℃|9℃|<3级|\n|10月27日|多云|15℃|8℃|<3级|\n|10月28日|晴|18℃|8℃|<3级|\n|10月29日|多云|14℃|8℃|<3级|\n|10月30日|小雨|10℃|8℃|<3级|\n|10月31日|小雨|10℃|8℃|<3级|', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 359, 'prompt_tokens': 1130, 'total_tokens': 1489, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'doubao-pro-32k-functioncall-240815', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-54a61e28-1be2-400a-9d58-26e659215a39-0', usage_metadata={'input_tokens': 1130, 'output_tokens': 359, 'total_tokens': 1489, 'input_token_details': {}, 'output_token_details': {}})]}}

总结 🎉

这次我们通过,两个比较基础的 chatbot 对 langgraph 有了基础的了解,之后我会对一些核心概念进行比较详细的解释,,最后我们会通过构建一个生产级别的 agent来对整个langgraph框架一窥门径。

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

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

相关文章

【算法】约瑟夫环问题

据说著名的犹太历史学家Josephus有过以下故事&#xff0c; 罗马人占领乔塔帕特&#xff0c; 39个犹太人与Josephus和他的朋友躲在洞中&#xff0c;其中39个犹太人决定自杀&#xff0c; &#xff0c;他们的自杀方式是41个人绕成一圈&#xff0c;第一个人报数1&#xff0c;报数到…

RK3588的demo板学习

表层的线宽是3.8mil: 换层之后线宽变成了4.2mil: (说明对于一根线&#xff0c;不同层线宽不同) 经典&#xff1a; 开窗加锡&#xff0c;增强散热&#xff0c;扩大电流&#xff1a; R14的作用&#xff1a;与LDO进行分压&#xff0c;降低LDOP的压差从而减小其散热&#xff1a;第…

如何系统的从0到1学习大模型?有哪些书籍推荐?

大模型应用得好&#xff0c;不仅需要海量的基础数据、大规模算力、综合人工智能发展成果的技术&#xff0c;还需要政产学研用各方的共同推进。 大模型不仅能生成结果、生成数据&#xff0c;更能传递价值观。应用于我国的大模型需要懂中文、懂中国文化、懂中国国情。大模型是全…

【Linux系统编程】环境基础开发工具使用

目录 1、Linux软件包管理器yum 1.1 什么是软件包 1.2 安装软件 1.3 查看软件包 1.4 卸载软件 2、Linux编辑器-vim 2.1 vim的概念 2.2 vim的基本操作 2.3 vim的配置 3、Linux编译器-gcc/g 3.1 gcc编译的过程​编辑​编辑​编辑 3.2 详解链接 动态链接 静态链接 4…

纯HTML实现标签页切换

纯HTML实现标签页切换 实现原理&#xff1a; HTML结构&#xff1a; 使用无序列表&#xff08;<ul>&#xff09;创建标签导航。每个标签是一个列表项&#xff08;<li>&#xff09;&#xff0c;包含一个链接&#xff08;<a>&#xff09;。每个链接指向对应的内…

商品计划:零售企业的痛点破解与运营优化指南

在现代零售业的激烈竞争中&#xff0c;商品计划不仅是企业盈利的关键&#xff0c;更是解决众多痛点的有效途径。零售企业在运营过程中常常面临各种挑战&#xff0c;如财务问题、库存管理、市场分析等。而科学、系统的商品计划可以帮助企业有效应对这些挑战&#xff0c;提升整体…

气膜:冰雪产业的创新解决方案—轻空间

随着冰雪运动的普及和发展&#xff0c;如何在不同季节和地区有效开展冰雪项目&#xff0c;成为了行业内的一个重要课题。气膜作为一种新兴的建筑形式&#xff0c;凭借其独特的优势&#xff0c;正在逐渐成为冰雪产业的创新解决方案。 优越的建筑特性 气膜建筑以其轻便、快速搭建…

Web Storage:数据储存机制

前言 在HTML5之前&#xff0c;开发人员一般是通过使用Cookie在客户端保存一些简单的信息的。在HTML5发布后&#xff0c;提供了一种新的客户端本地保存数据的方法&#xff0c;那就是Web Storage&#xff0c;它也被分为&#xff1a;LocalStorage和SessionStorage&#xff0c;它允…

【黑马redis高级篇】持久化

//来源[01,05]分布式缓存 除了黑马&#xff0c;还参考了别的。 目录 1.单点redis问题及解决方案2.为什么需要持久化&#xff1f;3.Redis持久化有哪些方式呢&#xff1f;为什么我们需要重点学RDB和AOF&#xff1f;4.RDB4.1 定义4.2 触发方式4.2.1手动触发save4.2.2被动触发bgsa…

软件工程:需求规格说明书(图书管理系统)

目录 1 导言 1.1 编写目的 1.2 参考资料 2 项目介绍 2.1 项目背景 2.2 项目目标 3 应用环境 3.1 系统运行网络环境 ​编辑 3.2 系统软硬件环境 4 功能模型 4.1 功能角色分析 4.1.1 图书管理员 4.1.2 普通读者 4.1.3 邮件系统 4.2 功能性需求 4.2.1 预定图…

AI+Xmind彻底解决你的思维导图

在写作领域、老师授课、产品经理等都会使用到思维导图&#xff0c;如果是一个个拖拉撰写太麻烦了。 本篇内容小索奇就教会大家利用AI结合Xmind制作思维导图。 先打开我们的AI软件 这里小索奇用ChatGPT&#xff08;可以使用kimi&#xff0c;豆包等大模型都可以&#xff09; P…

中小型医院网站开发:Spring Boot入门

2 相关技术简介 2.1 Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;…

上市公司资产误定价Misp计算数据-含参考资料及代码(2006-2023年)

数据说明&#xff1a;参考《经济研究》期刊游家兴&#xff08;2012&#xff09;老师的做法&#xff0c;先根据行业内所有公司推算出公司的基础价值&#xff0c;进而通过对公司的实际价值与基础价值进行对比&#xff0c; 来衡量公司相对于业内同行的误定价水平&#xff0c;具体大…

D39【python 接口自动化学习】- python基础之函数

day39 函数的返回值 学习日期&#xff1a;20241016 学习目标&#xff1a;函数&#xfe63;-52 函数的返回值&#xff1a;如何得到函数的执行结果&#xff1f; 学习笔记&#xff1a; return语句 返回值类型 def foo():return abc var foo() print(var) #abc# 函数中return函…

python实现录屏功能

python实现录屏功能 将生成的avi文件转为mp4格式后删掉avi文件 参考感谢&#xff1a;https://www.cnblogs.com/peachh/p/16549254.html import os import cv2 import time import threading import numpy as np from PIL import ImageGrab from pynput import keyboard from da…

统一认证与单点登录:简化用户体验的关键解决方案

引言 在数字化时代&#xff0c;企业往往需要管理多个应用和系统&#xff0c;随之而来的是用户密码和身份认证管理的复杂性。统一认证&#xff08;Single Sign-On, SSO&#xff09;作为一种身份管理解决方案&#xff0c;不仅可以减少用户在多个系统间切换登录的麻烦&#xff0c…

选择合适的SSL证书

随着我们在线业务的增长&#xff0c;确保网站安全变得越来越重要。对于许多人来说&#xff0c;保护网站安全的想法似乎令人望而生畏&#xff0c;尤其是在有各种SSL证书可用的情况下。您可能想知道哪一个最适合您的业务需求或如何浏览这些选项。 除了SSL证书之外&#xff0c;使…

Nuxt.js 应用中的 app:resolve 事件钩子详解

title: Nuxt.js 应用中的 app:resolve 事件钩子详解 date: 2024/10/17 updated: 2024/10/17 author: cmdragon excerpt: app:resolve 是 Nuxt.js 中的生命周期钩子,在解析 app 实例后调用。这个钩子允许开发者在应用完全初始化后执行一些自定义操作,比如注册插件、设置中…

D40【python 接口自动化学习】- python基础之函数

day40 练习&#xff1a;函数实现电商购物车功能 学习日期&#xff1a;20241017 学习目标&#xff1a;函数 - 53 如何利用函数实现电商购物车功能&#xff1f; 学习笔记&#xff1a; 购物车功能分析 定义商品为列表 实现商品的展示 # 商品 products[[1000,iphone,phone,1200…

(MySQL)索引

注&#xff1a;此博文为本人学习过程中的笔记 1.简介 1.1.概念 MySQL的索引是一种数据结构&#xff0c;它可以帮助数据库高效地查询&#xff0c;更新数据表中的数据。索引通过一定的规则排列数据表中的记录&#xff0c;使得对表的查询可以通过对索引的搜索来加快查询 MySQ…