云音乐大模型 Agent 探索实践

news2024/12/24 7:12:23

一. 前言

本篇文章介绍了大语言模型时代下的 AI Agent 概念,并以 LangChain 为例详细介绍了 AI Agent 背后的实现原理,随后展开介绍云音乐在实践 AI Agent 过程中的遇到的问题及优化手段。通过阅读本篇文章,读者将掌握业界主流的 AI Agent 实现原理及实践优化手段,对应用自研 AI Agent 或理解 Open AI 最新提出的 Assistants API 都具有一定的参考价值。

二. AI Agent 简介

2.1 什么是 AI Agent ?

相信阅读这篇文章的读者,都在今年感受到了大语言模型带来的爆炸影响力,也都有过与之直接进行交互的使用经历,感受到了它的强大和无所不知。

但大语言模型也存在一些限制,比如:

  • 他的数学计算能力相对薄弱,对于复杂的运算可能会出现错误。(如问 3457 * 43216 = ?,它可能会回答 149,623,912。这是错的正确答案是 149,397,712)

  • 训练的数据集不包含近期的数据,所以无法直接知道最近的天气和最近发生的新闻。(OpenAI 近期推出的 gpt-4-1106-preview 的训练数据集更新至23年4月)

图片

区别于直接与大语言模型进行对话,AI Agent 是通过工程化的手段,为大语言模型提供了获取外部工具、知识的能力。他是介于人类、大语言模型之间的代理。当用户向 AI Agent 输入问题时,AI Agent 可以使用大语言模型作为推理引擎,将一个复杂的任务进行分解、给出任务执行规划。之后 Agent 会调用外部工具获取结果,并将大语言的上次推理和工具调用结果返回给大语言模型,让大语言模型继续思考、规划。如此循环,直到将一个复杂的任务完成。

图片

基于以上的理解,我们可以给 AI Agent 下一个定义:

他是人与大模型之间的智能代理,在接到任务时,它会使用大语言模型作为推理引擎,进行自主的任务规划、执行调度。

2.2 AI Agent 的应用场景

AI Agent 又有哪些应用场景呢?在《AI Agent 的千亿美金问题》这篇文章中,作者详细介绍了 AI Agent 的应用场景,笔者从中引用3个大家可能比较熟悉的例子:

1. AI 辅助编程场景

Cursor

Cursor 将自己的产品称为 AI-first IDE,其产品 UI 与 VS Code 接近,加入了很多 LLM 原生的 feature,比 Github Copilot 能做得更深入。可以认为是 AI agent 化的 VS Code + Github Copilot.

Vercel v0

v0 是由 Vercel 团队打造的 AI 前端代码生成工具。其使用过程非常直接:用户使用自然语言描述需求,v0 根据需求描述来生成组件代码。然后用户继续对不满意的地方提出修改意见,将其迭代为 v1、v2… 直到满足用户的要求。当用户想将一个生成网页的标题改为渐变色时,只需要选择标题部分并提出“增加一个渐变色”,产品便会只对这一部分代码进行修改。图片

2. 个人助理类场景

Lindy.AI

Lindy.ai 是一款基于办公场景的智能个人AI助手产品,帮助用户智能化处理日常办公任务。它可以帮人类做日程规划预定、邮件起草发送、会议纪要撰写和总结等。

图片

技术交流

建了技术交流群!想要进交流群、获取如下原版资料的同学,可以直接加微信号:dkl88194。加的时候备注一下:研究方向 +学校/公司+CSDN,即可。然后就可以拉你进群了。

方式①、添加微信号:dkl88194,备注:来自CSDN + 技术交流
方式②、微信搜索公众号:Python学习与数据挖掘,后台回复:加群

资料1
在这里插入图片描述

资料2
在这里插入图片描述

三. 如何来构建 AI Agent ?

对 AI Agent 做了简要的介绍后,我们接着来看,如何构建 AI Agent?目前市面上比较火的 Agent 相关的项目有 AutoGPT、BabyAGI、LangChain 等。

  • AutoGPT 在今年3月份发布后取得了惊人的增长,目前已经是一个 152k start 的项目。

  • BabyAGI 则提出了 Plan and execute Agent,他的实现方式是: 一次性对任务做全局的规划,后续严格一步步执行,不再变更任务计划。

  • LangChain 则是一个通用的大语言模型应用层开发框架,提供了 Python、TS 两种语言库,内置各种 LLM 工具,在 Agent 领域,它也提供了多种 Agent 的实现思路,包括了 AutoGPT、BabyAGI 的实现,本文选择 LangChain 展开介绍。

图片

3.1 LangChain Agent 使用示例

前文提到 LLM 不擅长解决复杂数学计算,我们接着来看 LangChain 使用外部工具来增强 LLM 的数学运算能力的官方示例。本示例的用户提问是: “5~10之间的随机数的平方是多少?” 。

一共分为4大步:

图片

  1. 初始化大语言模型接口,可以传入 modelName、temperature、maxTokens 等参数。

  2. 初始化工具列表,示例中使用了一个 LangChain 内置的计算器工具,以及动态构建工具。我们重点来看下这个动态生成工具:

  3. name 是工具的名字

  4. description 是工具的介绍,是供大语言模型理解的。

  5. schema 是工具的入参定义 ,这里定义了 low 和 hight 都是数字类型,分别代表 随机数的 下界 和 上界。

  6. func 是工具的方法调用定义,参数是 schema 中的定义,函数体是一段 js 随机数生成代码。

  7. 有了工具和大语言模型接口后,随后构造出了 Agent 执行器。

  8. 最后一步是将用户的输入传给 Agent 执行器。

最后输出的随机数平方是 45.067

3.2 LangChain Agent 执行步骤拆解

在本地执行的过程中,Langchain 会输出详细的执行调度日志,如下图所示:图片图片

通过分析这些日志可以揭开 Langchain Agent 背后的运行原理。

执行步骤一: 调用大语言模型

如下图所示, Agent 执行的第一步是将用户的输入与一个系统的 prompt 进行组装,我们暂时先称其为 “魔法咒语”,后续会详细介绍。大语言模型会返回他的思考: “用户的问题是 5~10之间的随机数的平方。我可以使用「随机数生成工具」先生成一个随机数,然后使用计算器工具计算它的平方。” 并以 JSON 指示下一步采取的动作是: 调用「随机数生成工具」,入参为 low 5, high 10。

图片

执行步骤二: 调用工具-随机数生成器

接着 Agent 执行器 会调用「随机数生成工具」入参为 {low:5, hight:10},工具返回 6.7132

图片

执行步骤三: 调用大语言模型

如下图所示,Agent 执行器会把用户的原始问题,和上一步大语言模型的思考、工具调用和工具的输出做拼接,传给大语言模型继续思考。大语言模型回复说: 随机数是 6.71…,现在我可以使用计算器工具来计算它的平方值。并使用 JSON 格式指示下一步动作是: 调用计算器工具,入参是 6.71…的平方的数学描述。图片

执行步骤四: 调用工具 计算器

接着 Agent 执行器 会调用 计算器工具,入参为 6.71...^2,计算器工具返回的结果为 45.06..

图片

执行步骤五: 调用大语言模型

如下图所示: Agent 执行器将上一步的思考、工具调用、结果做拼接,传递给大语言模型继续思考。大语言模型回复说: 我知道了最终的结果,答案是 45.067图片

当我第一次运行 Agent 示例,看到 Agent 能如此丝滑地一步步思考,执行外部工具,并得到最终结果时,我非常惊叹于 Agent 的能力,也十分好奇背后的原理的是什么。经过一番探索,发现其核心原理就藏在魔法咒语里。我们接着来看这里的魔法咒语是什么?

3.3 LangChain Agent 的魔法咒语

魔法咒语片段一

魔法咒语是由多个片段组成,片段一指示了大语言模型可以使用一些工具,但必须要遵循工具的 JSON Schema,然后给出了 合法的 JSON Schema 示例。紧接着给出了大语言模型可用的工具介绍,包含工具的名字、工具的描述和入参的 JSON Schema。

图片

魔法咒语片段二

片段二主要指示大语言模型如何使用工具。需要通过一个 JSON markdown 格式包裹,包含 action 和 action_input 字段,action 必须为 Final Answer 或 工具名。并给出了 Action 的示例。图片

魔法咒语片段三

我们知道大语言模型是生成式 AI,而片段三指示了大语言模型生成的内容需要遵循的段落结构。分别是:

  • Question 问题是什么

  • Thought 思考如何去解决

  • Action 下一步采取的行动

  • Observation: 行动的结果

并指示生成的思考、行动、结果 是可以重复 N 次的。并指示 LLM 在知道最终的结果后,输出 Final Answer。

这一段是大语言模型能将复杂任务分解、逐步执行、继续思考如此循环的关键。而这一思考框架称为 ReAct。

图片

知道了 LangChain 背后的魔法咒语后,我们能否直接在 ChatGPT 中直接输入魔法咒语试下效果呢?答案是可以的。

我们把这段魔法咒语直接复制到 ChatGPT 上。我们看到大模型确实按照 Thought、Action、Observation 的段落格式进行生成输出。

图片

但好像又有点问题,他返回的结果和此前步骤拆解中的步骤一不太一样。步骤一只返回 需要调用「随机数生成器工具」,随后 Agent 会介入工具调用,完成工具调用后再交由大语言模型进行思考,而这里大语言模型直接返回了后续的工具调用结果、下一步思考、下一步的行动,在多步重复后,把一个错误的结果输出给我们了,那么问题出在了哪里呢?

事实上在 Agent 执行器调用大语言模型时,有一个关键的参数 Stop Sequences,这个参数的作用是让大语言模型在准备生成这个词前就强制停住,不再往下生成。

Agent 会传入 Observation 作为这个参数的值,意思就是让大语言模型生成到 Observation 时就强制停止,这样控制权才会转交回给 Agent,Agent 可以继续调用外部工具、执行后续的步骤。

我们在 ChatGPT 上加上这个参数,这一次大语言模型的输出就符合预期了。以上就是 LangChain Agent 的核心原理。

图片

四. 云音乐 Adora 平台在 Agent 方面的实践

Adora 是网易云音乐内部的智能数字助理搭建平台,提供 LLM 相关服务。内置专属 Chat UI 界面、配置中心,可轻松实现知识库管理、智能问答、意图识别、行为翻译等功能。帮助用户快速构建属于自己的智能助手。我们后续也会有文章介绍 Adora,各位读者敬请期待。

4.1 基础能力整合

接着我们来看云音乐 Adora 平台在 Agent 方面的实践。首先是基础能力整合。

步骤一

我们还是基于这段官方示例进行扩展。这里的 ChatOpenAI 是 LangChain 提供的大语言模型接口,底层是调用的 OpenAI 官方 Client。由于各种原因,我们无法直接使用,所以要做下替换。

图片

得益于 LangChain 的面向对象封装,我们只需继承 LangChain 的 ChatOpenAI 类,重写其中的一个函数即可。将 OpenAI 官方 Client 调用 替换为内部封装的 gpt-client 即可。

图片

步骤二

第二步是将 Adora 平台在线录入的服务转换为 LangChain 的 Tools。我们在 Adora 原有的服务定义上,增加了 description_for_ai 字段,以及 input_params 字段,有了这些配置,我们就可以将 Adora 在线录入的服务,转换为 LangChain 的 Tool。图片

做完了以上的两步,再加上一些胶水代码,我们就为 Adora 平台整合入了 Agent 的能力。

Adora 平台的用户在创建 Agent 智能体时,只需在可视化界面上,选择 Agent智能体动作,并圈选这个Agent 所需的服务,即可完成一个 Agent 的构建。图片

在完成基础能力的整合后,我们还遇到了哪些问题,以及做了哪些优化呢?

4.2 问题及优化手段

问题1: 如何高效地调试 Agent ?

我们此前提到 Agent 在执行时会输出日志,对于我们理解 Agent 的执行逻辑很有帮助,但这些日志也存在一些冗余的信息,并且是平铺式的,难以快速提炼关键信息。图片

我们做的第一步是将这些输出日志做采集、提炼。将 Agent 的执行步骤,归纳为关键的 Thought 和 Tool 两大步骤,并以结构化的方式在前端做呈现。

如下图所示,在 Thought 中我们会展示此次调用大语言模型的 system prompt、human input,以及大语言模型的回答,并展示出整体的耗时。

图片

在 Tool 环节,会展示 Agent 使用的工具、耗时。以及工具的入参和出参。

图片

图片

通过结构化的展示,我们将 Agent 执行的每一步,都可视化呈现在开发者眼前,若 Agent 的思考出错或工具调用传参不对,开发者都可以及时看到,并通过改进 prompt 优化整体效果。

值得一提的是 LangChain 官方出品的开发者平台 LangSmith,也将 Agent 的执行可视化作为了关键特性在宣传,可见可视化调试的重要性。图片

问题2: 如何解决 Agent 执行的异常中断

我们在调试过程中发现,当 LLM 返回的 action_input 不符合工具的 schema 定义时,Agent 会执行抛错,中断整体执行逻辑。此外在外部接口调用返回异常时,tool 也会直接抛错,导致 Agent 的整体执行逻辑中断。

举例来说,正常情况下使用 「会议室查询」服务,需要有 buildingName、bookDay 两个参数,我们也在 Prompt 中提示了大语言模型这两个字段为必填项。

但 LLM 由于上下文信息过多,可能会出现遗忘的现象。导致输出的结果中,遗漏了 buildingName 字段。当前 LangChain 的默认处理是当 Schema 校验不通过时,直接抛错,这样 Agent 的执行就结束了。

图片

我们的优化做法是改写 DynamicStructuredTool 逻辑,在入参不符合预期时,不直接抛错,而是给 LLM 返回错误提示,让其继续思考。这样 LLM 在看到上一次工具的输入、错误提示后,在下次思考时,就会尝试纠正自己,给出正确的工具入参。具体的改写代码如下所示:

图片

同理在接口调用环节,如果遇到外部返回异常时,也可以采样同样的思路进行优化。比如会议预定接口,假设接口调用时传入了一个已被占用的时段,后端接口响应就会返回 { code: 400 ,message: 该时段已被占用} , 此时在 request 中,遇到返回码非 200 时,不直接抛错,而是包装一个错误信息返回给 LLM,这样 LLM 在下次思考时,也会纠正自己,尝试给出合理的工具入参。参考代码如下所示:

图片

问题3 如何让 Agent 请求用户协助?

我们此前提到,Agnet 的执行过程,只有思考、工具调用的重复循环,直到给出任务执行的最终结果。中间没有留给用户介入的机会。

图片

但我们在一些场景,我们是希望能有用户介入的机会,比如在订咖啡、订会议室的场景,在上下文信息不足时,我们希望 Agent 能够向用户去征集偏好、选项,而不是自行决策,一条路走到黑,导致预定失败。

我们的做法是: 首先调整工具的描述,告知 LLM 在不知道参数时,需要向用户提问。

图片

但只靠这一步,效果并不好,有时 LLM 的输出会不符合 Action 格式要求,所以我们还对系统提示词做了逐步的调整,以强化对 LLM 的提醒。

图片

通过以上的 Prompt 优化,现在当输入 「今天下午有哪些会议室?」时,大语言模型会回复「请问您想要查询1号楼、2号楼还是3号楼的会议室?」。现在大语言能够正确地向用户提问了,把控制权交给了用户,后续用户回答 「2号楼」时,我们只需将上一轮的对话作为记忆带到下一轮的 Agent 执行中,就达成了人工介入 Agent 补充信息的效果。以会议室预定为例,详细的步骤如下所示:

图片

最终实现的效果:

图片

我们通过可视化调试界面加深下理解: 在第三轮对话的第一个 Thought 环节。第一条 system 为系统提示词,后续的 human、ai、human、ai 是前两轮的对话记忆,最后一个 human 才是第三轮对话的用户输入,这6消息整体作为入参 messages 发送给 LLM ,最后一条 ai 是这次调用 LLM 的返回结果。

图片

会议预定 Agent 完整执行步骤如下:

图片

图片

图片

图片

问题4 模型推理能力、响应速度

在实践中,我们遇到的最大问题是模型的推理能力与响应速度无法兼得。举例来说,当我以 「帮我预定2号楼7楼 今天下午 3点到5点的会议室」 这个问题进行测试时,gpt-4.0-0613 模型分别以 19.07秒、24.78秒、19.01 秒完成任务,中间没有任何步骤推理出错。而使用 gpt-3.5-turbo-0613 模型时,在第一次测试时,Agent 调用的 tool 并不存在,导致任务失败,第二次测试时,Agent 第一步调用 tool 仍然不存在,但在第二步思考时,Agent 进行了纠正,整体完成任务耗时为 13.51秒。第三次测试时,Agent 一次性完成了任务,仅耗时 8.09秒。

下图为 gpt-3.5-turbo-0613 第二轮测试效果:

图片

整体测试总结来看,gpt4.0-0613 可以以100%的正确率完成任务,但平均解题耗时需要 20+秒,而 gpt-3.5-turbo-0613 虽然任务完成率只有 66% ,但整体耗时仅为 10.8秒。

图片

对于 gpt-4 的推理能力更强,应该是符合我们大家直觉的,但耗时更久却有点反直觉。我们随后查看了官方的文档,在文档中可以看到,gpt-4 的 出字速度确实是比 gpt-3.5 要慢上几倍,这是符合官方预期的。

图片

受限于推理能力、响应速度难以兼得。当下想要将 Agent 正式投入生产环境,还是有一些挑战的。比如当我们把会议预定、咖啡预定 Agent 在公司 1024 的活动上推出时,部分用户身上表现出了一定的等待焦虑:「为什么还没有反应」「我还要等多久」「是不是挂了」。

在这里工程上能做的优化可能比较有限,比如除了 Loading 外,我们可以加入一些其他的响应提示,如 Agent 目前的思考步骤,以缓解用户的焦虑。

整体上,推理能力与速度的同步提升,还是较大依赖大模型厂商的逐步优化。正如 OpenAI 最新发布的 gpt-4-turbo-1106 在响应速度上就已经有了一些提升。我们相信随着推理能力和响应速度的提升,基于大语言模型实现的 AI Agent 在不远的未来会有大规模的落地的可能。

图片

五. 总结

在 11 月的 OpenAI 的开发者大会上,官方同时也发布了最新的 Assistants API ,为构建 AI Agent 提供了官方支持,使得 AI Agent 的构建更加简单、高效。虽然官方的方案可能会演变为最终方案,但我们相信对 LangChain Agent 的实践不会白费,他会加深我们对 Agent 发展脉络的理解,而且使用过后,我们就会发现 Assistants API 的封装 与 LangChain Agent 有许多共通之处。我们后续也会对此进行跟进、实践,请大家继续关注我们,我们会第一时间分享我们的实践经验。

引用

  • LangChain Agent 示例

  • Assistants API

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

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

相关文章

【C进阶】C程序是怎么运作的呢?-- 程序环境和预处理(下)

前言: 这是程序环境和预处理的下半篇文章。至此,关于c语言知识点:从编译到运行的过程已讲解完毕。传送🚪,上半篇: http://t.csdnimg.cn/hvxmr 本章涉及的知识点: 宏和函数对比、命名约定、#undef、命令行定…

【算法每日一练]-结构优化(保姆级教程 篇5 树状数组)POJ3067日本 #POJ3321苹果树 #POJ2352星星 #快排变形

目录 今天知识点 求交点转化求逆序对,每次操作都维护一个y点的前缀和 树的变动转化成一维数组的变动,利用时间戳将节点转化成区间 离散化数组来求逆序对数 先将y排序,然后每加入一个就点更新求一次前缀和 POJ3067:日本 思路&…

关于学习计算机的心得与体会

也是隔了一周没有发文了,最近一直在准备期末考试,后来想了很久,学了这么久的计算机,这当中有些收获和失去想和各位正在和我一样在学习计算机的路上的老铁分享一下,希望可以作为你们碰到困难时的良药。先叠个甲&#xf…

scala编码

1、Scala高级语言 Scala简介 Scala是一门类Java的多范式语言,它整合了面向对象编程和函数式编程的最佳特性。具体来讲Scala运行于Java虚拟机(JVM)之上,井且兼容现有的Java程序,同样具有跨平台、可移植性好、方便的垃圾回收等特性…

大数据技术6:大数据技术栈

前言:大数据相关的技术名词特别多,这些技术栈之间的关系是什么,对初学者来说很难找到抓手。我一开始从后端转大数据的时候有点懵逼,整体接触了一遍之后才把大数据技术栈给弄明白了。 一、大数据技术栈 做大数据开发,无…

12.12作业

头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QtTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECT…

Linux:gdb的简单使用

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、前置理解二、使用总结 前言 gdb是Linux中的调试代码的工具 一、前置理解 我们都知道要调试一份代码&#xff0c;这份代码的发布模式必须是debug。那你知道在li…

揭秘高效大型语言模型:技术、方法与应用展望

近年来&#xff0c;大型语言模型&#xff08;LLMs&#xff09;在自然语言处理领域取得了显著的进展&#xff0c;如GPT-series(GPT-3, GPT-4)、Google-series(Gemini, PaLM), Meta-series(LLAMA1&2), BLOOM, GLM等模型在各种任务中展现出惊人的能力。然而&#xff0c;随着模…

2-Spring

2-Spring 文章目录 2-Spring项目源码地址Spring概述Spring特点&#xff08;优点&#xff09;Spring相关学习网站基于Maven的Spring框架导入Spring的组成及拓展 Spring-IOC--原型理解IOC-原型--示例开发示例-常规开发示例-Set函数&#xff08;IOC原型&#xff09;开发示例-对比思…

【热】如何实现el-table列宽随内容长度自适应最小宽度

非常火急火燎的来写这篇博客&#xff01;&#xff01;因为自己一开始想实现这个效果时在网上查了很久查了很多资料和博客都没有找到能有效达到效果的方法&#xff0c;要么就是别人说有效但是我这里会报错而且难以解决。最后终于被我自己给摸索出来了&#xff01; 应用场景 很…

AI+无代码助力企业供应链优化

内容来自演讲&#xff1a;潘峰 | 预见明日科技&#xff08;北京&#xff09;有限公司 | CEO 摘要 本文介绍了企业供应链中的挑战和解决方案。文章指出&#xff0c;供应链成本占企业经营成本的大部分&#xff0c;且存在供给端和需求端的高度不确定性。为应对这种不确定性&…

Openwrt源码下载出现“The remote end hung up unexpected”

最近项目原因需要下载openwrt21.02版本源码&#xff0c;花费了很多时间&#xff0c;找到正确方法后&#xff0c;发现可以节省很多时间&#xff0c;记录下过程&#xff0c;方便自己&#xff0c;可能方便他人。 一.问题阐述 openwrt21.02下载链接如下&#xff1a; git clone -…

Uncaught ReferenceError: jQuery is not defined解决方法

当我在写java的Maven项目时&#xff0c;出现了这样的一个报错信息&#xff1a; 我一直找代码&#xff0c;抓包&#xff0c;调试&#xff0c;比对代码 jQuery未定义就是指JS的导包没有导进来&#xff01;&#xff01;&#xff01;&#xff01; 导进来就运行正常啦

12.字符串拼接【2023.12.4】

1.问题描述 我们在编程过程中经常会遇到把不同字符串拼接在一起的情况&#xff0c;从而更直观地展示给用户我们所要表达的信息。本题将给出两个字符串&#xff0c;请依次将这两个字符串拼接在一起。 2.解决思路 用字符串拼接符 进行连接两个字符串 3.代码实现 str1input(…

SpringBoot中MyBatis-Flex的集成和使用

一、MyBatis-Flex 是什么​ MyBatis-Flex是一个基于MyBatis的数据访问框架&#xff0c;专门为Flex应用程序而设计的。它提供了一种灵活而高效的方式来处理Flex应用程序中的数据访问&#xff0c;可以轻松地连接到各种数据源&#xff0c;并提供了一些方便的工具和功能&#xff0c…

2023.12.6-12.11 黑马知行教育项目实战,访问咨询意向线索主题

目录 简单介绍: 一.项目背景介绍 二.项目架构介绍 三.项目内容 3.1访问和咨询分析主题: 3.1.1 表与表之间的关联 3.1.2访问咨询主题需求汇总:最终需在ADS层制作六张表 3.1.3 访问咨询DWS大宽表建表与导入数据 3.2意向线索主题需求分析 3.2.1意向线索主题需求汇总:最终需在…

最新科研成果:在钻石中存储多比特数据,实现25GB数据密度

近日&#xff0c;纽约城市大学&#xff08;CUNY&#xff09;的研究人员已经成功地利用钻石原子结构中的小型氮缺陷作为“颜色中心”来写入数据进行存储&#xff08;然后是检索&#xff09;。这项发表在《自然纳米技术》上的技术允许通过将数据编码为多个光频率&#xff08;即颜…

[GFCTF 2021]文件查看器

文章目录 前置知识可调用对象数组对方法的调用GC回收机制phar修改签名 解题步骤 前置知识 可调用对象数组对方法的调用 我们先来看下面源码 <?phperror_reporting(0);class User{public $username;public $password;public function check(){if($this->username"…

架构LAMP

目录 1.什么是LAMP 2.LAMP组成及作用 3.搭建Apache httpd服务 4.编译安装mysqld 服务 5.编译安装PHP 解析环境 6.安装论坛 1.什么是LAMP LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整套系统和相关软件&#xff0c;能够提供动态Web站点服务…

Threejs项目实战之一:汽车外观换肤效果三维展示

目录 最终效果1 创建项目2 安装插件3 编写代码3.1 准备工作3.2 代码编写3.2.1 在template标签中构建html页面3.2.2 在style标签中构建页面样式文件3.2.3 在script标签中编写js代码 最终效果 先看下最终实现的效果 接下来&#xff0c;我们就从创建项目开始&#xff0c;一步一步…