Hexo 博客专属AI助手

本项目通过向量检索 + 大语言模型(RAG)结合本地 Hexo 博客内容,实现基于语义的智能问答接口。


项目地址:https://github.com/EvannZhongg/hexo-ai-assistant.git


项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
📁 D:/YourProjects/
├── 📁 Blog/ # Hexo 博客项目目录
│ ├── source/_posts/ # Markdown 博文文件目录
│ ├── themes/hexo-theme-xxx/ # 自定义主题目录
│ │ ├── layout/_partial/
│ │ │ ├── footer.ejs # 向量构建自动化脚本(Hexo 构建钩子)
│ │ │ ├── chatbot.ejs # ai助手UI
│ │ │ └── ...
│ │ └── ...
│ ├── scripts/auto_vector.js # 向量构建自动化脚本(Hexo 构建钩子)
│ └── ... # 其他 Hexo 文件

├── 📁 hexo-ai-assistant/ # AI助手后端项目目录
│ ├── build_vector_store.py # 向量库和标题映射构建脚本
│ ├── main.py # Flask 主服务入口(/ask 问答接口)
│ ├── embedder.py # 嵌入向量生成器(调用第三方 API)
│ ├── chat.py # 通用 LLM 聊天模块(OpenAI / DeepSeek)
│ ├── vector_store.json # 本地语义向量数据库(自动生成)
│ ├── title_mapping.json # 博客标题与链接映射表(自动生成)
│ ├── config.yml # 所有路径、模型、API Key 配置集中管理
│ └── .venv/ # 虚拟环境(可选)

执行原理(项目运行流程)

  1. 语义知识构建阶段(由 build_vector_store.py 执行):

    • 扫描博客的 Markdown 源文件,提取文章正文内容。
    • 使用嵌入模型(如 BGE)生成语义向量。
    • 构建 vector_store.jsontitle_mapping.json,供问答使用。
  2. 用户问答处理阶段(由 main.py 提供 API):

    • 用户通过前端发送提问。
    • 后端提问向量化,与本地向量库匹配最相关文章。
    • 拼接问答上下文(包含语义内容和标题索引)发给大语言模型。
    • 模型生成带参考链接的回答,流式返回至前端。
  3. 前端问答展示阶段(由 chat.html / chatbot.ejs 负责):

    • 用户界面加载聊天框,支持 Markdown 格式渲染和多轮对话。
    • 请求被代理转发至本地后端或公网中转地址。

1. 安装依赖

建议使用虚拟环境:

1
2
3
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt

2. 配置项修改(hexo-ai-assistant/config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
paths:
blog_post_dir: /your/path/to/hexo/source/_posts # 修改为你的博客 Markdown 路径
vector_store: vector_store.json # 向量库保存路径,建议使用绝对路径
title_mapping: title_mapping.json # 博客标题映射表路径,建议使用绝对路径

blog:
base_url: https://your-github-pages-url.github.io # 修改为你的博客地址(不含末尾 /)

embedding:
api_url: https://api.siliconflow.cn/v1/embeddings # 嵌入模型 API 地址
model: BAAI/bge-large-zh-v1.5 # 使用的中文嵌入模型
api_key: <YOUR_EMBEDDING_API_KEY> # 替换为你的嵌入模型 API Key
max_characters: 5000 # 每篇文章最大截取字符数

chat:
api_url: https://api.deepseek.com/v1 # Chat 模型 API 地址(可替换为 OpenAI)
model: deepseek-chat # 使用的模型名称
api_key: <YOUR_CHAT_API_KEY> # 替换为你的 LLM 接口 Key

server:
port: 5000 # 后端服务运行端口(默认5000)

3. 构建向量库 & 标题映射表

1
python build_vector_store.py

生成文件:

  • vector_store.json: 含每篇文章的文本和语义向量
  • title_mapping.json: 含每篇文章的标题 + 主标题 + 链接

博客格式需遵循以下结构:

1
2
3
4
5
6
7
8
9
---
title: Article Title
date: YYYY-MM-DD HH:mm:ss
tags: [...] # No impact
categories: ... # No impact
---
# Main Title # Must be a first level title

正文内容...

4. 启动后端问答服务

1
python main.py

本地服务启动后默认监听:

1
http://127.0.0.1:5000/ask

你可以在浏览器中打开 chat.html 进行测试,查看是否可以正确输出回答。


5. 配置 Hexo 脚本

如果上述操作都正确执行后,将向量构建脚本接入 Hexo 构建流程

1.创建脚本文件 scripts/auto_vector.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const { exec } = require("child_process");

hexo.extend.filter.register("before_generate", function () {
console.log("构建博客向量中...");
return new Promise((resolve, reject) => {
exec("/your_project/.venv/Scripts/python build_vector_store.py", {
cwd: "D:/your_project"
}, (err, stdout, stderr) => {
if (err) {
console.error("构建失败:", stderr);
reject(err);
} else {
console.log("构建成功");
resolve();
}
});
});
});

这个脚本的作用是在运行 hexo g 时,自动重构向量库保证所有博客均被项链化。

2. 在页面底部引入 ejs 文件

打开文件:

1
themes/hexo-theme-Chic/layout/_partial/footer.ejs

</footer> 标签之后添加以下代码:

1
<%- partial('chatbot') %>

新建文件 chatbot.ejs 在路径 themes\hexo-theme-Chic\layout\_partial\chatbot.ejs

1
2
将chatbot.ejs的代码拷贝至此处
完整代码文件可见文章开头的项目地址中

运行以下命令,重新生成并启动本地预览:

1
2
3
hexo clean
hexo g
hexo d

效果如下:
image


6. 使用 Ngrok 暴露后端接口(可选)

在本地测试都没问题后,可以使用 Ngrok 暴露本地服务至公网

1
ngrok http 5000

https://xxx.ngrok-free.app/ask 地址填入前端请求 chatbot.ejs 中:

1
const response = await fetch("https://xxx.ngrok-free.app/ask", {...});

只使用 Ngrok 有网路安全问题,你可以自行设置代理保证你的端口不被暴露在公网中。


完整流程总结

  1. 写好博客(Markdown 文件),保证格式符合要求
  2. build_vector_store.py 提取文本并生成向量
  3. main.py 启动问答服务并支持语义检索
  4. 前端请求通过 Ngrok 访问服务
  5. 模型结合语义内容和标题表生成参考明确的回答

该项目代码基于 Hexohexo-theme-Chic