484 lines
18 KiB
HTML
484 lines
18 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>All-in-RAG | 大模型应用开发实战:RAG技术全栈指南</title>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
|
<meta name="description" content="面向大模型应用开发者的RAG(检索增强生成)技术全栈教程,从零开始掌握RAG技术的核心原理与实际应用">
|
|
<meta name="viewport"
|
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
|
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@latest/lib/themes/vue.css">
|
|
<style>
|
|
/* --- 1. 原有样式保持 --- */
|
|
/* 脚注样式 */
|
|
.footnote {
|
|
margin-top: 20px;
|
|
padding: 10px;
|
|
background-color: #f8f9fa;
|
|
border-left: 4px solid #42b883;
|
|
font-size: 0.9em;
|
|
line-height: 1.4;
|
|
}
|
|
.footnote p {
|
|
margin: 0;
|
|
}
|
|
sup a {
|
|
color: #42b883;
|
|
text-decoration: none;
|
|
font-weight: bold;
|
|
}
|
|
sup a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
.footnote a {
|
|
color: #42b883;
|
|
text-decoration: none;
|
|
margin-left: 5px;
|
|
}
|
|
.footnote a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
/* Mermaid图表样式 */
|
|
.mermaid {
|
|
text-align: center;
|
|
margin: 20px 0;
|
|
}
|
|
.mermaid svg {
|
|
max-width: 100%;
|
|
height: auto;
|
|
}
|
|
/* Logo样式 */
|
|
.app-name-link {
|
|
display: flex !important;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
padding: 10px 0;
|
|
}
|
|
.app-name-link img {
|
|
max-height: 60px;
|
|
width: auto;
|
|
margin: 0 auto;
|
|
vertical-align: middle;
|
|
display: block !important;
|
|
}
|
|
.app-name {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
}
|
|
/* 隐藏文字,只显示logo */
|
|
.app-name-link .app-name-text {
|
|
display: none;
|
|
}
|
|
/* 调整侧边栏logo区域 */
|
|
.sidebar .app-name {
|
|
text-align: center;
|
|
padding: 15px 0;
|
|
}
|
|
/* 语言切换器样式 */
|
|
.app-nav {
|
|
position: fixed;
|
|
right: 20px;
|
|
top: 20px;
|
|
z-index: 10;
|
|
}
|
|
.app-nav ul {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
.app-nav li {
|
|
display: inline-block;
|
|
}
|
|
#lang-selector {
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
padding: 6px 12px;
|
|
font-size: 14px;
|
|
cursor: pointer;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
transition: all 0.3s;
|
|
}
|
|
#lang-selector:hover {
|
|
border-color: #42b883;
|
|
}
|
|
#lang-selector:focus {
|
|
outline: none;
|
|
border-color: #42b883;
|
|
box-shadow: 0 0 0 2px rgba(66, 184, 131, 0.2);
|
|
}
|
|
|
|
/* 修复表格渲染问题 */
|
|
.markdown-section table {
|
|
display: table;
|
|
width: auto;
|
|
max-width: 100%;
|
|
table-layout: auto;
|
|
}
|
|
|
|
/* --- 2. 新增:暗黑模式核心样式 --- */
|
|
:root {
|
|
--dark-bg: #1a1a1a;
|
|
--dark-sidebar: #141414;
|
|
--dark-border: #333;
|
|
--theme-color: #42b883;
|
|
|
|
/* 字体颜色优化:使用更高亮度的灰白色,提高对比度 */
|
|
--dark-text: #e6e6e6;
|
|
--dark-code-text: #f8f8f2;
|
|
--dark-code-bg: #2b2b2b;
|
|
}
|
|
|
|
/* 基础反色 */
|
|
body.dark-mode {
|
|
background-color: var(--dark-bg);
|
|
color: var(--dark-text);
|
|
}
|
|
|
|
/* 侧边栏适配 */
|
|
body.dark-mode .sidebar {
|
|
background-color: var(--dark-sidebar);
|
|
border-right: 1px solid var(--dark-border);
|
|
color: var(--dark-text);
|
|
}
|
|
body.dark-mode .sidebar-nav li a {
|
|
color: #999;
|
|
}
|
|
body.dark-mode .sidebar-nav li.active > a {
|
|
color: var(--theme-color);
|
|
border-right: 2px solid var(--theme-color);
|
|
}
|
|
|
|
/* 代码块适配 - 增强对比度 */
|
|
body.dark-mode pre {
|
|
background-color: var(--dark-code-bg) !important;
|
|
}
|
|
body.dark-mode code {
|
|
background-color: var(--dark-code-bg) !important;
|
|
color: var(--dark-code-text) !important;
|
|
}
|
|
/* 行内代码 */
|
|
body.dark-mode .markdown-section code {
|
|
color: #f08d49;
|
|
background-color: rgba(255,255,255,0.1);
|
|
}
|
|
|
|
/* 标题适配 */
|
|
body.dark-mode h1, body.dark-mode h2, body.dark-mode h3, body.dark-mode h4 {
|
|
color: #ffffff; /* 标题纯白 */
|
|
}
|
|
body.dark-mode blockquote {
|
|
color: #b0b0b0;
|
|
background: rgba(255,255,255,0.05);
|
|
border-left-color: var(--theme-color);
|
|
}
|
|
|
|
/* 表格适配 */
|
|
body.dark-mode .markdown-section tr:nth-child(2n) {
|
|
background-color: rgba(255,255,255,0.03);
|
|
}
|
|
body.dark-mode .markdown-section td,
|
|
body.dark-mode .markdown-section th {
|
|
border-color: var(--dark-border);
|
|
background-color: transparent;
|
|
}
|
|
|
|
/* --- 特殊组件适配 --- */
|
|
|
|
/* 1. 适配你的脚注 (footnote) */
|
|
body.dark-mode .footnote {
|
|
background-color: rgba(255,255,255,0.05); /* 深色背景 */
|
|
color: #cccccc;
|
|
border-left-color: var(--theme-color);
|
|
}
|
|
body.dark-mode .footnote a {
|
|
color: var(--theme-color);
|
|
}
|
|
|
|
/* 2. 适配语言选择下拉框 */
|
|
body.dark-mode #lang-selector {
|
|
background-color: #333 !important;
|
|
color: #fff !important;
|
|
border-color: #555 !important;
|
|
}
|
|
|
|
/* 3. Mermaid 图表反色 */
|
|
body.dark-mode .mermaid {
|
|
filter: invert(1) hue-rotate(180deg);
|
|
}
|
|
|
|
/* --- 3. 侧边栏开关按钮样式 --- */
|
|
.sidebar-toggle-btn {
|
|
cursor: pointer;
|
|
display: block;
|
|
text-align: center;
|
|
padding: 10px 0;
|
|
margin: 0 15px 10px 15px;
|
|
font-weight: bold;
|
|
font-size: 14px;
|
|
border-radius: 4px;
|
|
background-color: rgba(0,0,0,0.05);
|
|
color: #505d6b;
|
|
border: 1px solid rgba(0,0,0,0.05);
|
|
transition: all 0.3s;
|
|
}
|
|
body.dark-mode .sidebar-toggle-btn {
|
|
background-color: rgba(255,255,255,0.1);
|
|
color: #ccc;
|
|
border: 1px solid #444;
|
|
}
|
|
.sidebar-toggle-btn:hover {
|
|
background-color: var(--theme-color);
|
|
color: white;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div id="app"></div>
|
|
<script src="//cdn.jsdelivr.net/npm/mermaid@8.0.0-rc.8/dist/mermaid.min.js"></script>
|
|
<script>
|
|
window.$docsify = {
|
|
name: 'All-in-RAG',
|
|
repo: 'https://github.com/datawhalechina/all-in-rag',
|
|
logo: './logo.svg',
|
|
loadSidebar: true,
|
|
auto2top: true,
|
|
subMaxLevel: 3,
|
|
alias: {
|
|
'/en/_sidebar.md': '/en/_sidebar.md',
|
|
'/en/.*/_sidebar.md': '/en/_sidebar.md',
|
|
'/.*/_sidebar.md': '/_sidebar.md'
|
|
},
|
|
search: {
|
|
maxAge: 86400000,
|
|
paths: 'auto',
|
|
placeholder: {
|
|
'/en/': '🔍 Search',
|
|
'/': '🔍 搜索'
|
|
},
|
|
noData: {
|
|
'/en/': '😞 No Results',
|
|
'/': '😞 找不到结果'
|
|
},
|
|
depth: 6
|
|
},
|
|
pagination: {
|
|
previousText: {
|
|
'/en/': 'Previous',
|
|
'/': '上一章节'
|
|
},
|
|
nextText: {
|
|
'/en/': 'Next',
|
|
'/': '下一章节'
|
|
}
|
|
},
|
|
count: {
|
|
countable: true,
|
|
fontsize: '0.9em',
|
|
color: 'rgb(90,90,90)',
|
|
language: 'chinese'
|
|
},
|
|
|
|
plugins: [
|
|
// --- 新增:暗黑模式开关插件 ---
|
|
function(hook, vm) {
|
|
hook.doneEach(function() {
|
|
const sidebar = document.querySelector('.sidebar-nav');
|
|
// 防止重复添加
|
|
if (!sidebar || document.querySelector('.sidebar-toggle-btn')) return;
|
|
|
|
const btn = document.createElement('div');
|
|
btn.className = 'sidebar-toggle-btn';
|
|
|
|
// 初始化状态
|
|
const savedTheme = localStorage.getItem('theme-mode');
|
|
if (savedTheme === 'dark') {
|
|
document.body.classList.add('dark-mode');
|
|
btn.textContent = '🌙 Switch to Light';
|
|
} else {
|
|
btn.textContent = '☀️ Switch to Dark';
|
|
}
|
|
|
|
// 点击事件
|
|
btn.onclick = function() {
|
|
document.body.classList.toggle('dark-mode');
|
|
const isDark = document.body.classList.contains('dark-mode');
|
|
localStorage.setItem('theme-mode', isDark ? 'dark' : 'light');
|
|
btn.textContent = isDark ? '🌙 Switch to Light' : '☀️ Switch to Dark';
|
|
};
|
|
|
|
// 插入到侧边栏最顶部
|
|
sidebar.insertBefore(btn, sidebar.firstChild);
|
|
});
|
|
},
|
|
|
|
// --- 原有插件:脚注处理 ---
|
|
function(hook, vm) {
|
|
hook.beforeEach(function (html) {
|
|
html = html.replace(/\[\^([^\]]+)\](?!:)/g, '<sup class="footnote-ref"><a href="#fn-$1" data-footnote-ref="$1" id="fnref-$1">$1</a></sup>');
|
|
return html;
|
|
});
|
|
|
|
hook.afterEach(function (html, next) {
|
|
try {
|
|
html = html.replace(/<p>\s*\[\^([^\]]+)\]:\s*([\s\S]*?)<\/p>/g, function(_, id, content) {
|
|
return '<div class="footnote" id="fn-' + id + '"><p>' + content + ' <a href="#fnref-' + id + '">↩</a></p></div>';
|
|
});
|
|
} catch (e) { /* 忽略 */ }
|
|
next(html);
|
|
});
|
|
|
|
hook.doneEach(function () {
|
|
try {
|
|
var prev = window.__footnoteContainer;
|
|
var prevHandler = window.__footnoteHandler;
|
|
if (prev && prevHandler) {
|
|
prev.removeEventListener('click', prevHandler, true);
|
|
}
|
|
|
|
var container = document.querySelector('.markdown-section');
|
|
if (!container) return;
|
|
|
|
var handler = function (e) {
|
|
var a = e.target && e.target.closest ? e.target.closest('a') : null;
|
|
if (!a) return;
|
|
var href = a.getAttribute('href') || '';
|
|
if (!/^#(fn-|fnref-)/.test(href)) return;
|
|
var targetId = href.slice(1);
|
|
var el = document.getElementById(targetId);
|
|
if (!el) return;
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
try { el.scrollIntoView({ behavior: 'smooth', block: 'start' }); }
|
|
catch (_) { el.scrollIntoView(true); }
|
|
};
|
|
|
|
container.addEventListener('click', handler, true);
|
|
window.__footnoteContainer = container;
|
|
window.__footnoteHandler = handler;
|
|
} catch (e) {}
|
|
});
|
|
},
|
|
// --- 原有插件:语言切换插件 ---
|
|
function(hook, vm) {
|
|
hook.mounted(function() {
|
|
var nav = document.querySelector('.app-nav');
|
|
if (!nav) {
|
|
nav = document.createElement('nav');
|
|
nav.className = 'app-nav';
|
|
document.querySelector('main').appendChild(nav);
|
|
}
|
|
|
|
var langSwitcher = document.createElement('ul');
|
|
langSwitcher.innerHTML = `
|
|
<li>
|
|
<select id="lang-selector">
|
|
<option value="">中文</option>
|
|
<option value="en">English</option>
|
|
</select>
|
|
</li>
|
|
`;
|
|
nav.appendChild(langSwitcher);
|
|
|
|
var selector = document.getElementById('lang-selector');
|
|
selector.addEventListener('change', function(e) {
|
|
var lang = e.target.value;
|
|
var currentPath = location.hash.replace('#/', '');
|
|
|
|
if (lang === '') {
|
|
if (currentPath.startsWith('en/')) {
|
|
location.hash = '#/' + currentPath.replace('en/', '');
|
|
} else {
|
|
location.hash = '#/';
|
|
}
|
|
} else {
|
|
if (currentPath === '' || currentPath === '/') {
|
|
location.hash = '#/en/';
|
|
} else if (currentPath.startsWith('en/')) {
|
|
return;
|
|
} else {
|
|
location.hash = '#/en/' + currentPath;
|
|
}
|
|
}
|
|
});
|
|
|
|
function updateSelector() {
|
|
var currentPath = location.hash.replace('#/', '');
|
|
if (currentPath.startsWith('en/')) {
|
|
selector.value = 'en';
|
|
} else {
|
|
selector.value = '';
|
|
}
|
|
}
|
|
|
|
updateSelector();
|
|
window.addEventListener('hashchange', updateSelector);
|
|
});
|
|
},
|
|
// --- 原有插件:图片相对路径修复 ---
|
|
function(hook, vm) {
|
|
function getRouteDir() {
|
|
var hash = decodeURIComponent(window.location.hash || '');
|
|
if (!hash || hash === '#/' || hash === '#') return '';
|
|
var path = hash.replace(/^#\//, '').replace(/(\?.*|#.*)/g, '');
|
|
if (path && !path.endsWith('/')) {
|
|
path = path.replace(/[^\/]*$/, '');
|
|
}
|
|
return path;
|
|
}
|
|
|
|
hook.doneEach(function() {
|
|
try {
|
|
var routeDir = getRouteDir();
|
|
var base = window.location.origin + window.location.pathname + routeDir;
|
|
var selector = '.markdown-section img:not([data-origin])';
|
|
var imgs = document.querySelectorAll(selector);
|
|
imgs.forEach(function(img) {
|
|
var src = img.getAttribute('src');
|
|
if (!src) return;
|
|
if (/^(https?:)?\/\//i.test(src) || src.startsWith('/')) return;
|
|
try {
|
|
var abs = new URL(src, base).pathname;
|
|
img.setAttribute('src', abs);
|
|
} catch (e) {}
|
|
});
|
|
} catch (e) {}
|
|
});
|
|
}
|
|
]
|
|
}
|
|
</script>
|
|
<!-- Put them above docsify.min.js -->
|
|
<script src="//cdn.jsdelivr.net/npm/docsify@latest/lib/docsify.min.js"></script>
|
|
<!-- 搜索功能 -->
|
|
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
|
|
<!-- 新增:图片放大插件 (官方插件,稳定支持动态路由) -->
|
|
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script>
|
|
|
|
<!-- code render-->
|
|
<script src="//cdn.jsdelivr.net/npm/prismjs@latest/components/prism-bash.js"></script>
|
|
<script src="//cdn.jsdelivr.net/npm/prismjs@latest/components/prism-python.js"></script>
|
|
<script src="//cdn.jsdelivr.net/npm/docsify-pagination@latest/dist/docsify-pagination.min.js"></script>
|
|
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code"></script>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.js"></script>
|
|
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.css" />
|
|
<script src="https://cdn.jsdelivr.net/npm/marked@3"></script>
|
|
<!-- CDN files for docsify-katex -->
|
|
<script src="//cdn.jsdelivr.net/npm/docsify-katex@latest/dist/docsify-katex.js"></script>
|
|
<!-- 字数统计 -->
|
|
<script src="//unpkg.com/docsify-count/dist/countable.js"></script>
|
|
<!-- Mermaid -->
|
|
<script src="//cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
|
|
<script src="//unpkg.com/docsify-mermaid@latest/dist/docsify-mermaid.js"></script>
|
|
<script>mermaid.initialize({ startOnLoad: true });</script>
|
|
|
|
</body>
|
|
|
|
</html>
|