AI 搜索 | Cloudflare Vectorize 实现问答搜索

AI 搜索 | Cloudflare Vectorize 实现问答搜索

2026年5月14日星期四 · #设计文档 AI / RAG / Cloudflare · 3526 字 18 分钟 ·
-浏览量
·
简介

基于 Cloudflare Vectorize 实现博客 AI 语义搜索,涵盖 Markdown 分块、向量化、RAG 检索及 Worker 流式问答。

AI 搜索 | Cloudflare Vectorize 实现问答搜索#

背景#

博客已有 Pagefind 全文搜索,但它是关键词匹配——用户搜「缓存穿透怎么解决」,如果文章标题和正文中没有这几个字,就搜不到。

需要的是语义搜索:用户提问,AI 基于博客内容生成回答,并附上参考文章链接。

架构#

┌─────────────────────────────────────────────┐
│ 前端 Svelte 聊天组件 │
│ POST /api/ai-chat → SSE 流式接收 │
└──────────────┬──────────────────────────────┘
┌─────────────────────────────────────────────┐
│ Cloudflare Worker │
│ 1. 问题 → embedding 向量 │
│ 2. Vectorize 检索 topK 相似段落 │
│ 3. 拼接 prompt(系统指令 + 检索结果 + 问题)│
│ 4. 调用 LLM 流式生成回答 │
│ 5. SSE 返回 chunk + 参考文章 │
└──────────────┬──────────────────────────────┘
┌─────────────────────────────────────────────┐
│ Cloudflare Vectorize │
│ 存储所有文章段落的向量 + metadata │
└─────────────────────────────────────────────┘

核心是 RAG(Retrieval-Augmented Generation):先检索再生成。

文档分块策略#

直接把整篇文章向量化效果差——一篇 3000 字的文章,embedding 模型只能捕捉到主题,丢失细节。

做法是按 Markdown heading 切段:

## 缓存穿透
缓存穿透是指查询一个一定不存在的数据...
### 解决方案
1. 布隆过滤器...
2. 缓存空值...

每个段落保留上下文:文章标题 + 日期 + 分类 + 标签 + 章节标题路径 + 正文。打包成一个 chunk:

文章:Redis 缓存设计
日期:2025-03-15
分类:笔记
标签:Redis, 缓存
章节:缓存问题 > 缓存穿透
缓存穿透是指查询一个一定不存在的数据...

空字段(如无分类、无标签)自动省略,通过 .filter(Boolean) 过滤空行。过滤条件:正文少于 50 字的段落丢弃(太短没有检索价值)。

实现细节#

分块逻辑在 scripts/build-vectorize-index.jssplitByHeadings() 中:

function splitByHeadings(content, articleTitle) {
const lines = content.split("\n");
const chunks = [];
let currentHeadingPath = [];
let currentContent = [];
function flush() {
const text = currentContent.join("\n").trim();
if (text.length < 50) return;
chunks.push({ heading: currentHeadingPath.join(" > ") || articleTitle, text });
}
for (const line of lines) {
const headingMatch = line.match(/^(#{1,4})\s+(.+)/);
if (headingMatch) {
flush();
currentContent = [];
const level = headingMatch[1].length;
const title = headingMatch[2].trim();
currentHeadingPath = currentHeadingPath.slice(0, level - 1);
currentHeadingPath[level - 1] = title;
} else {
currentContent.push(line);
}
}
flush();
return chunks;
}

关键点:

  • 只识别 # ~ #### 四级标题,遇到标题就切段
  • currentHeadingPath 维护层级路径,如 缓存问题 > 缓存穿透 > 解决方案
  • 每个 chunk 的 ID 由 slug::heading 哈希生成,保证同一章节始终对应同一向量 ID
  • 每个 chunk 携带 metadata(articleTitlearticlePathpublishedcategorytagsheadingexcerpt),供检索结果展示和去重使用

与 LangChain 递归分块的对比#

维度Heading 分块(本博客)LangChain RecursiveCharacterTextSplitter
切分依据语义边界:Markdown 标题层级字符边界:分隔符列表递归切分
文档结构理解理解章节层级关系纯文本处理,无结构感知
语义完整性高,每个 chunk 对应完整小节低,可能把一句话切成两半
Chunk 大小控制被动,取决于标题下内容多少主动,可精确控制 chunk_size
超长处理无,一个标题下几千字仍作为一个 chunk有,超长自动继续递归切分
元信息注入自动注入文章标题、日期、分类、标签、章节路径默认不注入,需额外处理
实现复杂度简单(正则匹配标题)中等(递归逻辑 + 分隔符管理)
适用场景技术文档、博客等结构清晰的 Markdown小说、散文、无结构文本

LangChain 递归分块的核心逻辑(伪代码):

separators = ["\n\n", "\n", ". ", " ", ""] # 从大到小
for sep in separators:
chunks = text.split(sep)
if all(len(c) <= chunk_size for c in chunks):
break
# 太长的继续用更小的分隔符递归切分

本博客方案的潜在问题:如果一个标题下的内容非常长(比如一个 # 下面有几千字),生成的 chunk 会很大,可能导致 embedding 质量下降、检索粒度太粗。

改进方向:先按 Heading 切分保留语义边界,再对超长段落做二次字符切分,同时让子 chunk 继承父标题路径。

向量化与存储#

构建脚本#

scripts/build-vectorize-index.js 负责:

  1. 读取 src/content/posts/ 下所有非 draft 文章
  2. 按 heading 切段,生成 chunk 列表
  3. 调用 embedding API 生成向量
  4. 批量写入 Cloudflare Vectorize

支持增量更新——通过 .vectorize-manifest.json 记录每篇文章的内容 hash,只处理新增/修改/删除的文章。具体用法和底层 API 见下文「向量索引上传」小节。

Embedding 来源#

两种模式,三者齐备时走第三方 API,否则用 Cloudflare Workers AI 免费模型:

模式模型维度特点
第三方 APIQwen3-Embedding-8B1024中文效果好,需要 API Key
Workers AIbge-base-en-v1.5768免费,英文为主

对话模型同样有两种模式:

模式模型特点
第三方 APIDeepSeek-V4-Flash效果好,需要 API Key
Workers AIllama-3-8b-instruct免费,英文为主

配置在 .env 中(仅敏感信息),参考 .env.example

Terminal window
# Cloudflare 凭证(必填)
CLOUDFLARE_API_TOKEN=xxx
CLOUDFLARE_ACCOUNT_ID=xxx
# 第三方 AI API Key(可选,有则走第三方 API,无则回退 Workers AI)
AI_API_KEY=sk-xxx

非敏感配置(API 地址、模型名称、向量维度等)统一在 aiSearchConfig.ts 中管理,无需在 .env 重复配置。

Cloudflare 凭证获取#

CLOUDFLARE_API_TOKEN

  1. 登录 Cloudflare Dashboard
  2. 右上角头像 → My ProfileAPI TokensCreate Token
  3. 选择 Create Custom Token,权限勾选:
    • AccountVectorizeEdit
    • AccountWorkers AIUse
  4. 创建后复制 Token(页面关闭后无法再查看)

CLOUDFLARE_ACCOUNT_ID

  1. 登录 Cloudflare Dashboard
  2. 点击任意域名 → 概览页右侧栏 API 区域 → 复制 Account ID
  3. 或直接从 URL 中复制:https://dash.cloudflare.com/<account_id>/...

AI_API_KEY(可选):

当前使用魔搭社区(ModelScope)的免费接口,注册即可获取:

  1. 注册 ModelScope
  2. 右上角头像 → API-KEY 管理创建 API Key

Worker Secret 配置#

Worker 运行时需要的 AI_API_KEY 不能写在代码中,需在 Cloudflare Dashboard 配置:

  1. 登录 Cloudflare Dashboard
  2. Workers & Pages → 选择你的 Worker → SettingsVariables and Secrets
  3. 添加 Secret 类型变量:AI_API_KEY,值为第三方 API 的 Key

向量索引上传#

构建脚本 scripts/build-vectorize-index.js 通过 Cloudflare REST API 操作 Vectorize(不是 Wrangler CLI):

Terminal window
# 首次使用前,确保 .env 已配置 CLOUDFLARE_API_TOKEN 和 CLOUDFLARE_ACCOUNT_ID
# 增量更新(只处理新增/修改/删除的文章)
node scripts/build-vectorize-index.js
# 全量重建(删除旧索引,重新创建并上传所有文章向量)
node scripts/build-vectorize-index.js --force

全量重建流程:删除旧索引 → 创建新索引(指定维度和 cosine 度量)→ 分批生成 embedding → 分批插入向量。增量更新通过 .vectorize-manifest.json 记录每篇文章的内容 hash,只处理有变化的文章。

底层 API 调用:

// 插入向量
await fetch(`${API_BASE}/vectorize/v2/indexes/${INDEX_NAME}/insert`, {
method: "POST",
headers: { Authorization: `Bearer ${API_TOKEN}` },
body: JSON.stringify({ vectors }),
});
// 删除向量
await fetch(`${API_BASE}/vectorize/v2/indexes/${INDEX_NAME}/delete-by-ids`, {
method: "POST",
headers: { Authorization: `Bearer ${API_TOKEN}` },
body: JSON.stringify({ ids: batch }),
});
// 查询(Worker 运行时通过绑定调用,不需要 API Token)
const results = await env.VECTORIZE.query(queryVector, {
topK: 10,
returnMetadata: true,
});

Worker 端问答流程#

src/worker.js 中的 handleAIChat 处理 /api/ai-chat

1. 统一配置管理#

所有 AI 相关配置集中在 src/config/aiSearchConfig.ts,前端组件、构建脚本、Worker 三方共享:

export const aiSearchConfig = {
apiUrl: "https://api-inference.modelscope.cn/v1", // API 地址
modelName: "deepseek-ai/DeepSeek-V4-Flash", // LLM 对话模型
embeddingModel: "Qwen/Qwen3-Embedding-8B", // 向量模型
vectorizeDim: 1024, // 向量维度
batchSize: 500, // 构建脚本批大小
embedBatchSize: 50, // Embedding 请求批大小
indexName: "blog-ai-search", // Vectorize 索引名
};

Worker 运行时通过 getAiConfig(env) 读取配置,非敏感项从 aiSearchConfig 取值,仅 API Key 从环境变量 env.AI_API_KEY 注入。当配置项和 API Key 都存在时走第三方 API,否则回退到 Cloudflare Workers AI 内置模型。

2. Embedding#

async function getEmbedding(env, text) {
const cfg = getAiConfig(env);
if (useThirdParty(env)) {
const res = await fetch(buildApiUrl(cfg.apiUrl, "/v1/embeddings"), {
method: "POST",
headers: {
Authorization: `Bearer ${cfg.apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: cfg.embeddingModel,
input: text,
dimensions: cfg.vectorizeDim,
encoding_format: "float",
}),
});
if (!res.ok)
throw new Error(`Embedding API ${res.status}: ${await res.text()}`);
const data = await res.json();
return data.data?.[0]?.embedding;
}
const result = await env.AI.run("@cf/baai/bge-base-en-v1.5", { text });
return result.data[0];
}

模型名和维度均从 aiSearchConfig 读取,切换模型只需改配置文件。

3. 向量检索#

const queryVector = await getEmbedding(env, question);
const results = await env.VECTORIZE.query(queryVector, {
topK: 10,
returnMetadata: true,
});

过滤 score < 0.2 的低相似度结果,按 articlePath 去重后拼接上下文。每条匹配结果格式为 【文章标题 - 章节标题】\n摘要,用 --- 分隔。去重后的文章信息(标题、路径、发布日期、摘要、相似度分数)作为 refs 事件先于回答发送。

4. Prompt 拼接与 system 注入防护#

系统提示(system prompt)决定了 AI 的人格和行为准则。如果用户通过构造请求在 history 中插入 role: "system" 的消息,就可能覆盖或绕过预设人格——这称为 system 注入攻击

防护措施:在拼接 messages 之前,过滤掉 history 中所有 role === "system" 的条目,确保只有服务端硬编码的 systemPrompt 生效:

const safeHistory = history.filter((m) => m.role !== "system").slice(-6);
const messages = [
{ role: "system", content: systemPrompt },
...safeHistory,
{ role: "user", content: question },
];

当前人格设定为猫娘「喵墩」,系统提示包含完整的角色背景、语言规范、性格画像等,与博客检索规则拼接后传给 LLM。

5. 流式返回#

SSE 格式,四种事件类型:

data: {"type":"refs","articles":[...]} ← 参考文章(先发)
data: {"type":"chunk","text":"..."} ← 回答文本片段
data: {"type":"error","error":"..."} ← 错误信息
data: {"type":"done"} ← 结束

LLM 后端由 aiSearchConfig 决定:配置了 apiUrl + modelName + AI_API_KEY 时走第三方 API(OpenAI 兼容格式流),否则回退 Workers AI(@cf/meta/llama-3-8b-instruct,Cloudflare 原生流)。

前端组件#

src/components/controls/AISearch.svelte,Svelte 5 + runes。

核心交互:

  • 入口:导航栏「工具」菜单触发 toggle-ai-search 事件,或 Ctrl+K 快捷键
  • 聊天面板:全屏遮罩 + 居中卡片,移动端底部弹起
  • 流式渲染:逐字显示(打字机效果),光标闪烁动画
  • 参考文章:AI 回答下方显示可点击的原文链接
  • 多轮对话:保留最近 6 条历史消息作为上下文
  • Markdown 渲染:使用 marked 库,支持代码块、列表、引用
  • 会话管理:localStorage 持久化,支持新建、切换、删除、上限控制
  • 建议按钮:空对话时显示预设问题,点击直接发送
  • 模型名显示:标题栏展示当前使用的对话模型名称
  • 停止生成:生成中可点击停止按钮中断流式响应
  • 错误处理:SSE error 事件和请求异常均以引用块形式展示

关键状态管理:

let messages = $state<Message[]>([]);
let isLoading = $state(false);
let abortCtrl: AbortController | null = null;
let reader: ReadableStreamDefaultReader<Uint8Array> | null = null;
let sessionId = $state("");
let sessionList = $state<SessionMeta[]>([]);
let showSessionList = $state(false);

流式读取使用 ReadableStream + TextDecoder,逐行解析 SSE data。生成中可通过 AbortController 中断请求,同时取消 reader。前端处理四种 SSE 事件:refs(参考文章)、chunk(文本片段)、error(错误信息)、done(结束)。

会话管理#

数据结构设计#

interface SessionMeta {
id: string; // 会话唯一标识
title: string; // 自动提取的第一条用户消息(前20字)
updatedAt: number; // 最后更新时间戳
}

localStorage 存储策略:

  • ai-chat:sessions — 会话元数据列表(JSON 数组)
  • ai-chat:session:{id} — 单个会话的完整消息记录

新建会话#

标题栏「新建会话」按钮(add-circle-outline 图标),点击后:

  1. 保存当前会话到 localStorage
  2. 生成新的 sessionId
  3. 清空消息列表,开始新对话
function startNewSession() {
saveCurrentSession();
sessionId = generateSessionId();
messages = [];
showSessionList = false;
}

历史会话列表#

标题栏「历史」按钮(history 图标),点击展开/收起下拉面板:

{#if showSessionList}
<div class="ai-session-list">
{#each sessionList as sess}
<button
class="ai-session-item"
class:ai-session-item-active={sess.id === sessionId}
onclick={() => switchSession(sess.id)}
>
<div class="ai-session-info">
<span class="ai-session-title">{sess.title}</span>
<span class="ai-session-time">{formatTime(sess.updatedAt)}</span>
</div>
<!-- 悬停显示删除按钮 -->
<span onclick={(e) => { e.stopPropagation(); deleteSession(sess.id); }}>
<Icon icon="material-symbols:close" size="sm" />
</span>
</button>
{/each}
</div>
{/if}

会话切换#

点击历史会话项切换到该会话,自动保存当前会话后加载目标会话的消息:

function switchSession(id: string) {
if (id === sessionId) { showSessionList = false; return; }
saveCurrentSession();
sessionId = id;
messages = loadSessionMessages(id);
showSessionList = false;
scrollToBottom();
}

会话删除#

鼠标悬停会话项时出现删除按钮(close 图标),删除后若删除的是当前会话则自动新建会话:

function deleteSession(id: string) {
localStorage.removeItem(STORAGE_SESSION_PREFIX + id);
sessionList = sessionList.filter((s) => s.id !== id);
saveSessionListToStorage(sessionList);
if (id === sessionId) {
startNewSession();
}
}

会话上限与自动清理#

最多保留 20 个会话,超出时自动清理最旧的:

const MAX_SESSIONS = 20;
// 保存时检查上限
if (sessionList.length > MAX_SESSIONS) {
const removed = sessionList.splice(MAX_SESSIONS);
for (const s of removed) {
localStorage.removeItem(STORAGE_SESSION_PREFIX + s.id);
}
}

自动保存时机#

  • 每次 AI 回复完成后send()finally 块中调用 saveCurrentSession()
  • 组件卸载时onMount 返回的清理函数中保存
  • 新建/切换会话前:先保存当前会话再操作
function saveCurrentSession() {
if (!sessionId || messages.length === 0) return;
if (messages.some((m) => m.streaming)) return; // 流式中不保存
localStorage.setItem(STORAGE_SESSION_PREFIX + sessionId, JSON.stringify(messages));
// 更新 sessionList 元数据...
}

初始化恢复#

组件挂载时自动恢复最近会话:

onMount(() => {
sessionList = loadSessionListFromStorage();
if (sessionList.length > 0) {
const latest = sessionList[0];
sessionId = latest.id;
messages = loadSessionMessages(latest.id);
} else {
sessionId = generateSessionId();
}
// ...
return () => {
saveCurrentSession(); // 卸载时保存
};
});

敏感配置处理#

非敏感配置集中在 src/config/aiSearchConfig.ts,三方共享。敏感信息(API Key)的配置方式见上文「Worker Secret 配置」小节。

资源消耗#

资源免费额度单次问答消耗日均可用
Workers AI10k tokens/天~500-1000 tokens10-20 次
Vectorize30M 查询/月1 次查询~1M 次/天
Worker 请求100k/天1 次请求100k 次/天

个人博客完全够用。

文件清单#

文件作用
scripts/build-vectorize-index.js向量索引构建脚本
src/worker.jshandleAIChatWorker 端 RAG 问答 API
src/config/aiSearchConfig.tsAI 搜索统一配置中心
src/components/controls/AISearch.svelte前端聊天 UI
.env.example环境变量模板(含获取说明)
wrangler.tomlVectorize + AI 绑定配置
.vectorize-manifest.json增量更新 manifest(gitignored)

踩坑记录#

1. 向量维度不一致

构建脚本用第三方 API 生成 1024 维向量,但 Vectorize 索引创建时指定了 768 维(Workers AI 的默认值)——写入直接报错。必须保证 VECTORIZE_DIM 和索引创建时的 --dimensions 一致。

2. Embedding URL 拼接

第三方 API 的 base URL 可能带 /v1/chat/completions 后缀,需要统一清理再拼 /v1/embeddings

function buildApiUrl(base, suffix) {
return base
.replace(/\/+$/, "")
.replace(/\/v1\/?$/, "")
.replace(/\/chat\/completions\/?$/, "") + suffix;
}

3. Workers AI 流式响应格式

Workers AI 的流式响应和 OpenAI SSE 格式不同,不能用同一套解析逻辑。需要分别处理,且 Workers AI 可能回退到非流式模式(需要额外处理 response 字段)。

4. 相似度阈值

Vectorize 返回的 cosine score 分布因 embedding 模型而异。实测 Qwen3-Embedding 的 score 整体偏低,0.2 以下基本是无关内容。阈值需要根据实际效果调整。

AI 搜索 | Cloudflare Vectorize 实现问答搜索
https://tblog.mmzhiku.xyz/posts/ai/ai-blog-ai-search-vectorize/
作者
MmzMing
发布于
2026-05-14
许可协议
CC BY-NC-SA 4.0

评论区

看板娘
公告
友链 互换友链

正在招募技术类博客友链,要求原创、稳定更新。点击了解更多。

查看详情
维护 服务器升级

本周日凌晨 2:00-4:00 进行服务器维护,期间站点可能短暂无法访问。

欢迎 关于我的介绍

欢迎来到我的博客,我是深耕java、python和react技术开发。热爱技术、持续学习,欢迎同好交流探讨,也欢迎大佬互换友链。

查看详情
音乐
封面

音乐

暂未播放

0:00
0:00
暂无歌词
标签
# AI 6 # 认证 5 # 安全 4 # 登录 3 # Skill 2 # Redis 2 # Bitmap 2 # 部署 2 # Java 2 # 并发编程 2 # 性能优化 2 # 前端 1 # 博客 1 # Prompt 1 # 工作流 1 # RAG 1 # Cloudflare 1 # 缓存设计 1 # 高性能 1 # Bot 1 # Umami 1 # Vercel 1 # 线程池 1 # 虚拟线程 1 # 分布式 1 # JWT 1 # OAuth2 1 # MinIO 1 # 对象存储 1 # 扫码登录 1 # WebSocket 1 # Agent 1 # Oracle 1 # 数据库 1
目录
工具

隐私政策

更新日期: 2026 年 7 月 15 日
生效日期: 2026 年 7 月 15 日

适用范围#

本政策适用于 MmzMing 的博客(以下简称“本站”)。本站是个人博客,用于发布和分享内容;不提供账户注册、支付、定位或广告投放服务。访问本站、发表文章评论或在留言板留言前,请阅读本政策。

信息收集与使用#

本站只在提供内容、评论和留言功能,以及维护站点安全所需的范围内处理信息。

  • 访问与统计信息:访问页面时,统计服务可能处理访问时间、页面地址、来源页、浏览器和设备相关信息,用于了解内容访问情况、排查故障和改进站点。
  • 评论信息:使用文章评论功能时,Waline 可能处理您主动提交的昵称、邮箱、站点链接和评论内容;还可能处理 IP 地址等必要信息,用于防止垃圾评论、滥用和维护服务安全。评论内容、昵称和站点链接(如填写)可能公开展示在文章下方;邮箱不会公开展示。
  • 留言信息:留言板使用 Waline /guestbook/ 频道。Waline 可能处理您主动提交的昵称、可选邮箱、站点链接、留言内容和图片,以及浏览器、操作系统、IP 地址等必要的反滥用信息。默认情况下,留言图片以内嵌数据随留言提交;如站点维护者配置了远程图片上传接口,图片会先发送至该接口并在留言中保存返回的图片地址。留言内容、昵称、图片和站点链接(如填写)可能公开展示;邮箱和 IP 地址不会在留言板公开展示。
  • AI 对话信息:使用 AI 搜索时,本站会处理您提交的问题以及最近 6 条对话历史,用于检索博客内容并生成回答。问题和对话历史会发送至 ModelScope,或在第三方接口不可用时由 Cloudflare Workers AI 处理。请勿在 AI 对话中提交密码、Token、身份证件、联系方式或其他敏感信息。

请不要在评论或留言中提交身份证件、银行卡、住址、密码或其他不必要的敏感个人信息。

第三方服务#

为实现本站功能,以下第三方会在各自服务范围内处理相关数据:

  • Umami:用于匿名化的网站访问统计和出站链接点击统计,帮助我了解本站的使用情况。
  • Waline:用于文章评论、留言板及访问量统计。服务会按照其自身规则处理您在评论或留言时提交的信息及必要的反滥用信息。
  • Cloudflare:为本站提供静态资源分发、AI Worker、Vectorize 和相关基础设施。留言板不使用项目 Worker 或 KV 存储。
  • ModelScope:为 AI 搜索提供文本向量和对话模型服务,会处理您提交的问题及发送给模型的最近对话历史。
  • Cloudflare Workers AI:在未配置第三方 AI 接口时提供文本向量和对话模型服务,并处理相同的 AI 请求数据。
  • unpkg:用于加载 Waline 的前端脚本、样式和表情资源;请求这些资源时,您的浏览器会与该服务建立连接。

第三方服务可能有独立的隐私政策和数据保存规则。请在使用相关功能前查阅其规则;本站无法控制其独立的数据处理活动。

本站主要使用浏览器本地存储(Local Storage 或 Session Storage)保存使用偏好,例如主题颜色、明暗模式、文章列表视图和音乐播放设置。留言板会在本地保存匿名资料、未发送草稿和登录状态,以便恢复输入与会话;管理员登录状态仅保存在当前会话。AI 搜索的会话标题和完整对话也会保存在当前浏览器的 Local Storage 中,最长保存 7 天;您可以在 AI 面板中使用“清空全部会话”立即删除这些数据。

本站不主动设置用于广告定向的第一方 Cookie。评论、统计或资源服务可能按照其自身规则使用 Cookie 或类似技术。您可以通过浏览器设置查看、删除或限制 Cookie 和本地存储;清除后,部分偏好或互动状态可能会恢复为默认值,评论功能也可能受到影响。

信息公开、保存与安全#

评论和留言属于公开互动内容,提交后可能被搜索引擎收录、被他人引用或在缓存中短暂保留。请谨慎决定发布内容。除非您提出删除请求、内容违反规则或法律法规另有要求,公开内容会持续保留以维持讨论上下文。

本站会采取合理措施保护数据安全,包括使用 HTTPS、输入校验、内容转义和访问频率限制。但互联网传输和第三方服务均无法保证绝对安全,请理解并自行承担公开发布信息的相应风险。

你的权利#

你可以通过 784774835@qq.com 联系我,申请查询、更正或删除由本站直接保存的评论、留言或相关公开内容。为保护他人权益,请在请求中提供足以定位内容的信息,并说明你与该内容的关系;必要时可能需要进行合理核验。

对于由 Waline、Umami、Cloudflare 或 unpkg 独立处理的数据,你也可以直接向对应服务提供方行使相关权利。删除公开评论或留言后,第三方缓存、搜索引擎索引或他人转载的副本可能无法立即同步删除。

未成年人条款#

未满 14 周岁的未成年人应在监护人同意和指导下使用本站的评论、留言等互动功能。监护人如发现未成年人未经同意提交了个人信息,可通过上述联系方式与我联系,我会在合理范围内协助处理。

政策更新与联系#

我可能因本站功能或适用规则变化更新本政策,更新后的版本将在本站公布并标明日期。继续使用相关功能即表示你已阅读并理解更新后的政策。

如对本政策或数据处理有疑问,请联系 784774835@qq.com

用户协议

更新日期: 2026 年 5 月 19 日
生效日期: 2026 年 5 月 19 日

适用范围#

本协议适用于你访问 MmzMing 的博客,以及使用文章评论、留言板等互动功能的行为。继续浏览本站或提交评论、留言,即表示你已阅读、理解并同意遵守本协议及本站的隐私政策。

评论及留言规则#

请在交流中保持友善、理性和尊重。你不得利用本站发布、传播或实施以下行为:

  • 发布任何违反中华人民共和国法律法规的内容。
  • 发布任何侵犯他人合法权益的内容,包括但不限于隐私、名誉、肖像、著作权、商标权和其他知识产权。
  • 恶意攻击、辱骂、骚扰、威胁、歧视其他用户或任何第三方。
  • 发布垃圾广告、恶意推广、刷屏、灌水,或与讨论主题明显无关的重复内容。
  • 利用本站进行网络诈骗、钓鱼、传播恶意软件,或发布可能危害网络和信息安全的内容。
  • 绕越或试图绕越本站的审核、限流、封禁等管理措施。
  • 冒充他人、伪造身份,或收集、公开他人的个人信息。

内容与访问管理#

你应对自己发布的评论和留言负责,并保证拥有发布该等内容所需的合法权利。论坛管理员有权在不另行通知的情况下删除违规内容、限制或封禁违规账号,或限制其继续使用本站互动功能。

如发现涉嫌违法犯罪、严重侵权或危及本站安全的内容,本站可保留相关记录,并在法律法规要求或必要时向有关部门提供协助。对管理措施有疑问时,可通过文末联系方式说明情况;本站会结合实际情况处理,但不承诺恢复已删除内容或访问权限。

知识产权与内容授权#

本站原创文章、页面设计和其他受保护内容的权利归作者或权利人所有。未经授权,请勿复制、转载、镜像或用于商业用途;法律法规允许的合理使用除外。

你发布评论或留言时,授予本站为展示、存储、备份、审核、删除和维护互动功能所必需的非独占、免费的使用许可。该许可不改变你对原创内容依法享有的权利。

免责声明#

本站内容仅用于个人记录、学习交流和一般信息参考,不构成任何专业意见、承诺或担保。你应结合自身情况独立判断,并对据此采取的行动负责。

评论、留言和外部链接中的内容由其发布者或运营者负责,不代表本站立场。本站会在合理范围内处理明显违规内容,但不保证所有内容均及时发现,也不对第三方网站的可用性、内容、安全性或隐私实践承担责任。

因网络故障、不可抗力、第三方服务异常、维护升级或超出合理控制范围的原因导致本站暂时无法访问、内容延迟或数据丢失的,本站会尽力恢复,但不承担由此产生的间接损失。

未成年人条款#

未满 14 周岁的未成年人应在监护人同意和指导下使用评论、留言等互动功能。监护人应协助未成年人理解本协议,并对其使用行为进行必要的引导。

其他条款#

我可以根据本站功能、管理需要或法律法规变化更新本协议,更新后的版本将在本站公布并标明日期。继续使用本站即视为接受更新后的协议。

本协议的订立、执行和解释适用中华人民共和国法律。因本协议或使用本站产生争议时,双方应先友好协商;协商不成的,依法向有管辖权的人民法院解决。

如对本协议或内容管理有疑问,请联系 784774835@qq.com