运用Agent搭建“狼人杀”游戏服务器端!

news2024/11/25 7:07:57

背景

从23年开年以来,大模型引爆了各行各业。去年比较出圈的是各类文生图的应用,比如Stable Diffusion。网上可以看到各类解释其背后的原理和应用的文章。另外一条平行线,则是文生文的场景。受限于当时LLM(大语言模型)的能力,其应用场景相当受限。不过,进入到24年以来,Claude 3、LLaMa 3、 Mistral、GPT 4等大模型的能力开始不断增强,将各路榜单分数不断提高。LLM生态同时也在快速进化,各种智能体(Agent)开始屡见不鲜。

斯坦福大学吴恩达教授也于前不久之前发表了著名的Agent“四种设计模式”:反思,工具使用,规划和多Agent协作。在目前大模型的能力前提下,往往利用良好的“流程设计”可以做到“1+1 > 2”的效果。要做到这样效果,有别于传统方法,Agent工作流不是让LLM直接生成最终输出,而是多次提示(prompt)LLM,使其逐步构建更高质量的输出。

本文利用了上述思想,将展示如何使用“Agent”技术,从头开始搭建一个“狼人杀”游戏服务器端。

图片

狼人杀

既然是《狼人杀》游戏,我们需要知道LLM对它的了解程度如何?这里对它提了几个问题,发现它对于LLM是有基本的了解的。这可能是这个游戏已经存在了很多年,在互联网上有大量相关的语料,因此在训练的时候LLM对它就有天然的认知。

图片

不过这也带来了新的问题:

这么多版本,如何让LLM在游戏过程中保持和人类一致的认知?

游戏中每个角色都是有自己的设定和功能的,如何写提示词,才能让LLM代入角色?

游戏中同阵营角色如何进行配合?

作为LLM驱动的游戏,它和传统游戏开发有什么不一样?

市面上那么多的LLM,哪一款能真正地将游戏玩下去?

生成式AI技术

下面会介绍一些目前比较火热的生成式AI技术,同样也是《狼人杀》游戏用到的技术。由于这块涉及内容很多,受限于篇幅无法全部展开。

LLM Tuning

对于模型微调手段,通常有如下四种手段:

提示词工程(PE):通过提示词模版的方式引导LLM的输出。

检索式增强(RAG):通过向量数据库来存储私有知识库,减少LLM的幻觉。

微调(Fine-Tuning):通过向LLM训练中增加私有词条,让LLM输出带有一定偏向性。

预训练(Pre-Traning):从头训练一个新模型。

提示词工程

常用的提示词工程技术有(这里主要介绍在游戏中使用到的方法):

zero-shot/few-shot:在没有或者少量样本情况下引导LLM进行输出。

CoT/XoT:利用大模型的推理能力,一步一步输出中间过程来提高提示词效果。

ReAct:让LLM逐步思考观察,并且使用工具来获取额外信息,循环前面过程来引导出可信结果。

Reflextion:它由三个不同的模型组成:Actor、Evaluator和Self-Reflection。Actor模型使用大型语言模型(LLM)来生成文本和动作,并在环境中接收观察结果。Evaluator模型负责评估Actor产生的轨迹的质量,并计算一个奖励分数以反映其性能。Self-Reflection模型则对反馈内容进行反思,为后续流程提供有价值的反馈信息。这三个模型共同协作,在任务中不断迭代优化,从而提高决策能力。

接下来可以看,如何在《狼人杀》游戏中使用这些提示词技巧。

游戏规则设定

通过以下的规则设定传入LLM后,我们可以限定住游戏的版本,并且将一些常用的策略告知大模型,也能有助于LLM进行游戏。

## 游戏分坏人和好人两大阵营, 
- 坏人阵营只有狼人,好人阵营有女巫,预言家和村民
- 阵营配置:{formation}
- 坏人阵营:消灭所有好人,或者保证坏人数目大于好人数目
- 好人阵营:女巫和预言家要利用自己特殊能力保护村民消灭所有坏人

## 游戏分白天和夜晚两个阶段交替进行:
- 夜晚:所有玩家闭眼,不能发言,行动不会暴露身份
-- 狼人的行动必须统一投票淘汰一名玩家
-- 预言家必须查验一名玩家身份
-- 女巫必须使用一种药水
-- 普通村民晚上无法行动和发言
- 白天:所有玩家睁眼, 分为讨论和投票两环节
-- 讨论环节,每个玩家必须参与讨论发言
-- 投票环节,每个玩家必须投票或者放弃

## 策略:
- 村民:多观察大家发言,说出站队理由,根据场上局势和信息来进行判断
- 女巫:只有一瓶毒药和一瓶解药,可以暗示但需要隐藏自己身份
-- 毒药可以立马淘汰一名玩家
-- 解药可以让淘汰的玩家复活
- 预言家:发言要流利,多说细节。第二天不要跳,第三天可以跳
- 狼人:
-- 悍跳预言家:发言强势,制造混乱,模仿预言家发言
-- 普通狼人:发言精简,根据情况站队,必要时踩自己队友
-- 自刀狼人1:狼人夜晚自刀,骗女巫解药,若女巫不救,则狼人团队减1,若女巫救人,则可坐实好人身份
-- 自刀狼人2:和真预言家一起跳“预言家”时候,自刀让好人相信自己身份

Agent设定

通用部分, 这里的game_rule即为上面的游戏规则部分,commands会在工具部分介绍:

<instructions>
你是资深的社交游戏玩家助手, 熟悉《狼人杀》游戏规则:
<game_rules>
{game_rule}
</game_rules>

熟悉游戏所有命令以及例子:
<commands>
{commands}
</commands>

由于采用Reflextion架构设计,我们需要对应地设置三个模块(LLM)。

Self-Reflection(游戏内叫DoMemory,记忆总结模块)。

接下来, 你扮演游戏中“上帝”角色,需要将<input>的文字输入进行有效提炼并且输出且满足下面的要求:

- 保持客观冷静, 用自然语言且不能超过{num}个字还原内容
- 不输出无关内容,内容言简意赅,突出重点
- 不需要输出任何中间思考过程
- 不要给任何推理和主观意见

Actor(游戏内叫DoAction,利用ReAct方式实现的推理规划模块)。

现在需要你根据,结合观察和推理提取有用的信息,一步一步使用如下格式思考:

观察: 不要编造任何内容.陈述游戏事实(当前时间,上轮决策评分(如果有),本玩家身份,本玩家队友(如果有),物品状态(如果有)等等)

思考: 结合玩家性格特点,进行逐步推测游戏信息(本方游戏赢面,场上玩家身份,是否有矛盾信息等等),注意鉴别历史信息真伪
行动: 必须从 <commands> 中的描述选择合适方法, 只需要输出方法名字即可
参数: 
    agent=执行玩家,
    target=目标玩家(必须是明确的名字),
    content=发言内容,多使用专用词汇来发言, 运用辩解,对抗,欺骗,伪装,坦白等技巧包装内容(可选,注意言简意赅,少讲废话, 突出重点.)

决策: 参考 <commands> 中例子部分输出JSON格式

注意:
- 决策评分标准:1-3分为差,4-5分一般,6分及格,7分优秀,8分满分.
- 决策评分信息不一定每次都有,需要保证一个6分以上的决策

Evaluator(游戏内叫DoReflect,设定两个维度对DoAction进行打分)。

<examples>
{"score": 1}
{"score": 5}
</examples>

接下来, 你需要将玩家<input>的内容进行评分. 请一步一步使用如下格式思考:

观察: 陈述游戏情况和玩家决策

思考:
- 决策对于自己的影响 (1:不利,2:平均,3:有利,4:最佳.如果决策不足够清晰明确,直接1分) 
- 决策对于本方的影响 (1:不利,2:平均,3:有利,4:最佳.如果决策不足够清晰明确,直接1分)
- 将以上多个分数相加

评分: 输出参考 <examples> 中例子输出JSON格式

这样,每次Agent需要做决策时候,都会进行至少3次LLM的调用来保证输出结果的可靠性。

工具

在《狼人杀》游戏中,我们需要将每个Agent按照其身份对动作进行抽象和归类。这么做的好处有:

统一成外部资源,方便扩展。甚至可以利用RAG技术将这部分作为专用知识库来存储。

提高模版的复用率, 比如狼人的动作就包括wolf+player,而村名只有player可以用。

提供zero-shot/few-shot来增强LLM的认知和输出结果的可控性。

<wolf>
- 方法: WolfVote
  描述: agent(狼人)夜晚对target(目标)投票, 并且提醒队友跟随
  参数: agent=执行玩家,target=玩家名字
  例子: {"action": "WolfVote", "agent": "P1", "target": "Mike"}
</wolf>

<prophet>
- 方法: ProphetCheck
  描述: agent(预言家)夜晚查验对target(目标)身份, 同一个夜晚只能用一次
  参数: agent=执行玩家,target=玩家名字
  例子: {"action": "ProphetCheck", "agent": "Ben", "target": "John"}
</prophet>

<witch>
- 方法: WitchPoision
  描述: agent(女巫)夜晚对target(目标)使用毒药
  参数: agent=执行玩家,target=玩家名字
  例子: {"action": "WitchPoision", "agent": "P6", "target": "P2"}
- 方法: WitchAntidote
  描述: agent(女巫)夜晚对target(目标)使用解药
  参数: agent=执行玩家,target=死亡玩家
  例子: {"action": "WitchAntidote", "agent": "Lisa", "target": "Chirs"}
</witch>

<player>
- 方法: PlayerVote
  描述: agent(玩家)白天对target(目标)进行投票, 票数高的玩家会被淘汰
  参数: agent=执行玩家,target=玩家名字
  例子: {"action": "PlayerVote", "agent": "P2", "target": "P4"}
- 方法: PlayerDoubt
  描述: agent(玩家)白天对target(目标)进行怀疑,不会计入投票
  参数: agent=执行玩家,target=存活玩家,content=思考/理由(可选项)
  例子: {"action": "PlayerDoubt", "agent": "P2", "target": "P4", content="我对P4身份存疑,(给出原因)"}
- 方法: Debate
  描述: agent(玩家)白天讨论,不会计入投票
  参数: agent=执行玩家, content=思考/理由
  例子: {"action": "Debate", "agent": "P2", "content": "我跳预言家/女巫,(给出原因)"}
- 方法: DeathWords
  描述: agent(玩家)白天死亡遗言
  参数: agent=执行玩家, content=思考/理由
  例子: {"action": "DeathWords", "agent": "P2", "content": "我今天被刀了,(给出原因)"}
- 方法: Pass
  描述: agent(玩家)行动弃权
  参数: agent=执行玩家
  例子: {"action": "Pass", "agent": "P2"}
</player>

输出提取

当前面的PE模版设置好以后,我们可以看到Agent的回答基本就符合要求了:

观察: 目前是第1天夜晚,我是狼人Fiona,队友是Daphne。狼人Daphne已经投票淘汰了Adam。还剩下6名存活玩家。

思考: 作为狼人,我的目标是消灭所有好人玩家。第一天夜晚刚开始,场上信息很少,难以判断其他玩家的身份。不过Daphne已经开始行动了,我应该支持她的决策,并利用狼人的优势来混淆视听。

行动: WolfVote
参数: 
    agent=Fiona
    target=Adam
    content=我同意狼人Daphne的决定,一起刀Adam吧。

决策: {"action": "WolfVote", "agent": "Fiona", "target": "Adam"}
这里面还有比较关键的一步,则是提取决策里面的内容。不同的框架会用不同方式来提取,比如 langchain 会用 output parser 来做。这里我们会采用正则的方式提取即可:

def ParseJson(text):
    try:
        # 使用正则表达式查找 {} 之间的内容
        json_pattern = re.compile( r'{[\s\S]*?}') 
        json_strings = re.findall(json_pattern, text)
        return json_strings
    except Error:
        logger.exception("Cannot parse json")
    return None

上帝

在《狼人杀》游戏中,“上帝”是一个比较特殊的存在。它的行动不需要太多的发散,甚至“可控”才是它的追求。因为它是游戏的节拍器,用来保证游戏正常运行。所以这个部分我们就采用了程序实现方案。

这里我们采用的技巧是:在每次向Agent提问时候会动态替换玩家的身份信息和游戏局面信息。减少LLM上下文过长后带来的遗忘问题。比如下面的这段“上帝提问”,它其实是动态生成的:

图片

Agent

“Agent”技术可以认为是一个或者多项微调技术(PE+RAG+Fine-Tuning等)的综合实现。其起源很早,并且有各种版本和模式。但真正让LLM“出圈”来自standford town。在小镇项目中,玩家可以以上帝的角色观察里面多个村民进行生活和对话,可以类比为一个“西部世界”。这里重要的一个特质是:自主思考和行动。

图片

为了实现这个特质,设计者提出了generative Agent架构,最重要的三个核心模块:memory stream,reflection和planning。

Memory System:长程记忆模块,即用自然语言记录Agent经历的复杂清单。

Reflection:随着时间推移,将记忆合成提炼出high-level的推断,使得Agent得出关于自身以及他人的总结,从而更好地指导Agent的行为。

Planning:将这些总结以及当前环境转换为high-level的行为计划,然后进行递归为行动和反应的详细行为。

消息系统

对于游戏环境来说,通常我们会有多个Agent进行协作和互动,因此会引入一个“环境(Environments)”的概念。Agent通过观察环境,思考规划,行动后,会对环境产生一个变化。这个变化可能是:某个“狼人”的伪装,某个“预言家”的查验,某个“玩家”的临终遗言等等。它是一个可以被观察的变化。进一步,我们可以把它抽象成“消息”。因为对于《狼人杀》来说,它就是一个个消息来驱动的游戏。

当然由于游戏的特殊性,“消息”是需要进行分类的。比如“狼人”之间的对话就只有他们之间“共享”;而“预言家”的行为又只能它自己独享;“平民”的动作则是公开透明的。为此我们需要实现两种消息系统:点对点,多播或者广播。

图片

实现这种消息传递机制并不困难,最简单的方案就是通过一些具有特殊设计的数据结构(比如数组,队列等等)就能完成目的。当然,现在主流的Multi-Agent框架也都提供了这种机制。

MetaGPT:提出了环境概念,并且利用Agent之间的订阅消息方法实现了之间的工作流(消息传递)。

AutoGen:预设了很多工作流(消息传递)的模版,比如2-Agent、seq chat、group chat、nested chat。

LangGraph:基于Langchain的多Agent工作流(消息传递)。

除此之外,它们还有的特性:

人在回路

有的时候,我们会考虑将玩家的输入也考虑进去,比如让玩家和游戏Agent进行对局之类。这个时候我们需要将某些Agent替换成人类输入。框架的好处是,它会封装好对应的方法。比如在MetaGPT中,我们只需要将is_human=True即可。本文实现的狼人杀并没有采用“人在回路”的特性。

team.hire(
    [
        SimpleCoder(),
        SimpleTester(),
        # SimpleReviewer(), # the original line
        SimpleReviewer(is_human=True), # change to this line
    ]
)

“预算”控制

在MetaGPT中设置了investment参数,类似的在AutoGen有max_turns,它能保证Agent之间的对话在规定的“预算”内完成,从而避免超额使用token数。同样,《狼人杀》游戏也延续了这样思路,当一个问题超过三次无法给出“有效”的答案时候,则会自动PASS该Agent的选择。

本文看来,选择成熟的框架还是自己实现没有绝对的对错。比如LangGraph就被人诟病设计得过于臃肿(40w+行的代码,语法糖过多,文档维护差)。AutoGen对于非Azure系的模型支持不够好。MetaGPT虽然支持更多模型调用,但工作流设计过于简单,并且容错率较低等等。

游戏架构

介绍到现在,我们《狼人杀》的游戏架构图也呼之欲出了。

图片

Game部分就对应了游戏的“上帝”,它是纯代码实现的。

其核心为一个无限循环,每次循环会根据游戏的时间(白天或夜晚)以及关键的事件向Agent提问。

为了统一控制,所有的问题都是预设好的,只需要动态替换关键信息即可。

另外一个重要的工作,就是维护场上玩家的信息:比如存活情况,道具情况等等。

Player 部分就是游戏内的“玩家Agent”,利用Reflextion的多LLM模式来完成游戏推理。

DoMemory/DoAnswer/DoReflect: 这些模块分别和Reflexion子模块对应,前面已解释。

DoValidation模块,这个模块的作用是为了验证大模型输出的数据有效性,来解决一些特殊场景下的问题。比如预言家同一个晚上重复检查玩家。

DoAction模块,对应着真正的玩家动作选择以及对环境产生影响,它会形成一个“可被观察的记忆”。

Memory部分就是通过消息方式实现的共享记忆(狼人)和独享记忆(预言家)。

每次记忆提取并不是全部塞到context中,而是设定了一个记忆窗口大小,比如过去的20轮。

拿到过去的记忆,也不是直接使用,需要通过一个“压缩”过程。

模型选择

模型选择是非常有意思的话题。模型的选择我们一般会考虑模型生成内容的质量、响应速度和性价比。因此在游戏,综合考虑下我们选择了Sonnet模型作为游戏的核心引擎。

在实际游戏开发中,为了节约成本,降低对模型访问频次的依赖,同时避免单一模型的Bias。因此在模型行为评估阶段,我们选择了第二种大语言模型来对推理模型的输出进行打分。而在内容总结方面,我们选择了第三种大语言模型。对于这种目标明确且不复杂的任务,即便是小参数量的大语言模型,也可以非常好地完成任务。

在整个游戏过程中,选择交替使用3个模型,1个模型保障了每个玩家角色高质量的“发言”,另外2个模型起到辅助作用。

事实上,我们还可以根据需要,随时切换到Amazon Bedrock上其他模型。灵活的模型切换这一点,Amazon Bedrock为我们提供了丰富的模型选择,我们完全可以根据业务的需要,去做不同模型之间的切换。

另外Amazon Bedrock还支持自定义模型的上传,我们完全可以将开源模型上传到Amazon Bedrock后,然后以按需或者独占算力资源的方式服务我们的应用。这一点上我们完全可以将大模型托管这件事从我们的应用中进行解耦,从而我们可以更加专注于业务逻辑的开发。

其他考虑

游戏复盘

当游戏参与的Agent变多后,一局游戏下来,其产生的内容和tokens数是很庞大的。这个时候还需要引入一个LLM来帮助我们进行游戏“复盘”,将关键的信息提取出来,方便后续分析。

图片

模型问题

虽然LLM拒答问题的情况有所减少,但这并不意味着问题完全解决了。幻觉问题依然存在。比如,LLM偶尔会虚构不存在的人物或事实,例如某某玩家昨晚表现异常等。另一个问题是,模型的回答往往过于“礼貌”,或者说带有明显的AI味道,缺乏拟人性。诸如此类的问题,光靠提示工程(Prompt Engineering)是无法从根本上解决的。在这种情况下,我们需要借助Fine-tuning的方法来优化模型输出,使其更加自然、人性化。

其实开源社区有不少用Llama或者Mistral作为底模来Fine-tuning过的LLM,比如Pygmalion-2-13b, 它就很擅长于对话和角色扮演。因此后续会考虑在最终输出层加一个这类型的LLM。受限于篇幅,这里不再展开。

服务器架构

既然是游戏服务器,最后我们需要考虑的就是怎么对外服务,下面是服务器部分的架构图。

应用层包括:

Amazon EC2 flask负责启动游戏进程,监控端口。

Amazon DynamoDB负责记录游戏的进度和日志。

Amazon S3 + Amazon Cloudfront负责分发游戏的配置。

模型层包括:

Amazon Bedrock:亚马逊云科技模型商店,为游戏进程统一的调用接口。

总结

总的来说,Agent是当下比较火热的技术。在本文中,我们主要聚焦于如何使用大模型来驱动游戏Agent,并结合提示词工程的一些技巧以及游戏的特性进行架构设计。可以看到,LLM的能力不断增长,超长上下文、响应速度、拒答率等因素不再成为约束,其在”游戏智能 NPC”的探索和应用会越来越多。借助其优秀的推理能力,游戏的玩法和设计也会变得更加丰富多彩。

然而,目前我们还看到一些其他的限制:角色的表现力、游戏的沉浸感这块目前属于大模型能力的短板。哪怕我们利用”微调”(fine-tuning)的方法,提升的效果也比较有限。即使解决了文字的部分,一款游戏的表现力还取决于画面、声音等多维度,这是一个复杂且具有挑战性的工程。

站在现在的时间点回过头来看,LLM技术就像90年代初的游戏联网、3D渲染一样,没有人知道未来这些技术将如何发挥最佳的表现力。未曾想到,现代游戏游戏把这些技术已经运用得淋漓尽致。同样,我们也充满了好奇和信心,LLM必将在这新一轮“大航海时代”中披荆斩棘。

最后,欢迎大家来尝试和探讨。

游戏客户端:

https://github.com/yourlin/Werewolf-Unity

游戏服务器:

https://github.com/xiwan/LLM-Game-Agents

游戏展示视频:

https://github.com/pgvector/pgvector

如何学习AI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

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

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

相关文章

笔记分享 |【黑马Pink老师】Web APIs

Web API 基本认知 介绍 严格意义上讲&#xff0c;我们在 JavaScript 阶段学习的知识绝大部分属于 ECMAScript 的知识体系&#xff1b; ECMAScript 简称 ES 它提供了一套语言标准规范&#xff0c;如变量、数据类型、表达式、语句、函数等语法规则都是由 ECMAScript 规定的&am…

Android Glide动态apply centerCropTransform(),transition withCrossFade动画,Kotlin

Android Glide动态apply centerCropTransform(),transition withCrossFade动画,Kotlin import android.graphics.Bitmap import android.os.Bundle import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import com.bumptech.glide.Glide import …

大数据学习10之Hive高级

1.Hive高级 将大的文件按照某一列属性进行GROUP BY 就是分区&#xff0c;只是默认开窗存储&#xff1b; 分区是按行&#xff0c;如一百行数据&#xff0c;按十位上的数字分区&#xff0c;则有十个分区&#xff0c;每个分区里有十行&#xff1b; 分桶是根据某个字段哈希对桶数取…

嵌入式新手必读好文,常见传感器类型中,LM393的作用,及模块原理(看不懂来问我)!!!

目录 序言 常感器基本知识 常见传感器原理 D0引脚的作用 如何设置电位器 欢迎指正&#xff0c;希望对你&#xff0c;有所帮助&#xff0c;禁止搬运&#xff01;&#xff01;&#xff01; 前言&#xff1a;编写不易&#xff0c;请问搬运&#xff0c;仅供学习&#xff0c;有…

机器学习2_支持向量机_线性可分——MOOC

目录 定义 线性可分&#xff08;Linear Separable&#xff09; 线性不可分&#xff08;Nonlinear Separable&#xff09; 数学化定义 问题描述 优化问题 线性可分定义 假定训练样本集是线性可分的 1、最小化&#xff08;Minimize&#xff09;&#xff1a; 2、限制条件…

git 工具原理

git 目录 git git的使用 了解git的三个区域 具体操作 如何下载别人上传到git的工程 -- 可以参考菜鸟教程&#xff0c;包括安装配置git Git 安装配置 | 菜鸟教程 -- Git 是一种分布式版本控制系统&#xff0c;用于管理软件项目的源代码。它是由 Linux 之父 Linus Torval…

MAN TruckScenes数据集:第一个用于自动驾驶卡车的大规模多模式数据集。

2024-07-15,为了推进自动驾驶卡车技术的发展并确保其在公共道路上的安全性&#xff0c;由慕尼黑工业大学和MAN Truck & Bus SE联合创建了MAN TruckScenes数据集。数据集首次为研究社区提供了一个包含丰富环境条件下的卡车特定挑战&#xff0c;如拖车遮挡、新型传感器视角和…

基于微信小程序的实习管理系统(附源码,文档)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

mp3格式音频怎么做成二维码?扫码获取音频文件的制作方法

随着二维码的广泛使用&#xff0c;现在很多内容都会通过生成二维码的方式来传输内容&#xff0c;通过这种方式可以更快捷的实现内容分享&#xff0c;简化其他人获取内容的流程&#xff0c;有效提高效率。音频是目前常见的一种内容分享方式&#xff0c;比如录音、听力、音乐等类…

山东布谷科技:关于直播源码|语音源码|一对一直播源码提交App Store的流程及重构建议

自从YY、六间房开启国内聊天室和秀场等网红盛行的网络红利时代以来&#xff0c;紧随其后国内各大音视频平台相应出现&#xff0c;先有映客花椒等直播平台的风头正劲&#xff0c;后有功能板块更丰富的头条抖音Tiktok等&#xff0c;盈利功能点不仅仅有直播PK连麦等礼物打赏功能&a…

【NOIP普及组】统计单词数

【NOIP普及组】统计单词数 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 一般的文本编辑器都有查找单词的功能&#xff0c;该功能可以快速定位特定单词在文章中的位置&#xff0c;有的还能统计出特定单词在文章中出现的次数。 现在&#x…

ArkTs语言常用数据类型和使用说明及示例(9种常用,7种非常用)

具体请前往&#xff1a;ArkTs语言基本数据类型及使用说明--包括9种常用变量类型和7种非常用类型

“双十一”电商狂欢进行时,在AI的加持下看网易云信IM、RTC如何助力商家!

作为一年一度的消费盛会&#xff0c;2024年“双十一”购物狂欢节早已拉开帷幕。蹲守直播间、在主播热情介绍中点开链接并加购&#xff0c;也已成为大多数人打开“双11”的重要方式。然而&#xff0c;在这火热的购物氛围背后&#xff0c;主播频频“翻车”、优质主播稀缺、客服响…

机器学习中的分类:决策树、随机森林及其应用

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

ETL架构怎么选?全量、增量还是实时流式?

一、 ETL &#xff1a; 基本定义&#xff1a;ETL 是将业务系统的数据经过抽取&#xff08;Extract&#xff09;、清洗转换&#xff08;Transform&#xff09;之后加载&#xff08;Load&#xff09;到数据仓库的过程&#xff0c;目的是将企业中分散、零乱、标准不统一的数据整合…

特色3D打印机stm32迷你8轴双核心主板

我自己设计的3D打印机主板 1. 这是一块迷你的8轴主板, 主板尺寸为100mm*75mm, 使用一个8cm静音风扇散热足够了2. 这是一个带有保护的板子, 驱动上的gpio具有过压保护功能, 能够直接抗住24V的冲击, 意味着一个驱动炸了, 板子不烧, 并且其他的驱动也没事, 主板支持自动关机3. 8…

【2】GD32H7xx 串口Idle + DMA接收不定长数据

目录 1. IDLE中断相关介绍2. D-Cache与DMA同时使用2.1 I-Cache与D-Cache2.2 D-Cache与DMA同时使用时的数据一致性问题2.2.1 CPU读取DMA写入到SRAM的数据2.2.2 DMA读取CPU写入到SRAM的数据 3. Uart Idle DMA收发程序4. 程序测试 1. IDLE中断相关介绍 在 GD32H7xx MCU 中&#…

证书学习(六)TSA 时间戳服务器原理 + 7 个免费时间戳服务器地址

目录 一、简介1.1 什么是时间戳服务器1.2 名词扩展1.3 用时间戳标记顺序1.4 7 个免费TSA时间戳服务器地址(亲测可用)1.5 RFC 3161 标准二、时间戳原理2.1 时间戳服务工作流程2.2 验证工作流程2.3 举个例子2.4 时间戳原理总结三、代码实现3.1 curl 命令请求时间戳3.2 java 代码…

一步一步从asp.net core mvc中访问asp.net core WebApi

"从asp.net core mvc中访问asp.net core WebApi"看到这个标题是不是觉得很绕口啊&#xff0c;但的确就是要讲一讲这样的访问。前面我们介绍了微信小程序访问asp.net core webapi(感兴趣的童鞋可以看看前面的博文有关WEBAPI的搭建)&#xff0c;这里我们重点不关心如何…

信捷 XD PLC C语言 FB和FC 不同

信捷 XD PLC 的C语言下 FB和FC 的使用&#xff0c;如果你有困惑&#xff0c;本文可能会帮到你&#xff01; 调用FB要带后缀_Body的&#xff0c;这个地方很容易忽视和出错。 不同之处FBFC可以在全局变量表中建立此类型对象可以1个&#xff0c;也可以多个不可以参数类型及数量有…