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

【AI大模型】GPTS 与 Assistants API

前言

          2023 年 11 月 6 日,OpenAI DevDay 发表了一系列新能力,其中包括:GPT Store 和 Assistants API。

GPTs 和 Assistants API 本质是降低开发门槛

可操控性和易用性之间的权衡与折中:

  1. 更多技术路线选择:原生 API、GPTs 和 Assistants API
  2. GPTs 的示范,起到教育客户的作用,有助于打开市场
  3. 要更大自由度,需要用 Assistants API 开发
  4. 想极致调优,还得原生 API + RAG
  5. 国内大模型的 Assistants API,参考 Minimax

Assistants API 的主要能力

已有能力:

  1. 创建和管理 assistant,每个 assistant 有独立的配置
  2. 支持无限长的多轮对话,对话历史保存在 OpenAI 的服务器上
  3. 通过自有向量数据库支持基于文件的 RAG
  4. 支持 Code Interpreter
    1. 在沙箱里编写并运行 Python 代码
    2. 自我修正代码
    3. 可传文件给 Code Interpreter
  5. 支持 Function Calling
  6. 支持在线调试的 Playground

承诺未来会有的能力:

  1. 支持 DALL·E
  2. 支持图片消息
  3. 支持自定义调整 RAG 的配置项

收费:

  1. 按 token 收费。无论多轮对话,还是 RAG,所有都按实际消耗的 token 收费
  2. 如果对话历史过多超过大模型上下文窗口,会自动放弃最老的对话消息
  3. 文件按数据大小和存放时长收费。1 GB 向量存储 一天收费 0.10 美元
  4. Code interpreter 跑一次 $0.03

创建一个 Assistant

可以为每个应用,甚至应用中的每个有对话历史的使用场景,创建一个 assistant。

虽然可以用代码创建,也不复杂,例如:

from openai import OpenAI# 初始化 OpenAI 服务
client = OpenAI()# 创建助手
assistant = client.beta.assistants.create(name="小U",instructions="你叫小U,你是JAVA技术框架 UAP的助手,你负责回答用户关于UAP的问题。",model="gpt-4-turbo",
)

但是,更佳做法是,到 Playground 在线创建,因为:

  1. 更方便调整
  2. 更方便测试

样例 Assistant 的配置

Instructions:

你叫小U,你是JAVA技术框架 UAP的助手,你负责回答用户关于UAP的问题。

Functions:

{"name": "ask_database","description": "Use this function to answer user questions about course schedule. Output should be a fully formed SQL query.","parameters": {"type": "object","properties": {"query": {"type": "string","description": "SQL query extracting info to answer the user's question.\nSQL should be written using this database schema:\n\nCREATE TABLE Courses (\n\tid INT AUTO_INCREMENT PRIMARY KEY,\n\tcourse_date DATE NOT NULL,\n\tstart_time TIME NOT NULL,\n\tend_time TIME NOT NULL,\n\tcourse_name VARCHAR(255) NOT NULL,\n\tinstructor VARCHAR(255) NOT NULL\n);\n\nThe query should be returned in plain text, not in JSON.\nThe query should only contain grammars supported by SQLite."}},"required": ["query"]}
}

代码访问 Assistant

管理 thread

Threads:

  1. Threads 里保存的是对话历史,即 messages
  2. 一个 assistant 可以有多个 thread
  3. 一个 thread 可以有无限条 message
  4. 一个用户与 assistant 的多轮对话历史可以维护在一个 thread 里
import jsondef show_json(obj):"""把任意对象用排版美观的 JSON 格式打印出来"""print(json.dumps(json.loads(obj.model_dump_json()),indent=4,ensure_ascii=False))

from openai import OpenAI
import osfrom dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())# 初始化 OpenAI 服务
client = OpenAI()   # openai >= 1.3.0 起,OPENAI_API_KEY 和 OPENAI_BASE_URL 会被默认使用# 创建 thread
thread = client.beta.threads.create()
show_json(thread)
{"id": "thread_zkT0xybD8VslhJzJJNY3IHuX","created_at": 1716553797,"metadata": {},"object": "thread","tool_resources": {"code_interpreter": null,"file_search": null}
}

可以根据需要,自定义 metadata,比如创建 thread 时,把 thread 归属的用户信息存入。

thread = client.beta.threads.create(metadata={"fullname": "王卓然", "username": "taliux"}
)
show_json(thread)
{"id": "thread_1LMmbLMx2ZrRQjymDOGQGYGX","created_at": 1716553801,"metadata": {"fullname": "王卓然","username": "taliux"},"object": "thread","tool_resources": {"code_interpreter": null,"file_search": null}
}

Thread ID 如果保存下来,是可以在下次运行时继续对话的。

从 thread ID 获取 thread 对象的代码:

thread = client.beta.threads.retrieve(thread.id)
show_json(thread)
{"id": "thread_1LMmbLMx2ZrRQjymDOGQGYGX","created_at": 1716553801,"metadata": {"fullname": "王卓然","username": "taliux"},"object": "thread","tool_resources": {"code_interpreter": {"file_ids": []},"file_search": null}
}

此外,还有:

  1. threads.modify() 修改 thread 的 metadata 和 tool_resources
  2. threads.retrieve() 获取 thread
  3. threads.delete() 删除 thread。

具体文档参考:https://platform.openai.com/docs/api-reference/threads

给 Threads 添加 Messages

这里的 messages 结构要复杂一些:

  1. 不仅有文本,还可以有图片和文件
  2. 也有 metadata
message = client.beta.threads.messages.create(thread_id=thread.id,  # message 必须归属于一个 threadrole="user",          # 取值是 user 或者 assistant。但 assistant 消息会被自动加入,我们一般不需要自己构造content="你都能做什么?",
)
show_json(message)

{"id": "msg_wDZxbO2oi2rAvk9Yxgqw0hVP","assistant_id": null,"attachments": [],"completed_at": null,"content": [{"text": {"annotations": [],"value": "你都能做什么?"},"type": "text"}],"created_at": 1716553809,"incomplete_at": null,"incomplete_details": null,"metadata": {},"object": "thread.message","role": "user","run_id": null,"status": null,"thread_id": "thread_1LMmbLMx2ZrRQjymDOGQGYGX"
}

还有如下函数:

  1. threads.messages.retrieve() 获取 message
  2. threads.messages.update() 更新 message 的 metadata
  3. threads.messages.list() 列出给定 thread 下的所有 messages

具体文档参考:https://platform.openai.com/docs/api-reference/messages

也可以在创建 thread 同时初始化一个 message 列表:

thread = client.beta.threads.create(messages=[{"role": "user","content": "你好",},{"role": "assistant","content": "有什么可以帮您?",},{"role": "user","content": "你是谁?",},]
)show_json(thread)  # 显示 thread
print("-----")
show_json(client.beta.threads.messages.list(thread.id))  # 显示指定 thread 中的 message 列表
{"id": "thread_Qf32rY62YZrpW8d3nEm51mLn","created_at": 1716553813,"metadata": {},"object": "thread","tool_resources": {"code_interpreter": null,"file_search": null}
}
-----
{"data": [{"id": "msg_MkAm2f87yE3ynnLOzXCLq5XR","assistant_id": null,"attachments": [],"completed_at": null,"content": [{"text": {"annotations": [],"value": "你是谁?"},"type": "text"}],"created_at": 1716553813,"incomplete_at": null,"incomplete_details": null,"metadata": {},"object": "thread.message","role": "user","run_id": null,"status": null,"thread_id": "thread_Qf32rY62YZrpW8d3nEm51mLn"},{"id": "msg_tTgI3MS6t19pzQM7ItFJkZaA","assistant_id": null,"attachments": [],"completed_at": null,"content": [{"text": {"annotations": [],"value": "有什么可以帮您?"},"type": "text"}],"created_at": 1716553813,"incomplete_at": null,"incomplete_details": null,"metadata": {},"object": "thread.message","role": "assistant","run_id": null,"status": null,"thread_id": "thread_Qf32rY62YZrpW8d3nEm51mLn"},{"id": "msg_imlUh5ckePY0SaBmE6dDB3AY","assistant_id": null,"attachments": [],"completed_at": null,"content": [{"text": {"annotations": [],"value": "你好"},"type": "text"}],"created_at": 1716553813,"incomplete_at": null,"incomplete_details": null,"metadata": {},"object": "thread.message","role": "user","run_id": null,"status": null,"thread_id": "thread_Qf32rY62YZrpW8d3nEm51mLn"}],"object": "list","first_id": "msg_MkAm2f87yE3ynnLOzXCLq5XR","last_id": "msg_imlUh5ckePY0SaBmE6dDB3AY","has_more": false
}

开始 Run

  • 用 run 把 assistant 和 thread 关联,进行对话
  • 一个 prompt 就是一次 run

直接运行

assistant_id = "asst_pxKAiBW0VB62glWPjeRDA7mR"  # 从 Playground 中拷贝run = client.beta.threads.runs.create_and_poll(thread_id=thread.id,assistant_id=assistant_id,
)
if run.status == 'completed':messages = client.beta.threads.messages.list(thread_id=thread.id)show_json(messages)
else:print(run.status)

Run 的状态

Run 的底层是个异步调用,意味着它不等大模型处理完,就返回。我们通过 run.status 了解大模型的工作进展情况,来判断下一步该干什么。

run.status 有的状态,和状态之间的转移关系如图。

流式运行

  1. 创建回调函数
from typing_extensions import override
from openai import AssistantEventHandlerclass EventHandler(AssistantEventHandler):@overridedef on_text_created(self, text) -> None:"""响应输出创建事件"""print(f"\nassistant > ", end="", flush=True)@overridedef on_text_delta(self, delta, snapshot):"""响应输出生成的流片段"""print(delta.value, end="", flush=True)

     2. 运行 run

# 添加新一轮的 user message
message = client.beta.threads.messages.create(thread_id=thread.id,role="user",content="你说什么?",
)
# 使用 stream 接口并传入 EventHandler
with client.beta.threads.runs.stream(thread_id=thread.id,assistant_id=assistant_id,event_handler=EventHandler(),
) as stream:stream.until_done()

还有如下函数:

  1. threads.runs.list() 列出 thread 归属的 run
  2. threads.runs.retrieve() 获取 run
  3. threads.runs.update() 修改 run 的 metadata
  4. threads.runs.cancel() 取消 in_progress 状态的 run

具体文档参考:https://platform.openai.com/docs/api-reference/runs

使用 Tools

创建 Assistant 时声明 Code_Interpreter

如果用代码创建:

assistant = client.beta.assistants.create(name="Demo Assistant",instructions="你是人工智能助手。你可以通过代码回答很多数学问题。",tools=[{"type": "code_interpreter"}],model="gpt-4-turbo"
)

在回调中加入 code_interpreter 的事件响应

from typing_extensions import override
from openai import AssistantEventHandlerclass EventHandler(AssistantEventHandler):@overridedef on_text_created(self, text) -> None:"""响应输出创建事件"""print(f"\nassistant > ", end="", flush=True)@overridedef on_text_delta(self, delta, snapshot):"""响应输出生成的流片段"""print(delta.value, end="", flush=True)@overridedef on_tool_call_created(self, tool_call):"""响应工具调用"""print(f"\nassistant > {tool_call.type}\n", flush=True)@overridedef on_tool_call_delta(self, delta, snapshot):"""响应工具调用的流片段"""if delta.type == 'code_interpreter':if delta.code_interpreter.input:print(delta.code_interpreter.input, end="", flush=True)if delta.code_interpreter.outputs:print(f"\n\noutput >", flush=True)for output in delta.code_interpreter.outputs:if output.type == "logs":print(f"\n{output.logs}", flush=True)

发个 Code Interpreter 请求:

# 创建 thread
thread = client.beta.threads.create()# 添加新一轮的 user message
message = client.beta.threads.messages.create(thread_id=thread.id,role="user",content="用代码计算 1234567 的平方根",
)
# 使用 stream 接口并传入 EventHandler
with client.beta.threads.runs.stream(thread_id=thread.id,assistant_id=assistant_id,event_handler=EventHandler(),
) as stream:stream.until_done()
assistant > code_interpreterimport math# 计算 1234567 的平方根
square_root = math.sqrt(1234567)
square_rootoutput >1111.1107055554814assistant > 1234567 的平方根是约 1111.11。

Code_Interpreter 操作文件

# 上传文件到 OpenAI
file = client.files.create(file=open("mydata.csv", "rb"),purpose='assistants'
)# 创建 assistant
my_assistant = client.beta.assistants.create(name="CodeInterpreterWithFileDemo",instructions="你是数据分析师,按要求分析数据。",model="gpt-4-turbo",tools=[{"type": "code_interpreter"}],tool_resources={"code_interpreter": {"file_ids": [file.id]  # 为 code_interpreter 关联文件}}
)
# 创建 thread
thread = client.beta.threads.create()# 添加新一轮的 user message
message = client.beta.threads.messages.create(thread_id=thread.id,role="user",content="统计总销售额",
)
# 使用 stream 接口并传入 EventHandler
with client.beta.threads.runs.stream(thread_id=thread.id,assistant_id=my_assistant.id,event_handler=EventHandler(),
) as stream:stream.until_done()

关于文件操作,还有如下函数:

  1. client.files.list() 列出所有文件
  2. client.files.retrieve() 获取文件对象
  3. client.files.delete() 删除文件
  4. client.files.content() 读取文件内容

具体文档参考:https://platform.openai.com/docs/api-reference/files

创建 Assistant 时声明 Function

如果用代码创建:'''
python
assistant = client.beta.assistants.create(instructions="你叫瓜瓜。你是AGI课堂的助手。你只回答跟AI大模型有关的问题。不要跟学生闲聊。每次回答问题前,你要拆解问题并输出一步一步的思考过程。",model="gpt-4o",tools=[{"type": "function","function": {"name": "ask_database","description": "Use this function to answer user questions about course schedule. Output should be a fully formed SQL query.","parameters": {"type": "object","properties": {"query": {"type": "string","description": "SQL query extracting info to answer the user's question.\nSQL should be written using this database schema:\n\nCREATE TABLE Courses (\n\tid INT AUTO_INCREMENT PRIMARY KEY,\n\tcourse_date DATE NOT NULL,\n\tstart_time TIME NOT NULL,\n\tend_time TIME NOT NULL,\n\tcourse_name VARCHAR(255) NOT NULL,\n\tinstructor VARCHAR(255) NOT NULL\n);\n\nThe query should be returned in plain text, not in JSON.\nThe query should only contain grammars supported by SQLite."}},"required": ["query"]}}]
)
'''

 创建一个 Function

# 定义本地函数和数据库import sqlite3# 创建数据库连接
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()# 创建orders表
cursor.execute("""
CREATE TABLE Courses (id INT AUTO_INCREMENT PRIMARY KEY,course_date DATE NOT NULL,start_time TIME NOT NULL,end_time TIME NOT NULL,course_name VARCHAR(255) NOT NULL,instructor VARCHAR(255) NOT NULL
);
""")# 插入5条明确的模拟记录
timetable = [('2024-01-23', '20:00', '22:00', 'aaaaa', '张三'),('2024-01-25', '20:00', '22:00', 'bbbbbbbb', '张三'),('2024-01-29', '20:00', '22:00', 'ccccc', '张三'),('2024-02-20', '20:00', '22:00', 'dddddd', '张三'),('2024-02-22', '20:00', '22:00', 'eeeeeee', '李四'),]for record in timetable:cursor.execute('''INSERT INTO Courses (course_date, start_time, end_time, course_name, instructor)VALUES (?, ?, ?, ?, ?)''', record)# 提交事务
conn.commit()def ask_database(query):cursor.execute(query)records = cursor.fetchall()return str(records)# 可以被回调的函数放入此字典
available_functions = {"ask_database": ask_database,
}

增加回调事件的响应

from typing_extensions import override
from openai import AssistantEventHandlerclass EventHandler(AssistantEventHandler):@overridedef on_text_created(self, text) -> None:"""响应回复创建事件"""print(f"\nassistant > ", end="", flush=True)@overridedef on_text_delta(self, delta, snapshot):"""响应输出生成的流片段"""print(delta.value, end="", flush=True)@overridedef on_tool_call_created(self, tool_call):"""响应工具调用"""print(f"\nassistant > {tool_call.type}\n", flush=True)@overridedef on_tool_call_delta(self, delta, snapshot):"""响应工具调用的流片段"""if delta.type == 'code_interpreter':if delta.code_interpreter.input:print(delta.code_interpreter.input, end="", flush=True)if delta.code_interpreter.outputs:print(f"\n\noutput >", flush=True)for output in delta.code_interpreter.outputs:if output.type == "logs":print(f"\n{output.logs}", flush=True)@overridedef on_event(self, event):"""响应 'requires_action' 事件"""if event.event == 'thread.run.requires_action':run_id = event.data.id  # 获取 run IDself.handle_requires_action(event.data, run_id)def handle_requires_action(self, data, run_id):tool_outputs = []for tool in data.required_action.submit_tool_outputs.tool_calls:arguments = json.loads(tool.function.arguments)print(f"{tool.function.name}({arguments})",flush=True)# 运行 functiontool_outputs.append({"tool_call_id": tool.id,"output": available_functions[tool.function.name](**arguments)})# 提交 function 的结果,并继续运行 runself.submit_tool_outputs(tool_outputs, run_id)def submit_tool_outputs(self, tool_outputs, run_id):"""提交function结果,并继续流"""with client.beta.threads.runs.submit_tool_outputs_stream(thread_id=self.current_run.thread_id,run_id=self.current_run.id,tool_outputs=tool_outputs,event_handler=EventHandler(),) as stream:stream.until_done()

# 创建 thread
thread = client.beta.threads.create()# 添加 user message
message = client.beta.threads.messages.create(thread_id=thread.id,role="user",content="平均一堂课多长时间",
)
# 使用 stream 接口并传入 EventHandler
with client.beta.threads.runs.stream(thread_id=thread.id,assistant_id=assistant_id,event_handler=EventHandler(),
) as stream:stream.until_done()

两个无依赖的 function 会在一次请求中一起被调用

# 创建 thread
thread = client.beta.threads.create()# 添加 user message
message = client.beta.threads.messages.create(thread_id=thread.id,role="user",content="张三上几堂课,比李四多上几堂",
)
# 使用 stream 接口并传入 EventHandler
with client.beta.threads.runs.stream(thread_id=thread.id,assistant_id=assistant_id,event_handler=EventHandler(),
) as stream:stream.until_done()
assistant > functionassistant > functionask_database({'query': "SELECT COUNT(*) AS count FROM Courses WHERE instructor = '张三';"})
ask_database({'query': "SELECT COUNT(*) AS count FROM Courses WHERE instructor = '李四';"})assistant > 张三上了4堂课,而李四上了1堂课。因此,张三比李四多上了3堂课。

更多流中的 Event: https://platform.openai.com/docs/api-reference/assistants-streaming/events 

相关文章:

【AI大模型】GPTS 与 Assistants API

前言 2023 年 11 月 6 日,OpenAI DevDay 发表了一系列新能力,其中包括:GPT Store 和 Assistants API。 GPTs 和 Assistants API 本质是降低开发门槛 可操控性和易用性之间的权衡与折中: 更多技术路线选择:原生 API、…...

攻击者开始使用 XLL 文件进行攻击

近期,研究人员发现使用恶意 Microsoft Excel 加载项(XLL)文件发起攻击的行动有所增加,这项技术的 MITRE ATT&CK 技术项编号为 T1137.006。 这些加载项都是为了使用户能够利用高性能函数,为 Excel 工作表提供 API …...

Why RAG is slower than LLM?

I used RAG with LLAMA3 for AI bot. I find RAG with chromadb is much slower than call LLM itself. Following the test result, with just one simple web page about 1000 words, it takes more than 2 seconds for retrieving: 我使用RAG(可能是指某种特定的…...

Word页码设置,封面无页码,目录摘要阿拉伯数字I,II,III页码,正文开始123为页码

一、背景 使用Word写项目书或论文时,需要正确插入页码,比如封面无页码,目录摘要阿拉伯数字I,II,III为页码,正文开始以123为页码,下面介绍具体实施方法。 所用Word版本:2021 二、W…...

汽车汽配图纸管理、产品研发管理解决方案

汽车汽配图纸管理、产品研发管理解决方案 随着全球汽车市场的快速发展,中国汽车汽配行业迎来了前所未有的发展机遇。然而,在这一过程中,企业也面临着诸多挑战,如研发能力的提升、技术资料管理的复杂性、以及跨部门协作的困难等。为…...

小程序简单版音乐播放器

小程序简单版音乐播放器 结构 先来看看页面结构 <!-- wxml --><!-- 标签页标题 --> <view class"tab"><view class"tab-item {{tab0?active:}}" bindtap"changeItem" data-item"0">音乐推荐</view><…...

驾校预约管理系统

摘 要 随着驾驶技术的普及和交通安全意识的增强&#xff0c;越来越多的人选择参加驾校培训&#xff0c;以获取驾驶执照。然而&#xff0c;驾校管理面临着日益增长的学员数量和繁琐的预约管理工作。为了提高驾校的管理效率和服务质量&#xff0c;驾校预约管理系统成为了必不可少…...

C++ 左值右值 || std::move() || 浅拷贝,深拷贝 || 数据类型

数据类型&#xff1a; 作用&#xff1a;决定变量所占内存空间的字节大小&#xff0c;和布局方式基本数据类型&#xff1a; 算数类型&#xff1a; 整形&#xff08;bool / char……扩展集 / int / long……&#xff09;&& 浮点形&#xff08;float/double……&#xff…...

发那科机器人IO 分配

IO 信号 也称为输入\输出信号&#xff0c;是机器人与外围设备通信的电信号...

ubuntu开机怎么进入、退出命令行界面

要在Ubuntu系统开机时进入命令行界面&#xff0c;可以按照以下步骤操作&#xff1a; 在开机过程中按下Ctrl Alt F1组合键&#xff0c;这将会切换到第一个虚拟控制台&#xff0c;即命令行界面。如果Ctrl Alt F1没有生效&#xff0c;也可以尝试Ctrl Alt F2、Ctrl Alt F3…...

『FPGA通信接口』LVDS接口(4)LVDS接收端设计

文章目录 1.LVDS接收端概述2逻辑框图3.xapp855训练代码解读4.接收端发送端联调5.传送门 1.LVDS接收端概述 接收端的传输模型各个属性应该与LVDS发送端各属性一致&#xff0c;例如&#xff0c;如果用于接收CMOS图像传感器的图像数据&#xff0c;则接收端程序的串化因子、通道个…...

面试题:HTTP的body是二进制还是文本

实际上&#xff0c;HTTP的body可以是二进制数据&#xff0c;也可以是文本。HTTP协议本身不对body内容的格式做限制&#xff0c;具体格式取决于Content-Type头字段的定义。 文本数据&#xff1a; 当Content-Type头字段指定为文本类型时&#xff08;如text/plain、text/html、ap…...

5分钟带你部署一套Jenkins持续集成环境​

5分钟带你部署一套Jenkins持续集成环境 Jenkins是开源CI&CD软件领导者&#xff0c; 提供超过1000个插件来支持构建、部署、自动化&#xff0c; 满足任何项目的需要。 Jenkins的优点 持续集成和持续交付 作为一个可扩展的自动化服务器&#xff0c;Jenkins 可以用作简单的 CI…...

OpenAI突然宣布停止向中国提供API服务!

标题 &#x1f31f; OpenAI突然宣布停止向中国提供API服务! &#x1f31f;摘要 &#x1f4dc;引言 &#x1f4e2;正文 &#x1f4dd;1. OpenAI API的重要性2. 停止服务的原因分析3. 对中国市场的影响4. 应对措施代码案例 &#x1f4c2;常见问题解答&#xff08;QA&#xff09;❓…...

Bootstrap 标签

Bootstrap 标签 引言 Bootstrap 是一个流行的前端框架&#xff0c;它提供了一套丰富的组件和工具&#xff0c;帮助开发者快速构建响应式和移动优先的网页。在 Bootstrap 中&#xff0c;标签&#xff08;Badge&#xff09;是一种小巧的组件&#xff0c;用于显示计数、提示或标…...

EtherCAT主站SOEM -- 37 -- win-soem-win10及win11系统QT-SOEM-1个电机转圈圈-周期同步速度模式(CSV模式)

EtherCAT主站SOEM -- 37 -- win-soem-win10及win11系统QT-SOEM-1个电机转圈圈-周期同步速度模式(CSV模式) 0 QT-SOEM及STM32F767-SOEM视频欣赏及源代码链接:0.1 Linux--Ubuntu系统之 QT-SOEM博客、视频欣赏及源代码链接0.2 STM32F767-SOEM 博客、视频欣赏及源代码链接0.3 wi…...

老板舍不得买库存管理软件❓一招解决

在当今快节奏的商业环境中&#xff0c;仓库管理是企业运作中不可或缺的一环。对于许多中小型企业而言&#xff0c;简易且高效的库存管理系统尤为重要。搭贝简易库存管理系统针对仓库的出入库进行有效管理&#xff0c;帮助企业实现库存的透明化和流程的自动化。 客户的痛点 1. …...

【MySQL数据库】:MySQL视图特性

目录 视图的概念 基本使用 准备测试表 创建视图 修改视图影响基表 修改基表影响视图 删除视图 视图规则和限制 视图的概念 视图是一个虚拟表&#xff0c;其内容由查询定义&#xff0c;同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图中的数据…...

malloc、free和new delete的区别

malloc/free 和 new/delete 是在 C 中分配和释放内存的两种不同方法。它们主要有以下区别&#xff1a; 1. 语法和用法 malloc 和 free: malloc开辟空间时需要手动计算分配的空间大小 int* p (int*)malloc(sizeof(int) * 10); // 分配10个int类型的内存 // 使用内存 free(p); …...

如何有效地优化 Erlang 程序的内存使用,以应对大规模数据处理的需求?

要有效地优化Erlang程序的内存使用&#xff0c;以应对大规模数据处理的需求&#xff0c;可以考虑以下几个方面&#xff1a; 减少不必要的内存分配&#xff1a;避免过多的数据复制和不必要的数据结构创建。可以使用Erlang的二进制数据类型来避免数据复制&#xff0c;使用原子数据…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...