大模型学习笔记三:Function Calling

news2024/11/25 20:22:21

文章目录

    • 一、命令UI界面进化和Plugins的发展及失败
    • 二、Function Calling的机制
      • 1)示例 1:调用本地函数
      • 2)示例 2:多 Function 调用
      • 3)示例 3:用 Function Calling 获取 JSON 结构
      • 4)示例 4:通过 Function Calling 查询数据库
      • 5)示例 5:用 Function Calling 实现多表查询
      • 6)示例 6:Stream 模式
    • 三、Function Calling的注释事项
    • 四、支持 Function Calling 的国产大模型
      • 1、百度文心大模型
      • 2、MiniMax
      • 3、ChatGLM3-6B
      • 4、讯飞星火 3.0

一、命令UI界面进化和Plugins的发展及失败

  • UI接口进化
    ①命令行,简称CLI,例如UNIX/Linux Shell
    ②图形界面,简称GUI,例如WINDOWS
    ③语言界面,CUI或LUI ,例如GPT
    ④脑机接口,简称BCI

  • 补充
    自然语音接口,简称NLI

  • 插件Plugin调用流程
    在这里插入图片描述

  • Plugins失败分析
    1、缺少强Agent调度,只能手工选三个Plugins
    2、不在场景中,不能提供端到端一揽子服务
    3、延迟非常高(至少两次GPT-4生成,和一次Web API调用)

所以后面OpenAI才推出了Function Calling

二、Function Calling的机制

  • 原理图
    在这里插入图片描述

1)示例 1:调用本地函数

  • 需求
    需求:实现一个回答问题的 AI。题目中如果有加法,必须能精确计算。
  • 代码
# 初始化
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
import os
import json

_ = load_dotenv(find_dotenv())

client = OpenAI()


def print_json(data):
    """
    打印参数。如果参数是有结构的(如字典或列表),则以格式化的 JSON 形式打印;
    否则,直接打印该值。
    """
    if hasattr(data, 'model_dump_json'):
        data = json.loads(data.model_dump_json())

    if (isinstance(data, (list, dict))):
        print(json.dumps(
            data,
            indent=4,
            ensure_ascii=False
        ))
    else:
        print(data)
def get_completion(messages, model="gpt-3.5-turbo"):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0.7,  # 模型输出的随机性,0 表示随机性最小
        tools=[{  # 用 JSON 描述函数。可以定义多个。由大模型决定调用谁。也可能都不调用
            "type": "function",
            "function": {
                "name": "sum",
                "description": "加法器,计算一组数的和",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "numbers": {
                            "type": "array",
                            "items": {
                                "type": "number"
                            }
                        }
                    }
                }
            }
        }],
    )
    return response.choices[0].message

from math import *

prompt = "Tell me the sum of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10."
# prompt = "桌上有 2 个苹果,四个桃子和 3 本书,一共有几个水果?"
# prompt = "1+2+3...+99+100"
# prompt = "1024 乘以 1024 是多少?"   # Tools 里没有定义乘法,会怎样?
# prompt = "太阳从哪边升起?"           # 不需要算加法,会怎样?

messages = [
    {"role": "system", "content": "你是一个数学家"},
    {"role": "user", "content": prompt}
]
response = get_completion(messages)

# 把大模型的回复加入到对话历史中
print_json(response)
messages.append(response)

print("=====GPT回复=====")
print_json(response)

# 如果返回的是函数调用结果,则打印出来
if (response.tool_calls is not None):
    # 是否要调用 sum
    tool_call = response.tool_calls[0]
    if (tool_call.function.name == "sum"):
        # 调用 sum
        args = json.loads(tool_call.function.arguments)
        result = sum(args["numbers"])
        print("=====函数返回=====")
        print(result)

        # 把函数调用结果加入到对话历史中
        messages.append(
            {
                "tool_call_id": tool_call.id,  # 用于标识函数调用的 ID
                "role": "tool",
                "name": "sum",
                "content": str(result)  # 数值 result 必须转成字符串
            }
        )

        # 再次调用大模型
        print("=====最终回复=====")
        print(get_completion(messages).content)
  • 答复
    在这里插入图片描述

2)示例 2:多 Function 调用

  • 需求
    查询某个地点附近的酒店、餐厅、景点等信息。即,查询某个 POI 附近的 POI。
  • 代码
def get_completion(messages, model="gpt-3.5-turbo"):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0,  # 模型输出的随机性,0 表示随机性最小
        seed=1024,      # 随机种子保持不变,temperature 和 prompt 不变的情况下,输出就会不变
        tool_choice="auto",  # 默认值,由 GPT 自主决定返回 function call 还是返回文字回复。也可以强制要求必须调用指定的函数,详见官方文档
        tools=[{
            "type": "function",
            "function": {

                "name": "get_location_coordinate",
                "description": "根据POI名称,获得POI的经纬度坐标",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "POI名称,必须是中文",
                        },
                        "city": {
                            "type": "string",
                            "description": "POI所在的城市名,必须是中文",
                        }
                    },
                    "required": ["location", "city"],
                }
            }
        },
            {
            "type": "function",
            "function": {
                "name": "search_nearby_pois",
                "description": "搜索给定坐标附近的poi",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "longitude": {
                            "type": "string",
                            "description": "中心点的经度",
                        },
                        "latitude": {
                            "type": "string",
                            "description": "中心点的纬度",
                        },
                        "keyword": {
                            "type": "string",
                            "description": "目标poi的关键字",
                        }
                    },
                    "required": ["longitude", "latitude", "keyword"],
                }
            }
        }],
    )
    return response.choices[0].message
---------------------------------------------------
import requests

amap_key = "6d672e6194caa3b639fccf2caf06c342"


def get_location_coordinate(location, city):
    url = f"https://restapi.amap.com/v5/place/text?key={amap_key}&keywords={location}&region={city}"
    print(url)
    r = requests.get(url)
    result = r.json()
    if "pois" in result and result["pois"]:
        return result["pois"][0]
    return None


def search_nearby_pois(longitude, latitude, keyword):
    url = f"https://restapi.amap.com/v5/place/around?key={amap_key}&keywords={keyword}&location={longitude},{latitude}"
    print(url)
    r = requests.get(url)
    result = r.json()
    ans = ""
    if "pois" in result and result["pois"]:
        for i in range(min(3, len(result["pois"]))):
            name = result["pois"][i]["name"]
            address = result["pois"][i]["address"]
            distance = result["pois"][i]["distance"]
            ans += f"{name}\n{address}\n距离:{distance}米\n\n"
    return ans
-------------------------------------------------------
prompt = "我想在北京五道口附近喝咖啡,给我推荐几个"
# prompt = "我到北京出差,给我推荐三里屯的酒店,和五道口附近的咖啡"

messages = [
    {"role": "system", "content": "你是一个地图通,你可以找到任何地址。"},
    {"role": "user", "content": prompt}
]
response = get_completion(messages)
messages.append(response)  # 把大模型的回复加入到对话中
print("=====GPT回复=====")
print_json(response)

while (response.tool_calls is not None):
    # 1106 版新模型支持一次返回多个函数调用请求,所以要考虑到这种情况
    for tool_call in response.tool_calls:
        args = json.loads(tool_call.function.arguments)
        print("函数参数展开:")
        print_json(args)

        if (tool_call.function.name == "get_location_coordinate"):
            print("Call: get_location_coordinate")
            result = get_location_coordinate(**args)
        elif (tool_call.function.name == "search_nearby_pois"):
            print("Call: search_nearby_pois")
            result = search_nearby_pois(**args)

        print("=====函数返回=====")
        print_json(result)

        messages.append({
            "tool_call_id": tool_call.id,  # 用于标识函数调用的 ID
            "role": "tool",
            "name": tool_call.function.name,
            "content": str(result)  # 数值result 必须转成字符串
        })

    response = get_completion(messages)
    messages.append(response)  # 把大模型的回复加入到对话中

print("=====最终回复=====")
print(response.content)
  • 答复
=====GPT回复=====
{
    "content": null,
    "role": "assistant",
    "function_call": null,
    "tool_calls": [
        {
            "id": "call_WVpqDkc09ATorLhUqWOr155W",
            "function": {
                "arguments": "{\n  \"location\": \"北京五道口\",\n  \"city\": \"北京\"\n}",
                "name": "get_location_coordinate"
            },
            "type": "function"
        }
    ]
}
函数参数展开:
{
    "location": "北京五道口",
    "city": "北京"
}
Call: get_location_coordinate
https://restapi.amap.com/v5/place/text?key=6d672e6194caa3b639fccf2caf06c342&keywords=北京五道口&region=北京
=====函数返回=====
{
    "parent": "",
    "address": "海淀区",
    "distance": "",
    "pcode": "110000",
    "adcode": "110108",
    "pname": "北京市",
    "cityname": "北京市",
    "type": "地名地址信息;热点地名;热点地名",
    "typecode": "190700",
    "adname": "海淀区",
    "citycode": "010",
    "name": "五道口",
    "location": "116.338611,39.992552",
    "id": "B000A8WSBH"
}
函数参数展开:
{
    "longitude": "116.338611",
    "latitude": "39.992552",
    "keyword": "咖啡"
}
Call: search_nearby_pois
https://restapi.amap.com/v5/place/around?key=6d672e6194caa3b639fccf2caf06c342&keywords=咖啡&location=116.338611,39.992552
=====函数返回=====
星巴克(北京五道口购物中心店)
成府路28号1层101-10B及2层201-09号
距离:40米

瑞幸咖啡(五道口购物中心店)
成府路28号五道口购物中心负一层101号
距离:67米

MANNER COFFEE(五道口购物中心店)
成府路28号五道口购物中心一层东侧L1-04
距离:82米


=====最终回复=====
我为您找到了几个在北京五道口附近的咖啡店:

1. 星巴克(北京五道口购物中心店)
   地址:成府路28号1层101-10B及2层201-09号
   距离:40米

2. 瑞幸咖啡(五道口购物中心店)
   地址:成府路28号五道口购物中心负一层101号
   距离:67米

3. MANNER COFFEE(五道口购物中心店)
   地址:成府路28号五道口购物中心一层东侧L1-04
   距离:82米

您可以根据距离和个人喜好选择其中一家前往品尝咖啡。祝您享受愉快的咖啡时光!

3)示例 3:用 Function Calling 获取 JSON 结构

  • 备注
    Function calling 生成 JSON 的稳定性比较高。
  • 需求
    从一段文字中抽取联系人姓名、地址和电话
  • 代码
def get_completion(messages, model="gpt-3.5-turbo"):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0,  # 模型输出的随机性,0 表示随机性最小
        tools=[{
            "type": "function",
            "function": {
                "name": "add_contact",
                "description": "添加联系人",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "name": {
                            "type": "string",
                            "description": "联系人姓名"
                        },
                        "address": {
                            "type": "string",
                            "description": "联系人地址"
                        },
                        "tel": {
                            "type": "string",
                            "description": "联系人电话"
                        },
                    }
                }
            }
        }],
    )
    return response.choices[0].message


prompt = "帮我寄给王卓然,地址是北京市朝阳区亮马桥外交办公大楼,电话13012345678。"
messages = [
    {"role": "system", "content": "你是一个联系人录入员。"},
    {"role": "user", "content": prompt}
]
response = get_completion(messages)
print("====GPT回复====")
print_json(response)
args = json.loads(response.tool_calls[0].function.arguments)
print("====函数参数====")
print_json(args)
  • 答复
    在这里插入图片描述

4)示例 4:通过 Function Calling 查询数据库

  • 需求
    需求:从订单表中查询各种信息,比如某个用户的订单数量、某个商品的销量、某个用户的消费总额等等。
  • 代码
def get_sql_completion(messages, model="gpt-3.5-turbo"):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0,
        tools=[{  # 摘自 OpenAI 官方示例 https://github.com/openai/openai-cookbook/blob/main/examples/How_to_call_functions_with_chat_models.ipynb
            "type": "function",
            "function": {
                "name": "ask_database",
                "description": "Use this function to answer user questions about business. \
                            Output should be a fully formed SQL query.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "query": {
                            "type": "string",
                            "description": f"""
                            SQL query extracting info to answer the user's question.
                            SQL should be written using this database schema:
                            {database_schema_string}
                            The query should be returned in plain text, not in JSON.
                            The query should only contain grammars supported by SQLite.
                            """,
                        }
                    },
                    "required": ["query"],
                }
            }
        }],
    )
    return response.choices[0].message
--------------------------------------
#  描述数据库表结构
database_schema_string = """
CREATE TABLE orders (
    id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
    customer_id INT NOT NULL, -- 客户ID,不允许为空
    product_id STR NOT NULL, -- 产品ID,不允许为空
    price DECIMAL(10,2) NOT NULL, -- 价格,不允许为空
    status INT NOT NULL, -- 订单状态,整数类型,不允许为空。0代表待支付,1代表已支付,2代表已退款
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间,默认为当前时间
    pay_time TIMESTAMP -- 支付时间,可以为空
);
"""
---------------------------------------------
import sqlite3

# 创建数据库连接
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()

# 创建orders表
cursor.execute(database_schema_string)

# 插入5条明确的模拟记录
mock_data = [
    (1, 1001, 'TSHIRT_1', 50.00, 0, '2023-10-12 10:00:00', None),
    (2, 1001, 'TSHIRT_2', 75.50, 1, '2023-10-16 11:00:00', '2023-08-16 12:00:00'),
    (3, 1002, 'SHOES_X2', 25.25, 2, '2023-10-17 12:30:00', '2023-08-17 13:00:00'),
    (4, 1003, 'HAT_Z112', 60.75, 1, '2023-10-20 14:00:00', '2023-08-20 15:00:00'),
    (5, 1002, 'WATCH_X001', 90.00, 0, '2023-10-28 16:00:00', None)
]

for record in mock_data:
    cursor.execute('''
    INSERT INTO orders (id, customer_id, product_id, price, status, create_time, pay_time)
    VALUES (?, ?, ?, ?, ?, ?, ?)
    ''', record)

# 提交事务
conn.commit()
----------------------------------------------
def ask_database(query):
    cursor.execute(query)
    records = cursor.fetchall()
    return records


prompt = "10月的销售额"
# prompt = "统计每月每件商品的销售额"
# prompt = "哪个用户消费最高?消费多少?"

messages = [
    {"role": "system", "content": "基于 order 表回答用户问题"},
    {"role": "user", "content": prompt}
]
response = get_sql_completion(messages)
if response.content is None:
    response.content = ""
messages.append(response)
print("====Function Calling====")
print_json(response)

if response.tool_calls is not None:
    tool_call = response.tool_calls[0]
    if tool_call.function.name == "ask_database":
        arguments = tool_call.function.arguments
        args = json.loads(arguments)
        print("====SQL====")
        print(args["query"])
        result = ask_database(args["query"])
        print("====DB Records====")
        print(result)

        messages.append({
            "tool_call_id": tool_call.id,
            "role": "tool",
            "name": "ask_database",
            "content": str(result)
        })
        response = get_sql_completion(messages)
        print("====最终回复====")
        print(response.content)



  • 返回结果
====Function Calling====
{
    "content": "",
    "role": "assistant",
    "function_call": null,
    "tool_calls": [
        {
            "id": "call_6K8wpQeTWXg3ka1G1x0nbERl",
            "function": {
                "arguments": "{\n  \"query\": \"SELECT SUM(price) FROM orders WHERE strftime('%m', create_time) = '10' AND status = 1\"\n}",
                "name": "ask_database"
            },
            "type": "function"
        }
    ]
}
====SQL====
SELECT SUM(price) FROM orders WHERE strftime('%m', create_time) = '10' AND status = 1
====DB Records====
[(136.25,)]
====最终回复====
10月的销售额为136.25。

5)示例 5:用 Function Calling 实现多表查询

  • 代码
#  描述数据库表结构
database_schema_string = """
CREATE TABLE customers (
    id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
    customer_name VARCHAR(255) NOT NULL, -- 客户名,不允许为空
    email VARCHAR(255) UNIQUE, -- 邮箱,唯一
    register_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 注册时间,默认为当前时间
);
CREATE TABLE products (
    id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
    product_name VARCHAR(255) NOT NULL, -- 产品名称,不允许为空
    price DECIMAL(10,2) NOT NULL -- 价格,不允许为空
);
CREATE TABLE orders (
    id INT PRIMARY KEY NOT NULL, -- 主键,不允许为空
    customer_id INT NOT NULL, -- 客户ID,不允许为空
    product_id INT NOT NULL, -- 产品ID,不允许为空
    price DECIMAL(10,2) NOT NULL, -- 价格,不允许为空
    status INT NOT NULL, -- 订单状态,整数类型,不允许为空。0代表待支付,1代表已支付,2代表已退款
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间,默认为当前时间
    pay_time TIMESTAMP -- 支付时间,可以为空
);
"""

prompt = "统计每月每件商品的销售额"
# prompt = "这星期消费最高的用户是谁?他买了哪些商品? 每件商品买了几件?花费多少?"
messages = [
    {"role": "system", "content": "基于 order 表回答用户问题"},
    {"role": "user", "content": prompt}
]
response = get_sql_completion(messages)
print(response.tool_calls[0].function.arguments)
  • 返回
{
  "query": "SELECT strftime('%Y-%m', create_time) AS month, product_name, SUM(price) AS total_sales FROM orders JOIN products ON orders.product_id = products.id WHERE status = 1 GROUP BY month, product_name ORDER BY month, product_name"
}

6)示例 6:Stream 模式

  • 注意
    流式(stream)输出不会一次返回完整 JSON 结构,所以需要拼接后再使用。
  • 代码
def get_completion(messages, model="gpt-3.5-turbo"):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0,
        tools=[{
            "type": "function",
            "function": {
                "name": "sum",
                "description": "计算一组数的加和",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "numbers": {
                            "type": "array",
                            "items": {
                                "type": "number"
                            }
                        }
                    }
                }
            }
        }],
        stream=True,    # 启动流式输出
    )
    return response


prompt = "1+2+3"
# prompt = "你是谁"

messages = [
    {"role": "system", "content": "你是一个小学数学老师,你要教学生加法"},
    {"role": "user", "content": prompt}
]
response = get_completion(messages)

function_name, args, text = "", "", ""

print("====Streaming====")

# 需要把 stream 里的 token 拼起来,才能得到完整的 call
for msg in response:
    delta = msg.choices[0].delta
    if delta.tool_calls:
        if not function_name:
            function_name = delta.tool_calls[0].function.name
        args_delta = delta.tool_calls[0].function.arguments
        print(args_delta)  # 打印每次得到的数据
        args = args + args_delta
    elif delta.content:
        text_delta = delta.content
        print(text_delta)
        text = text + text_delta

print("====done!====")

if function_name or args:
    print(function_name)
    print_json(args)
if text:
    print(text)
  • 返回
====Streaming====

{

 
 "
numbers
":
 [
1
,
 
2
,
 
3
]

}
====done!====
sum
{
  "numbers": [1, 2, 3]
}

三、Function Calling的注释事项

1、只有 gpt-3.5-turbo-1106 和 gpt-4-1106-preview 可用本次课介绍的方法
2、gpt-3.5-turbo 是 gpt-3.5-turbo-1106 的别名
3、gpt-4 和 gpt-4-1106-preview 是两个不同的模型
4、OpenAI 针对 Function Calling 做了 fine-tuning,以尽可能保证函数调用参数的正确。
4、函数声明是消耗 token 的。要在功能覆盖、省钱、节约上下文窗口之间找到最佳平衡
Function Calling 不仅可以调用读函数,也能调用写函数。但官方强烈建议,在写之前,一定要有人做确认

四、支持 Function Calling 的国产大模型

1、百度文心大模型

官方文档:https://cloud.baidu.com/doc/WENXINWORKSHOP/index.html
在这里插入图片描述

2、MiniMax

官方文档:https://api.minimax.chat/document/guides/chat-pro?id=64b79fa3e74cddc5215939f4

  • 这是个公众不大知道,但其实挺强的大模型,尤其角色扮演能力
  • 如果你曾经在一个叫 Glow 的 app 流连忘返,那么你已经用过它了
  • 应该是最早支持 Function Calling 的国产大模型
  • Function Calling 的 API 和 OpenAI 1106 版之前完全一样,但其它 API 有很大的特色

3、ChatGLM3-6B

官方文档:https://github.com/THUDM/ChatGLM3/blob/main/tool_using/README.md

  • 最著名的国产开源大模型,生态最好
  • 早就使用 tools 而不是 function 来做参数,其它和 OpenAI 1106 版之前完全一样

4、讯飞星火 3.0

官方文档:https://www.xfyun.cn/doc/spark/Web.html#_2-function-call%E8%AF%B4%E6%98%8E

和 OpenAI 1106 版之前完全一样

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

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

相关文章

完整分析CRM管理系统的功能,详细说明!

很多使用过CRM管理系统的人都表示,一旦尝试使用客户管理系统进行业务处理之后,就再也离不开了。那么,客户管理系统究竟有什么魔力?以下是CRM管理系统的功能详解。 虽然CRM是围绕客户管理展开的,然而经过这么多年的发展…

五、分类算法 总结

代码: from sklearn.datasets import load_iris, fetch_20newsgroups from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.naive_bayes import MultinomialNB from s…

【FreeRTOS基础入门】事件组与同步点

文章目录 前言一、事件组是什么案例1.1 事件组的概念 二、事件组的操作2.1 事件组与其他实现同步与互斥方法的区别2.2 创建事件组2.3 删除事件组2.4 设置事件2.5 等待事件2.6 示例代码 三、同步点3.1 同步点是什么3.2 设置同步点 总结 前言 FreeRTOS是一个广泛应用于嵌入式系统…

vue3中使用 tui-image-editor进行图片处理,并上传

效果图 下载包 pnpm i tui-image-editor pnpm i tui-color-picker调用组件 //html部分 <el-dialog v-model"imgshow" destroy-on-close width"40%" draggable align-center :show-close"true":close-on-click-modal"false">&l…

windows极限摸鱼软件(仅6678kb)

时间过得真快啊&#xff0c;不知不觉春节假期就过完了。你已经开始工作了吗&#xff1f;反正我是一直没闲着。 歇的时间久了&#xff0c;一上班这节奏很难一下子转换过来。也可能刚上班&#xff0c;没什么事情做&#xff0c;有点无聊。 &#xff08;好吧&#xff0c;我承认了…

Java 面向对象进阶 11 多态的优势和弊端(黑马)

优势&#xff1a; 代码&#xff1a; public class test {public static void main(String[] args) {Animal a new Dog();a.eat(); } } class Animal{public void eat(){System.out.println("动物再吃东西");} } class Dog extends Animal{Overridepublic void eat(…

如何修改unity的背景颜色

要在Unity中将背景颜色设为黑色&#xff0c;可以按照以下步骤进行&#xff1a; 1、在Unity编辑器中&#xff0c;选择你想要修改背景颜色的摄像机对象&#xff08;一般是Main Camera&#xff09;。 2、在Inspector面板中&#xff0c;找到"Clear Flags"&#xff08;清…

Leetcode155(设计最小栈)

例题&#xff1a; 分析&#xff1a; 题目要求我们必须在常数时间内检索到最小元素。 我们可以使用两个栈&#xff08;A、B&#xff09;来实现&#xff0c;A栈用来正常存储数据、弹出数据&#xff0c; B栈用于存储A栈中的最小元素&#xff0c;如下图&#xff1a; 刚开始&#…

三十年一个大轮回!日股突破“泡沫时期”历史高点

2月22日周四&#xff0c;英伟达四季报业绩超预期&#xff0c;而且本季度业绩指引非常乐观&#xff0c;提振美股股指期货并成为芯片股和AI概念股情绪的重要催化剂。今日亚洲芯片股和AI股起飞&#xff0c;日本在芯片股的带动下突破1989年泡沫时期以来的历史最高收盘价。 美股方面…

SqlServer2016离线安装--Microsoft R Open 和 Microsoft R Server安装文件位置

问题 SQL SERVE 2016离线安装&#xff0c;会出现“Microsoft R Open 和 Microsoft R Server 脱机安装”的界面&#xff0c; 无法点击下一步的情况&#xff0c;如下图&#xff1a; 原因 离线安装时需要下载两个文件 解决方案 1、访问路径下载文件 https://go.microsoft.c…

MATLAB 导出可编辑的eps格式图像

任务描述&#xff1a;部分期刊要求提交可编辑的eps格式图像&#xff0c;方便美工编辑对图像进行美化 我试了直接print或者在figure窗口导出&#xff0c;发现导出的文件放到Adobe AI中并不能编辑&#xff0c;经Google找到解决办法&#xff1a; %EPS exportgraphics(gcf,myVect…

Nginx基础入门

一、Nginx的优势 nginx是一个高性能的HTTP和反向代理服务器&#xff0c;也是一个SMTP&#xff08;邮局&#xff09;服务器。 Nginx的web优势&#xff1a;IO多路复用&#xff0c;时分多路复用&#xff0c;频分多路复用 高并发&#xff0c;IO多路复用&#xff0c;epoll&#xf…

2024年1月手机市场行业分析:苹果手机份额骤降,国产高端手机成功逆袭!

小米Ultra发布。 一方面&#xff0c;我们有望看到国产手机再一次超越自己的决心&#xff0c;继续创新追逐高端&#xff1b;另一方面&#xff0c;我们也不得不正视目前手机市场所面临的危机状态。 2024年1月的线上手机市场远不如去年。根据鲸参谋数据显示&#xff0c;今年1月京…

linux系统内核升级

1.查看旧版本内核 2.导入密钥 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 3.安装yum源 rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm4.启用elrepo-kernel仓库并安装最新内核版本 yum --enablerepoelrepo-kernel install …

【AIGC】开源音频工具AudioCraft

AudioCraft是一个开源框架&#xff0c;旨在生成高质量的音频&#xff0c;适用于音乐、声音生成和压缩等多种应用。 先听效果&#xff1a; aimusic 它由三个模型组成&#xff1a;MusicGen、AudioGen和EnCodec。 *MusicGen&#xff1a;*这个模型使用了Meta拥有和特别许可的音乐进…

WP----Look 我看的见你,你却看不见我 tips:sql injection tips2: mysql 字符集

0x00 题目连接打开后&#xff0c;是空白的&#xff0c;源代码也是空白的 这种情况就抓包&#xff0c;看请求包和相应包里面是否有提示 相应包中存在很特别的响应头X-HT: verify 可能是参数&#xff0c;传递任意参数过去 0x01 传递5个长度的参数时&#xff0c;返回 说明参数的…

相机图像质量研究(35)常见问题总结:图像处理对成像的影响--运动噪声

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

使用 C++23 协程实现第一个 co_await 同步风格调用接口--Qt计算文件哈希值

C加入了协程 coroutine的特性&#xff0c;一直没有动手实现过。看了网上很多文章&#xff0c;已经了解了协程作为“可被中断和恢复的函数”的一系列特点。在学习过程中&#xff0c;我发现大多数网上的例子&#xff0c;要不就是在main()函数的控制台程序里演示yeild,await, resu…

命令执行 [WUSTCTF2020]朴实无华1

做题&#xff1a; 打开题目 我们用dirsearch扫描一下看看 扫描到有robots.txt&#xff0c;访问一下看看 提示我们 /fAke_f1agggg.php 那就访问一下&#xff0c;不是真的flag bp抓包一下 得到提示&#xff0c; /fl4g.php&#xff0c;访问一下看看 按alt&#xff0c;点击修复文…

IP地理位置查询定位:技术原理与实际应用

在互联网时代&#xff0c;IP地址是连接世界的桥梁&#xff0c;而了解IP地址的地理位置对于网络管理、个性化服务以及安全监控都至关重要。IP数据云将深入探讨IP地理位置查询定位的技术原理、实际应用场景以及相关的隐私保护问题&#xff0c;旨在为读者提供全面了解和应用该技术…