- 后端
- 即时通讯
- API网关
【免费下载链接】go-cqhttp
cqhttp的golang实现,轻量、原生跨平台.
本篇技术指南以 go-cqhttp 开源仓库为主体,系统讲解其项目定位、OneBot-v11 兼容性、四大通信接口、拓展 CQ 码 / API / 事件体系,以及基于config.yml与device.json的完整配置与部署方式,并结合仓库源码说明各功能模块的底层实现原理。读者读完可完整掌握 go-cqhttp 的能力边界、配置方法、命令行参数与消息 / 事件模型,具备基于其搭建 QQ 机器人与上层应用的实际能力。
项目定位与技术背景
go-cqhttp 是一个基于 Mirai),项目描述为"cqhttp 的 golang 实现,轻量、原生跨平台"。其核心价值在于:将 QQ 客户端协议能力封装为标准的 OneBot 接口,使上层 Bot 应用可以通过统一的 HTTP / WebSocket 协议收发消息,而无需关心底层协议实现。
从源码结构看,整个项目分为以下几大模块,与文章后续章节一一对应:
coolq/:核心业务层,负责 CQ 码编解码、消息转换与全部 API 的具体实现(cqcode.go、api.go);server/与modules/servers/:通信服务层,实现 HTTP、正向 / 反向 WebSocket、pprof 等服务器的注册与启动(http.go、websocket.go、servers.go);modules/config/:配置文件解析与默认配置生成(config.go、default_config.yml);db/:消息数据库实现,支持 LevelDB、SQLite3、MongoDB 三种后端;cmd/gocq/:程序入口,负责参数解析、登录流程、重连与签名服务器逻辑(main.go)。
需要特别说明的是,README 在"重要信息"一节明确提示:由于 QQ 官方不断更新加密方案,该项目的协议维护已停止,README 建议 Bot 开发者迁移至无头 NTQQ 方案。因此,本文内容以当前仓库实际能力为准,读者在选型时应结合这一背景做出判断。
兼容性与通信接口
go-cqhttp 兼容 OneBot-v11):
| 接口类型 | 说明 |
|---|---|
| HTTP API | 由 Bot 应用主动调用 go-cqhttp 暴露的 HTTP 接口(默认监听0.0.0.0:5700) |
| 反向 HTTP POST | go-cqhttp 将事件主动 POST 到应用配置的地址(支持多点上报) |
| 正向 WebSocket | 应用作为客户端主动连接 go-cqhttp 的 WebSocket 服务(默认监听0.0.0.0:6700) |
| 反向 WebSocket | go-cqhttp 作为客户端连接应用提供的 WebSocket 服务(支持 Universal / API / Event 三通道) |
源码层的服务注册机制
这四类服务在启动时由统一的注册机制加载。在 servers.go 中,servers包维护两个注册表:svr(需要配置节点的服务)与nocfgsvr(无需配置的服务),并提供Register与RegisterCustom两个注册函数:
func Register(name string, proc func(*coolq.CQBot, yaml.Node)) { ... svr[name] = proc } func Run(bot *coolq.CQBot) { for _, l := range base.Servers { for name, conf := range l { if fn, ok := svr[name]; ok { go fn(bot, conf) } } } ... }也就是说,config.yml中servers列表里出现的每个服务名,都会在登录成功后(见 cmd/gocq/main.go 中servers.Run(coolq.NewQQBot(cli))调用)以 goroutine 形式并发启动,这也是 go-cqhttp 支持"同一连接方式可添加多个"的底层原因。HTTP 服务、反向 HTTP 多点上报、WebSocket 服务的具体监听与转发逻辑位于 server/http.go 与 server/websocket.go。
拓展支持一览
在 OneBot-v11 标准之上,go-cqhttp 增加了以下能力(完整说明见 docs/cqhttp.md):
- HTTP POST 多点上报:
servers的http.post列表可配置多个上报地址; - 反向 WS 多点连接:
ws-reverse支持同时配置多个地址; - 修改群名(
/set_group_name); - 消息撤回事件(群消息撤回
group_recall、好友消息撤回friend_recall); - 解析 / 发送回复消息(
[CQ:reply]); - 解析 / 发送合并转发(
[CQ:forward]、[CQ:node]); - 使用代理请求网络图片(
message.proxy-rewrite配置项)。
已实现的 CQ 码体系
CQ 码是 OneBot 协议中描述消息内容的核心语法,形如[CQ:face,id=178]。go-cqhttp 既完整实现了 OneBot 标准的 CQ 码,也扩展了标准之外的类型。
符合 OneBot 标准的 CQ 码
| CQ 码 | 功能 |
|---|---|
[CQ:face] | QQ 表情 |
[CQ:record] | 语音 |
[CQ:video] | 短视频 |
[CQ:at] | @某人 |
[CQ:share] | 链接分享 |
[CQ:music] | 音乐分享 / 音乐自定义分享 |
[CQ:reply] | 回复 |
[CQ:forward] | 合并转发 |
[CQ:node] | 合并转发节点 |
[CQ:xml] | XML 消息 |
[CQ:json] | JSON 消息 |
拓展 CQ 码及与标准略有差异的 CQ 码
| 拓展 CQ 码 | 功能 |
|---|---|
[CQ:image] | 图片(支持 flash 闪照、show 秀图) |
[CQ:redbag] | 红包(仅接收) |
[CQ:poke] | 戳一戳(仅群聊发送) |
[CQ:node] | 合并转发消息节点 |
[CQ:cardimage] | 一种 xml 的图片消息(装逼大图) |
[CQ:tts] | 文本转语音(仅群聊,音源与登录账号性别有关) |
其中[CQ:image]是使用最频繁的拓展码,详细参数(见 docs/cqhttp.md)包括:file(文件名,支持本地路径、HTTP URL、base64://前缀)、type(flash闪照 /show秀图)、subType(群聊图片子类型,0~13 分别表示正常图片、表情包、热图、斗图、贴图、自拍、热搜图等)、url、cache(是否使用缓存)、id(秀图特效 ID,默认 40000)与c(下载线程数)。秀图特效 ID 对应关系为:40000 普通、40001 幻影、40002 抖动、40003 生日、40004 爱你、40005 征友。示例:[CQ:image,file=http://baidu.com/1.jpg,type=show,id=40004]。
注意:图片总大小不能超过 30MB,gif 总帧数不能超过 300 帧。
源码中的 CQ 码转换链路
CQ 码的编解码核心在 coolq/cqcode.go。上行方向(应用 → QQ),ConvertElement将解析出的msg.Element转换为 MiraiGo 消息元素,例如:
image类型:依据file前缀(http/file/base64/base16384/ 缓存文件)分别走网络下载、本地读取、解码流等路径,makeImageOrVideoElem中通过md5.Sum([]byte(f))生成缓存文件名,并限制图片 30MB、视频 100MB 的上限(常量maxImageSize、maxVideoSize定义于文件头部);reply类型:reply()函数支持两种用法,id存在时从数据库查询原消息构造ReplyElement,否则使用text/qq/time/seq字段构造自定义回复;music类型:qq(QQ 音乐)与163(网易云音乐)走各自平台的歌曲信息接口,custom类型则拼接 XML 卡片;tts类型:调用bot.Client.GetTts()获取语音数据并ResampleSilk重采样。
下行方向(QQ → 应用),toElements函数将 MiraiGo 元素数组转换为 OneBot 消息元素,群图、好友图、频道图分别映射为image类型,并自动附加type=flash或type=show字段。
已实现的 API 体系
go-cqhttp 实现了 OneBot 标准的绝大部分 API,并额外提供了大量拓展 API。标准 API 与拓展 API 的完整定义分别见 README.md 与 docs/cqhttp.md。
符合 OneBot 标准的 API
涵盖消息、群管理、好友管理、信息查询四大类,主要包括:
- 消息类:
/send_private_msg、/send_group_msg、/send_msg、/delete_msg(撤回信息); - 群管理类:
/set_group_kick(群组踢人)、/set_group_ban(单人禁言)、/set_group_whole_ban(全员禁言)、/set_group_admin(设置管理员)、/set_group_card(设置群名片)、/set_group_name(设置群名)、/set_group_leave(退出群组)、/set_group_special_title(设置专属头衔); - 请求处理类:
/set_friend_add_request(处理加好友请求)、/set_group_add_request(处理加群请求/邀请); - 信息查询类:
/get_login_info、/get_stranger_info、/get_friend_list、/get_group_info、/get_group_list、/get_group_member_info、/get_group_member_list、/get_group_honor_info、/can_send_image、/can_send_record、/get_version_info; - 运维类:
/set_restart(重启 go-cqhttp)、/.handle_quick_operation(对事件执行快速操作)。
拓展 API 及与标准略有差异的 API
| 拓展 API | 功能 |
|---|---|
/set_group_portrait | 设置群头像 |
/get_image | 获取图片信息(size、filename、url) |
/get_msg | 获取消息(message_id、real_id、sender、time、message) |
/get_forward_msg | 获取合并转发内容 |
/send_group_forward_msg | 发送合并转发(群) |
/.get_word_slices | 获取中文分词 |
/.ocr_image | 图片 OCR(仅支持已接收的图片) |
/get_group_system_msg | 获取群系统消息(邀请 / 进群请求列表) |
/get_group_file_system_info | 获取群文件系统信息 |
/get_group_root_files | 获取群根目录文件列表 |
/get_group_files_by_folder | 获取群子目录文件列表 |
/get_group_file_url | 获取群文件资源链接 |
/get_status | 获取状态(运行统计) |
此外,docs/cqhttp.md 还记录了更丰富的拓展 API,包括:/get_group_at_all_remain(@全体成员剩余次数)、/download_file(下载文件到缓存目录,返回绝对路径,可配合 CQ 码直接发送)、/get_group_msg_history(群消息历史)、/get_online_clients(在线客户端列表)、/check_url_safely(链接安全性检查,1 安全 / 2 未知 / 3 危险)、/_get_vip_info(用户 VIP 信息)、/_send_group_notice//_get_group_notice//_del_group_notice(群公告管理)、/set_essence_msg//delete_essence_msg//get_essence_msg_list(精华消息管理)、/upload_group_file//upload_private_file(上传文件,仅支持本地路径,HTTP 文件需先经/download_file下载)、/set_qq_profile(设置个人资料)、/get_unidirectional_friend_list//delete_unidirectional_friend//delete_friend、/qidian_get_account_info(企点协议专用)、/mark_msg_as_read、/reload_event_filter(重载事件过滤器)等。
以/get_status为例,其响应中的stat统计对象包含packet_received、packet_sent、packet_lost、message_received、message_sent、disconnect_times、lost_times等字段,所有统计信息在重启后重置,可用于监控 Bot 运行健康度。
已实现的事件体系
go-cqhttp 的事件上报同样分为 OneBot 标准事件与拓展事件两类。
符合 OneBot 标准的事件
- 消息事件:私聊信息、群消息;
- 通知事件:群文件上传、群管理员变动、群成员减少、群成员增加、群禁言、好友添加、群消息撤回、好友消息撤回、群内戳一戳、群红包运气王、群成员荣誉变更;
- 请求事件:加好友请求、加群请求/邀请。
拓展事件
| 事件类型 | 拓展 Event |
|---|---|
| 通知事件 | 好友戳一戳 |
| 通知事件 | 群内戳一戳 |
| 通知事件 | 群成员名片更新 |
| 通知事件 | 接收到离线文件 |
详细的字段定义见 docs/cqhttp.md 的事件章节,例如:
- 群消息撤回:
post_type=notice、notice_type=group_recall,携带group_id、user_id(消息发送者)、operator_id(操作者)、message_id; - 群内戳一戳:
notice_type=notify、sub_type=poke,携带group_id、user_id、target_id。注意此事件无法在平板和手表协议上触发; - 群成员名片更新:
notice_type=group_card,携带card_new、card_old(名片为空时为空字符串而非昵称),不保证时效性,仅在收到消息时校验; - 群成员头衔更新事件:
notice_type=notify,携带user_id与title; - 接收到离线文件:
notice_type=offline_file,file对象含name、size、url; - 其他客户端在线状态变更:
notice_type=client_status,携带client(Device 对象)与online; - 精华消息:
notice_type=essence,sub_type为add/delete,携带sender_id、operator_id、message_id。
事件过滤器机制可参考 docs/EventFilter.md 与 modules/filter/,通过在default-middlewares.filter配置过滤器文件路径,可按条件筛选需要上报的事件,并通过/reload_event_filterAPI 热重载。
配置体系:config.yml 与 device.json
go-cqhttp 运行时依赖config.yml(运行配置)与device.json(虚拟设备信息)两个文件。配置文件使用 YAML 语法,首次启动时若未找到配置文件,程序会自动生成config.yml(默认内容来自 default_config.yml,通过//go:embed嵌入二进制,见 config.go),并交互式询问需要启用的通信方式,生成完成后退出等待用户修改。
账号配置(account)
account: # 账号相关 uin: 1233456 # QQ账号 password: '' # 密码为空时使用扫码登录 encrypt: false # 是否开启密码加密 status: 0 # 在线状态 relogin: # 重连设置 delay: 3 # 首次重连延迟, 单位秒 interval: 3 # 重连间隔 max-times: 0 # 最大重连次数, 0为无限制 use-sso-address: true # 是否使用服务器下发的新地址进行重连 allow-temp-session: false # 是否允许发送临时会话消息encrypt: true时,程序每次启动要求输入解密密钥;密钥错误会导致登录时提示密码错误。解密后的密码哈希存储于内存中用于自动重连,因此该加密并不能防止内存读取(见 docs/config.md 注 1)。实现上,密码哈希经 PBKDF2(迭代 114514 次)+ AES 加密后写入password.encrypt文件,相关函数PasswordHashEncrypt/PasswordHashDecrypt位于 cmd/gocq/main.go;status在线状态取值 0~21,分别对应在线、离开、隐身、忙、听歌中、星座运势、今日天气、遇见春天、Timi 中、吃鸡中、恋爱中、汪汪汪、干饭中、学习中、熬夜中、打球中、信号弱、在线学习、游戏中、度假中、追剧中、健身中。源码中allowStatus数组(cmd/gocq/main.go)对应了这些状态,且登录时会做越界保护(if uint(base.Account.Status) >= uint(len(allowStatus)) { base.Account.Status = 0 });relogin重连逻辑:断开后首先等待delay秒,随后按interval间隔重试,max-times为最大重连次数,0 表示无限制;relogin.disabled: true可关闭自动重连(对应源码中if base.Reconnect.Disabled { os.Exit(1) })。
签名服务器配置(sign-servers)
这是 go-cqhttp 后期版本的核心配置块,用于规避登录 45 错误码与发送消息风控:
sign-servers: - url: '-' # 主签名服务器地址, 必填 key: '114514' # 签名服务器所需要的apikey(版本 1.1.0 及以下此项无效) authorization: '-' # authorization 内容, 依服务端设置,如 'Bearer xxxx' - url: '-' # 备用 key: '114514' authorization: '-' rule-change-sign-server: 1 # 判断签名服务不可用的额外规则 max-check-count: 0 # 连续寻找可用签名服务器最大尝试次数 sign-server-timeout: 60 # 签名服务请求超时时间(s) is-below-110: false # 签名服务器版本 <= 1.1.0 时设为 true auto-register: false # 是否在实例丢失时自动重新注册 auto-refresh-token: false # token 过期后是否立即自动刷新 refresh-interval: 40 # 定时刷新 token 间隔(分钟),建议 30~40,不可超过 60rule-change-sign-server取值:0 不设置(仅在请求无返回时判定不可用);1 在获取到的 sign 为空时切换(建议配合关闭auto-register);2 在 sign 或 token 为空时切换(建议配合关闭auto-refresh-token)。签名服务器的处理逻辑位于 cmd/gocq/main.go 的getAvaliableSignServer与定时刷新逻辑signStartRefreshToken。若未配置可用签名服务器,程序会输出警告"未配置签名服务器或签名服务器不可用, 这可能会导致登录 45 错误码或发送消息被风控"。
消息与上报配置(message)
message: post-format: string # 上报数据类型: string,array ignore-invalid-cqcode: false # 是否忽略无效的CQ码, 为假将原样发送 force-fragment: false # 是否强制分片发送消息 fix-url: false # 是否将url分片发送 proxy-rewrite: '' # 下载图片等请求网络代理 report-self-message: false # 是否上报自身消息 remove-reply-at: false # 移除服务端的Reply附带的At extra-reply-data: false # 为Reply附加更多信息 skip-mime-scan: false # 跳过 Mime 扫描, 忽略错误数据 convert-webp-image: false # 是否自动转换 WebP 图片 http-timeout: 15 # download 超时时间(s)post-format决定上报消息体是字符串形式(string,含 CQ 码)还是数组形式(array,分段元素);源码在 base/flag.go 的Init()中对非法的post-format值会警告并回退为string;force-fragment为原酷 Q 发送长消息的老方案,分片发送速度更优、兼容性更好,但在有发言频率限制的群里可能无法发送;关闭后优先使用新方案,能发送更长消息但速度更慢,部分老客户端无法解析(docs/config.md 注 3);fix-url对应源码中SplitURL,在ConvertElement的text分支中通过param.SplitURL将 URL 拆分发送;remove-reply-at/extra-reply-data对应toElements中对ReplyElement的处理:前者移除 reply 后紧跟的 @ 元素,后者为 reply 附加seq、qq、time、text字段。
日志与数据库配置(output / database)
output: log-level: warn # trace,debug,info,warn,error log-aging: 15 # 日志时效 单位天, 0 为永久保留 log-force-new: true # 是否每次启动强制创建全新日志文件 log-colorful: true # 是否启用日志颜色 debug: false # 开启调试模式 database: leveldb: enable: true # 启用内置leveldb数据库 sqlite3: enable: false cachettl: 3600000000000 # 1h- 日志按天轮转,写入
logs/%Y-%m-%d.log,轮转与清理逻辑见 cmd/gocq/main.go 的PrepareData()(使用file-rotatelogs); - 数据库启用 leveldb 会增加 10~20MB 内存占用;关闭后将无法使用撤回、回复、
get_msg等上下文相关功能。数据库抽象层位于 db/database.go 与 db/multidb.go,LevelDB / SQLite3 / MongoDB 实现分别在 db/leveldb/、db/sqlite3/、db/mongodb/。
中间件与连接服务(default-middlewares / servers)
default-middlewares: &default access-token: '' # 访问密钥, 强烈推荐在公网的服务器设置 filter: '' # 事件过滤器文件目录 rate-limit: # API限速设置(令牌桶算法, 全局生效) enabled: false frequency: 1 # 令牌回复频率, 单位秒 bucket: 1 # 令牌桶大小 servers: - http: address: 0.0.0.0:5700 timeout: 5 # 反向HTTP超时时间, 最小值为5 middlewares: <<: *default post: # 反向HTTP POST地址列表 #- url: '' # 地址 # secret: '' # 密钥 - ws: address: 0.0.0.0:6700 middlewares: <<: *default - ws-reverse: universal: ws://your_websocket_universal.server # api: ws://your_websocket_api.server # event: ws://your_websocket_event.server reconnect-interval: 3000 middlewares: <<: *default - pprof: host: 127.0.0.1 port: 7700- HTTP / WS 地址支持
tcp4://前缀指定 IPv4 监听(address: tcp4://0.0.0.0:5700,IPv6 同理); ws-reverse中设置universal后,api与event将被忽略;同时配置多个反向 WS 地址可实现多点连接;pprof性能分析服务器不支持中间件、不支持鉴权,请勿开放到公网;- 对于不需要的通信方式,可以注释停用(推荐),或添加配置
disabled: true关闭。
环境变量占位符
配置文件支持${VAR}占位符读取环境变量(实现于 config.go 的expand函数,使用正则\${([a-zA-Z_]+[a-zA-Z0-9_:/.]*)}匹配):
account: uin: ${CQ_UIN} # 读取环境变量 CQ_UIN password: ${CQ_PWD:123456} # 当 CQ_PWD 为空时使用默认值 123456设备信息(device.json)与协议
device.json保存虚拟设备信息,首次启动自动生成随机设备。关键字段为protocol:
| 值 | 类型 | 限制 | | -- | ---- | ---- | | 0 | iPad | 无 | | 1 | Android Phone | 无 | | 2 | Android Watch | 无法接收notify事件、无法接收口令红包、无法接收撤回消息 | | 3 | MacOS | 无 | | 4 | 企点 | 只能登录企点账号或企点子账号 |
协议不同对各类消息有所限制;扫码登录(password为空)仅部分协议支持,源码中isQRCodeLogin && cli.Device().Protocol != 2时会提示"当前协议不支持二维码登录"。另外可创建address.txt文件(位于工作目录,每行IP:PORT)自定义服务器 IP,用于解决海外服务器的链路问题,该逻辑见 cmd/gocq/main.go 的newClient()(c.SetCustomServer(addr))。
命令行参数与启动流程
通过-h可查看全部命令行参数,源码定义于 internal/base/flag.go:
| 参数 | 说明 |
|---|---|
-c <filename> | 指定配置文件路径,默认config.yml |
-d | 以 daemon(守护进程)方式运行 |
-h | 打印帮助 |
-w <dir> | 覆盖工作目录 |
-D | 开启 debug 模式 |
-faststart | 跳过启动等待 5 秒的流程 |
-update-protocol | 启动时更新协议版本 |
启动流程(见 cmd/gocq/main.go)分为四个阶段:
InitBase():解析参数、处理双击运行 /-h/-d,读取配置;PrepareData():初始化日志(rotatelogs 按天轮转)、创建图片 / 语音 / 视频缓存目录、打开数据库;LoginInteract():处理密码加密、加载 / 生成device.json、获取签名服务器、选择扫码 / 密码 / token 登录(登录成功后会保存session.token以便快速重连)、加载好友与群列表、设置在线状态、启动各通信服务;WaitSignal():后台检查更新与网络诊断,等待退出信号。
登录后程序会在断开时自动重连(DisconnectedEvent.Subscribe回调),优先使用session.token快速恢复会话,失败后回退为普通登录;若relogin.disabled则直接退出。
性能参考
README 中给出的官方性能数据为:在关闭数据库的情况下,加载 25 个好友、128 个群运行 24 小时后,内存使用约 15MB;开启数据库后内存使用将根据消息量增加 10~20MB。如果系统内存小于 128M,建议关闭数据库使用。该数据为项目自述,实际占用会随好友数、群数、消息量与协议版本变化。
云函数部署与跨平台运行
go-cqhttp 支持通过云函数(CustomRuntime)部署,scripts/bootstrap已给出 bootstrap 文件。部署步骤为:在本地完成登录,将config.yml、device.json、bootstrap和go-cqhttp二进制一起打包;在触发器中创建 API 网关触发器并启用集成响应,即可通过 API 网关访问 go-cqhttp(建议配置 AccessToken)。注意scripts/bootstrap中使用的工作路径为/tmp,该目录最大容量约 500M,如需长期使用应挂载文件存储(CFS)。详细说明见 docs/config.md。
其他周边文档还包括:快速开始、CQ 码与 API 详解、配置文件详解、事件过滤器、频道(guild)支持、滑动验证码处理、MIME 文件识别、管理 API(adminApi) 以及 常见问题(QA),可作为深入使用的参考。
总结
go-cqhttp 以 Go 原生实现、跨平台、轻量著称,通过完整兼容 OneBot-v11 标准并在此基础上扩展大量 CQ 码、API 与事件,为 QQ 机器人开发提供了统一、清晰的协议入口。本文从接口兼容、消息模型、事件体系、配置与启动流程、底层源码实现五个维度对其进行了系统梳理——理解coolq/的 CQ 码转换链路、modules/config/的配置解析机制、modules/servers/的服务注册机制,以及cmd/gocq/的登录与签名流程,是深入掌握 go-cqhttp 并进行二次开发的关键。需要注意的是,项目 README 已声明协议维护停止,生产环境选型时应关注其维护状态与替代方案。
- 后端
- 即时通讯
- API网关
【免费下载链接】go-cqhttp
cqhttp的golang实现,轻量、原生跨平台.
相关推荐
Go-CQHTTP:基于Golang的高性能QQ机器人框架
Go CQHTTP:基于Golang的高性能QQ机器人框架 Go CQHTTP是一个基于Golang编写的QQ机器人框架,它实现了OneBot协议的标准,为开发
后端即时通讯API网关go-cqhttp API完整指南:30+接口让你的QQ机器人功能全面解锁
go cqhttp API完整指南:30+接口让你的QQ机器人功能全面解锁 go cqhttp 是 CQHTTP 的 Golang 原生实现,提供 30+ 个
后端即时通讯API网关RC2 分组密码的 Go 实现深度解析:基于 crypto/cipher.Block 接口的兼容封装
RC2 分组密码的 Go 实现深度解析:基于 crypto/cipher.Block 接口的兼容封装 导读 本文以 scan4all 仓库 vendored 的
网络安全漏洞扫描渗透测试应用安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考