Compare commits

..

2 Commits

Author SHA1 Message Date
c5949bcf69 合并 2026-04-27 16:44:38 +08:00
29e286a2a0 首次提交 2026-04-26 01:56:44 +08:00
3 changed files with 631 additions and 0 deletions

304
build.js Normal file
View File

@ -0,0 +1,304 @@
const fs = require('fs');
const path = require('path');
const { marked } = require('marked');
// ─── Config ────────────────────────────────────────────────
const LOG_DIR = path.join(__dirname, 'llm_log');
const OUTPUT_FILE = path.join(__dirname, 'index.html');
// ─── Marked Config ─────────────────────────────────────────
const headingIds = new Map();
const renderer = new marked.Renderer();
renderer.code = function (code, lang) {
const validLang = lang || 'text';
const highlighted = highlightCode(code, validLang);
const id = 'highlight-' + Math.random().toString(36).slice(2, 8);
return `<pre class="relative group"><button class="copy-btn absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity px-2 py-1 text-xs bg-gray-600 hover:bg-gray-500 rounded" onclick="copyCode(this)">Copy</button><code id="${id}" class="hljs language-${validLang} block overflow-auto max-h-64 p-4 rounded-lg bg-gray-900 text-gray-100 text-sm leading-relaxed">${highlighted}</code></pre>`;
};
renderer.codespan = function (code) {
return `<code class="px-1.5 py-0.5 text-sm font-mono bg-blue-50 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 rounded border border-blue-200 dark:border-blue-700">${code}</code>`;
};
renderer.tablerow = function (content) {
return `<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors">${content}</tr>\n`;
};
renderer.tablecell = function (content, flags) {
const type = flags.header ? 'th' : 'td';
const cls = flags.header
? 'px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700'
: 'px-4 py-3 border border-gray-200 dark:border-gray-700';
const tag = flags.align
? `<${type} class="${cls}" align="${flags.align}">`
: `<${type} class="${cls}">`;
return tag + content + `</${type}>\n`;
};
renderer.table = function (header, body) {
if (body) body = `<tbody>${body}</tbody>`;
return `<div class="overflow-x-auto my-6 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm"><table class="w-full text-sm"><thead>${header}</thead>${body}</table></div>\n`;
};
marked.setOptions({ renderer, gfm: true });
function highlightCode(code, lang) {
const escaped = escapeHtml(code.trim());
if (!lang) return escaped;
try {
const hl = require('highlight.js');
const result = hl.getLanguage(lang) ? hl.highlight(code.trim(), { language: lang }) : hl.highlightAuto(code.trim());
return result.value;
} catch {
return escaped;
}
}
function escapeHtml(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
}
// ─── Read Log Files ────────────────────────────────────────
function readLogFile(filePath) {
const content = fs.readFileSync(filePath, 'utf-8');
return content
.split(/\r?\n/)
.map(line => line.trim())
.filter(line => line.length > 0);
}
// ─── Inject Heading IDs into Markdown ──────────────────────
function injectHeadingIds(markdown, prefix) {
const toc = [];
const lines = markdown.split('\n');
const headingRegex = /^(#{1,6})\s+(.+)$/;
let headingIndex = 0;
for (let i = 0; i < lines.length; i++) {
const match = lines[i].match(headingRegex);
if (match) {
const level = match[1].length;
const text = match[2].trim().replace(/[#!*_~]/g, '');
const headingId = `${prefix}-h${headingIndex++}`;
lines[i] = lines[i] + ` {#${headingId}}`;
toc.push({ level, text, id: headingId });
}
}
return { markdown: lines.join('\n'), toc };
}
// ─── Build Pages ───────────────────────────────────────────
async function build() {
const logFile = path.join(LOG_DIR, 'log.txt');
const logDir = LOG_DIR;
let mdFiles = [];
// Try reading log.txt first
if (fs.existsSync(logFile)) {
const entries = readLogFile(logFile);
mdFiles = entries
.filter(entry => entry.endsWith('.md'))
.map(entry => path.resolve(path.dirname(logFile), '..', entry));
}
// Fallback: scan llm_log directory for .md files
if (mdFiles.length === 0 && fs.existsSync(logDir) && fs.statSync(logDir).isDirectory()) {
mdFiles = fs.readdirSync(logDir)
.filter(f => f.endsWith('.md'))
.map(f => path.join(logDir, f))
.sort();
}
if (mdFiles.length === 0) {
console.error('No .md files found in llm_log/ or llm_log/log.txt');
process.exit(1);
}
console.log(`Found ${mdFiles.length} markdown file(s)`);
const pages = [];
for (const filePath of mdFiles) {
try {
const raw = fs.readFileSync(filePath, 'utf-8');
if (!raw.trim()) continue;
const prefix = path.basename(filePath, '.md');
const { markdown, toc } = injectHeadingIds(raw, prefix);
const html = marked.parse(markdown);
pages.push({
title: prefix,
html,
toc,
filePath
});
} catch (err) {
console.warn(`Failed to process ${filePath}: ${err.message}`);
}
}
if (pages.length === 0) {
console.error('No valid markdown content found.');
process.exit(1);
}
// ─── Generate HTML ───────────────────────────────────────
const tocLinks = pages.map((p, i) => `
<li>
<a href="#page-${i}" class="toc-link block px-3 py-2 text-sm rounded-md transition-colors hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white font-medium" data-target="${i}">
${escapeHtml(p.title)}
${p.toc.length > 0 ? `<span class="float-right text-xs text-gray-400">${p.toc.length}</span>` : ''}
</a>
${p.toc.length > 0 ? `<ul class="ml-4 mt-1 space-y-0.5 border-l border-gray-200 dark:border-gray-700 pl-2">${p.toc.map(t => {
const indent = t.level >= 4 ? 'ml-8' : 'ml-4';
return `<li class="${indent}"><a href="#${t.id}" class="toc-sublink block py-1 text-xs text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 transition-colors" data-target="${i}">${escapeHtml(t.text)}</a></li>`;
}).join('')}</ul>` : ''}
</li>`).join('');
const pageBlocks = pages.map((p, i) => `
<section id="page-${i}" class="page-section mb-20 scroll-mt-24">
<div class="mb-8 pb-4 border-b border-gray-200 dark:border-gray-700">
<h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-2">${escapeHtml(p.title)}</h1>
<p class="text-sm text-gray-500 dark:text-gray-400">${path.basename(p.filePath)}</p>
</div>
<div class="prose prose-gray dark:prose-invert max-w-none prose-headings:font-bold prose-headings:text-gray-900 dark:prose-headings:text-white prose-p:text-gray-700 dark:prose-p:text-gray-300 prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-strong:text-gray-900 dark:prose-strong:text-white prose-code:text-sm prose-pre:rounded-lg prose-pre:bg-gray-900 prose-img:rounded-lg prose-table:border-collapse prose-table:border prose-table:border-gray-200 dark:prose-table:border-gray-700 prose-th:bg-gray-50 dark:prose-th:bg-gray-800 prose-th:border prose-th:border-gray-200 dark:prose-th:border-gray-700 prose-td:border prose-td:border-gray-200 dark:prose-td:border-gray-700 prose-li:marker:text-gray-500">${p.html}</div>
</section>`).join('');
const html = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LLM Log Viewer</title>
<script src="https://cdn.tailwindcss.com"><\/script>
<script>
tailwind.config = {
darkMode: 'class',
theme: { extend: { fontFamily: { sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'] } } }
}
<\/script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css" id="hljs-light">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css" id="hljs-dark" disabled>
<style>
* { scrollbar-width: thin; scrollbar-color: #cbd5e1 transparent; }
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
.dark *::-webkit-scrollbar-thumb { background: #475569; }
.toc-link.active, .toc-sublink.active { background: #eff6ff; color: #2563eb; }
.dark .toc-link.active, .dark .toc-sublink.active { background: #1e3a5f; color: #60a5fa; }
.page-section { animation: fadeIn 0.3s ease-in-out; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 768px) { .sidebar { display: none !important; } .main-content { margin-left: 0 !important; padding-left: 1rem !important; padding-right: 1rem !important; } .mobile-toggle { display: flex !important; } }
</style>
</head>
<body class="bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100 font-sans antialiased transition-colors">
<div class="flex min-h-screen">
<!-- Sidebar -->
<aside class="sidebar fixed left-0 top-0 h-screen w-64 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-800 overflow-y-auto z-40 transition-transform">
<div class="p-5 border-b border-gray-200 dark:border-gray-800">
<h2 class="text-lg font-bold text-gray-900 dark:text-white flex items-center gap-2">
<svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
LLM Logs
</h2>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">${pages.length} file(s)</p>
</div>
<nav class="p-3">
<ul class="space-y-0.5">${tocLinks}</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="main-content flex-1 ml-64 min-w-0">
<header class="sticky top-0 z-30 bg-white/80 dark:bg-gray-950/80 backdrop-blur-md border-b border-gray-200 dark:border-gray-800">
<div class="flex items-center justify-between px-6 py-3">
<button id="menuBtn" class="mobile-toggle hidden items-center p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
<div class="flex items-center gap-3 ml-auto">
<button id="themeToggle" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" title="Toggle theme">
<svg id="sunIcon" class="w-5 h-5 hidden dark:block" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg>
<svg id="moonIcon" class="w-5 h-5 block dark:hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg>
</button>
</div>
</div>
</header>
<div class="max-w-4xl mx-auto px-6 py-10">
${pageBlocks}
</div>
</main>
</div>
<!-- Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"><\/script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/bash.min.js"><\/script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js"><\/script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/typescript.min.js"><\/script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/python.min.js"><\/script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/json.min.js"><\/script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/css.min.js"><\/script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/xml.min.js"><\/script>
<script>
// Init highlight.js
hljs.highlightAll();
// Theme toggle
const html = document.documentElement;
const themeBtn = document.getElementById('themeToggle');
const saved = localStorage.getItem('theme');
if (saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches)) html.classList.add('dark');
themeBtn.addEventListener('click', () => {
html.classList.toggle('dark');
localStorage.setItem('theme', html.classList.contains('dark') ? 'dark' : 'light');
document.getElementById('hljs-light').disabled = html.classList.contains('dark');
document.getElementById('hljs-dark').disabled = !html.classList.contains('dark');
});
// Sidebar toggle (mobile)
document.getElementById('menuBtn').addEventListener('click', () => {
document.querySelector('.sidebar').classList.toggle('-translate-x-full');
});
// Active TOC tracking
const sections = document.querySelectorAll('.page-section');
const tocLinks = document.querySelectorAll('.toc-link, .toc-sublink');
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const idx = entry.target.id.replace('page-', '');
tocLinks.forEach(l => l.classList.toggle('active', l.dataset.target === idx));
}
});
}, { rootMargin: '-80px 0px -70% 0px', threshold: 0 });
sections.forEach(s => observer.observe(s));
// Smooth scroll for TOC links
tocLinks.forEach(link => {
link.addEventListener('click', e => {
e.preventDefault();
const targetId = link.href.split('#').pop();
document.getElementById(targetId)?.scrollIntoView({ behavior: 'smooth' });
// Close mobile sidebar
if (window.innerWidth < 768) document.querySelector('.sidebar').classList.add('-translate-x-full');
});
});
// Copy code button
window.copyCode = function(btn) {
const code = btn.nextElementSibling;
navigator.clipboard.writeText(code.textContent).then(() => {
btn.textContent = 'Copied!';
setTimeout(() => btn.textContent = 'Copy', 2000);
});
};
</script>
</body>
</html>`;
fs.writeFileSync(OUTPUT_FILE, html, 'utf-8');
console.log(`\nBuild complete: ${OUTPUT_FILE}`);
console.log(` - ${pages.length} page(s) rendered`);
}
build().catch(err => { console.error(err); process.exit(1); });

301
index.html Normal file
View File

@ -0,0 +1,301 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LLM Log Viewer</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: { extend: { fontFamily: { sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'] } } }
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css" id="hljs-light">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css" id="hljs-dark" disabled>
<style>
* { scrollbar-width: thin; scrollbar-color: #cbd5e1 transparent; }
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 3px; }
.dark *::-webkit-scrollbar-thumb { background: #475569; }
.toc-link.active, .toc-sublink.active { background: #eff6ff; color: #2563eb; }
.dark .toc-link.active, .dark .toc-sublink.active { background: #1e3a5f; color: #60a5fa; }
.page-section { animation: fadeIn 0.3s ease-in-out; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@media (max-width: 768px) { .sidebar { display: none !important; } .main-content { margin-left: 0 !important; padding-left: 1rem !important; padding-right: 1rem !important; } .mobile-toggle { display: flex !important; } }
</style>
</head>
<body class="bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100 font-sans antialiased transition-colors">
<div class="flex min-h-screen">
<!-- Sidebar -->
<aside class="sidebar fixed left-0 top-0 h-screen w-64 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-800 overflow-y-auto z-40 transition-transform">
<div class="p-5 border-b border-gray-200 dark:border-gray-800">
<h2 class="text-lg font-bold text-gray-900 dark:text-white flex items-center gap-2">
<svg class="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
LLM Logs
</h2>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">1 file(s)</p>
</div>
<nav class="p-3">
<ul class="space-y-0.5">
<li>
<a href="#page-0" class="toc-link block px-3 py-2 text-sm rounded-md transition-colors hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white font-medium" data-target="0">
2026-04-26
</a>
</li></ul>
</nav>
</aside>
<!-- Main Content -->
<main class="main-content flex-1 ml-64 min-w-0">
<header class="sticky top-0 z-30 bg-white/80 dark:bg-gray-950/80 backdrop-blur-md border-b border-gray-200 dark:border-gray-800">
<div class="flex items-center justify-between px-6 py-3">
<button id="menuBtn" class="mobile-toggle hidden items-center p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
<div class="flex items-center gap-3 ml-auto">
<button id="themeToggle" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors" title="Toggle theme">
<svg id="sunIcon" class="w-5 h-5 hidden dark:block" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg>
<svg id="moonIcon" class="w-5 h-5 block dark:hidden" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg>
</button>
</div>
</div>
</header>
<div class="max-w-4xl mx-auto px-6 py-10">
<section id="page-0" class="page-section mb-20 scroll-mt-24">
<div class="mb-8 pb-4 border-b border-gray-200 dark:border-gray-700">
<h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-2">2026-04-26</h1>
<p class="text-sm text-gray-500 dark:text-gray-400">2026-04-26.md</p>
</div>
<div class="prose prose-gray dark:prose-invert max-w-none prose-headings:font-bold prose-headings:text-gray-900 dark:prose-headings:text-white prose-p:text-gray-700 dark:prose-p:text-gray-300 prose-a:text-blue-600 dark:prose-a:text-blue-400 prose-strong:text-gray-900 dark:prose-strong:text-white prose-code:text-sm prose-pre:rounded-lg prose-pre:bg-gray-900 prose-img:rounded-lg prose-table:border-collapse prose-table:border prose-table:border-gray-200 dark:prose-table:border-gray-700 prose-th:bg-gray-50 dark:prose-th:bg-gray-800 prose-th:border prose-th:border-gray-200 dark:prose-th:border-gray-700 prose-td:border prose-td:border-gray-200 dark:prose-td:border-gray-700 prose-li:marker:text-gray-500"><div class="overflow-x-auto my-6 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm"><table class="w-full text-sm"><thead><tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">小时</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">平均输入t/s</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">平均输出t/s</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">输入token总数</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">输出token总数</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">token总数</th>
</tr>
</thead><tbody><tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">00</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">216.04</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">26.08</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">115,105</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">5,701</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">120,806</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">08</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">300.02</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">34.15</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">96,329</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">16,921</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">113,250</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">09</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">190.30</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">28.20</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">19,066</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1,389</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">20,455</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">10</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">58.32</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">24.36</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">538</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">2,076</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">2,614</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">12</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">166.90</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">18.84</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">45,509</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">8,311</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">53,820</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">13</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">52.57</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">28.39</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">39</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1,438</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1,477</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">15</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">245.35</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">17.57</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">54,168</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">3,735</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">57,903</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">16</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">259.63</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">27.41</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">69,957</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">7,702</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">77,659</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">17</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">304.44</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">25.81</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">44,088</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1,764</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">45,852</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">18</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">233.83</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">27.90</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">206,821</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">17,378</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">224,199</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">20</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">374.10</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">25.27</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">30,747</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">3,918</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">34,665</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">21</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">237.74</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">31.39</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1,516</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">5,912</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">7,428</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">23</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">283.86</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">25.43</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">39,894</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1,999</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">41,893</td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>全天</strong></td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>233.31</strong></td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>26.56</strong></td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>723,777</strong></td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>78,244</strong></td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>802,021</strong></td>
</tr>
</tbody></table></div>
<div class="overflow-x-auto my-6 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm"><table class="w-full text-sm"><thead><tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="left">厂商</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="left">模型</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">输入费用 (元)</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">输出费用 (元)</th>
<th class="px-4 py-3 text-left font-semibold bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700" align="center">总费用 (元)</th>
</tr>
</thead><tbody><tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">🚀 DeepSeek</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">DeepSeek-V4-Flash</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">0.72</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">0.16</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>0.88</strong></td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">🚀 DeepSeek</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">DeepSeek-V4-Pro</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">8.69</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1.88</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>10.57</strong></td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">☁️ 千问 (Qwen)</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">Qwen3.6-Plus</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1.45</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">0.94</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>2.39</strong></td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">🌐 MiniMax</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">MiniMax-M2.7</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1.52</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">0.66</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>2.18</strong></td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">🌐 MiniMax</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">MiniMax-M2.7-highspeed</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">3.04</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1.31</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>4.35</strong></td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">🤖 智谱 (GLM)</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">GLM-5.1</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">4.34</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1.88</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>6.22</strong></td>
</tr>
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors"><td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">🏠 小米 (MiMo)</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="left">MiMo-V2-Pro (256K 档)</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">2.03</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center">1.10</td>
<td class="px-4 py-3 border border-gray-200 dark:border-gray-700" align="center"><strong>3.13</strong></td>
</tr>
</tbody></table></div>
</div>
</section>
</div>
</main>
</div>
<!-- Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/bash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/typescript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/python.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/json.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/css.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/xml.min.js"></script>
<script>
// Init highlight.js
hljs.highlightAll();
// Theme toggle
const html = document.documentElement;
const themeBtn = document.getElementById('themeToggle');
const saved = localStorage.getItem('theme');
if (saved === 'dark' || (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches)) html.classList.add('dark');
themeBtn.addEventListener('click', () => {
html.classList.toggle('dark');
localStorage.setItem('theme', html.classList.contains('dark') ? 'dark' : 'light');
document.getElementById('hljs-light').disabled = html.classList.contains('dark');
document.getElementById('hljs-dark').disabled = !html.classList.contains('dark');
});
// Sidebar toggle (mobile)
document.getElementById('menuBtn').addEventListener('click', () => {
document.querySelector('.sidebar').classList.toggle('-translate-x-full');
});
// Active TOC tracking
const sections = document.querySelectorAll('.page-section');
const tocLinks = document.querySelectorAll('.toc-link, .toc-sublink');
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const idx = entry.target.id.replace('page-', '');
tocLinks.forEach(l => l.classList.toggle('active', l.dataset.target === idx));
}
});
}, { rootMargin: '-80px 0px -70% 0px', threshold: 0 });
sections.forEach(s => observer.observe(s));
// Smooth scroll for TOC links
tocLinks.forEach(link => {
link.addEventListener('click', e => {
e.preventDefault();
const targetId = link.href.split('#').pop();
document.getElementById(targetId)?.scrollIntoView({ behavior: 'smooth' });
// Close mobile sidebar
if (window.innerWidth < 768) document.querySelector('.sidebar').classList.add('-translate-x-full');
});
});
// Copy code button
window.copyCode = function(btn) {
const code = btn.nextElementSibling;
navigator.clipboard.writeText(code.textContent).then(() => {
btn.textContent = 'Copied!';
setTimeout(() => btn.textContent = 'Copy', 2000);
});
};
</script>
</body>
</html>

26
llm_log/2026-04-26.md Normal file
View File

@ -0,0 +1,26 @@
| 小时 | 平均输入t/s | 平均输出t/s | 输入token总数 | 输出token总数 | token总数 |
| :---: | :---: | :---: | :---: | :---: | :---: |
| 00 | 216.04 | 26.08 | 115,105 | 5,701 | 120,806 |
| 08 | 300.02 | 34.15 | 96,329 | 16,921 | 113,250 |
| 09 | 190.30 | 28.20 | 19,066 | 1,389 | 20,455 |
| 10 | 58.32 | 24.36 | 538 | 2,076 | 2,614 |
| 12 | 166.90 | 18.84 | 45,509 | 8,311 | 53,820 |
| 13 | 52.57 | 28.39 | 39 | 1,438 | 1,477 |
| 15 | 245.35 | 17.57 | 54,168 | 3,735 | 57,903 |
| 16 | 259.63 | 27.41 | 69,957 | 7,702 | 77,659 |
| 17 | 304.44 | 25.81 | 44,088 | 1,764 | 45,852 |
| 18 | 233.83 | 27.90 | 206,821 | 17,378 | 224,199 |
| 20 | 374.10 | 25.27 | 30,747 | 3,918 | 34,665 |
| 21 | 237.74 | 31.39 | 1,516 | 5,912 | 7,428 |
| 23 | 283.86 | 25.43 | 39,894 | 1,999 | 41,893 |
| **全天** | **233.31** | **26.56** | **723,777** | **78,244** | **802,021** |
| 厂商 | 模型 | 输入费用 (元) | 输出费用 (元) | 总费用 (元) |
| :--- | :--- | :---: | :---: | :---: |
| 🚀 DeepSeek | DeepSeek-V4-Flash | 0.72 | 0.16 | **0.88** |
| 🚀 DeepSeek | DeepSeek-V4-Pro | 8.69 | 1.88 | **10.57** |
| ☁️ 千问 (Qwen) | Qwen3.6-Plus | 1.45 | 0.94 | **2.39** |
| 🌐 MiniMax | MiniMax-M2.7 | 1.52 | 0.66 | **2.18** |
| 🌐 MiniMax | MiniMax-M2.7-highspeed | 3.04 | 1.31 | **4.35** |
| 🤖 智谱 (GLM) | GLM-5.1 | 4.34 | 1.88 | **6.22** |
| 🏠 小米 (MiMo) | MiMo-V2-Pro (256K 档) | 2.03 | 1.10 | **3.13** |