Files
metapi/docs/index.md
T

7.3 KiB
Raw Blame History

layout, hero, features
layout hero features
home
name text tagline image actions
Metapi 文档中心 中转站的中转站 将分散的 AI 中转站聚合为一个统一网关
src alt
/logos/logo-full.png Metapi
theme text link
brand 10 分钟快速上手 /getting-started
theme text link
alt 常见问题 FAQ /faq
theme text link
alt 贡献教程/FAQ /community/faq-tutorial-guidelines
title details link
快速上手 从部署到第一条请求,按步骤完成最小可用环境搭建。 /getting-started
title details link
问题排查 汇总高频报错、根因定位和标准修复路径,降低重复沟通成本。 /faq
title details link
运维与配置 覆盖部署、配置、监控、备份、升级回滚等生产场景。 /operations

项目架构

Metapi Federated AI Model Aggregation Gateway Architecture

项目界面预览

仪表盘
仪表盘
模型广场
模型广场
智能路由
智能路由
账号管理
账号管理
站点管理
站点管理
令牌管理
令牌管理
模型操练场
模型操练场
可用性监控
可用性监控
<style> .home-architecture { max-width: 800px; margin: 0 auto; } .home-architecture img { width: 100%; border-radius: 16px; border: 1px solid var(--vp-c-divider); box-shadow: 0 12px 28px rgba(2, 8, 20, 0.08); } .home-carousel { position: relative; width: 100%; margin: 0; overflow: hidden; border: 1px solid var(--vp-c-divider); border-radius: 16px; background: var(--vp-c-bg-soft); box-shadow: 0 10px 24px rgba(2, 8, 20, 0.06); } .home-carousel-track { display: flex; width: 100%; transform: translateX(0%); transition: transform 420ms ease; will-change: transform; } .home-carousel-slide { flex: 0 0 100%; margin: 0; } .home-carousel-slide img { display: block; width: 100%; height: auto; max-height: min(78vh, 980px); object-fit: contain; background: var(--vp-c-bg); } .home-carousel-slide figcaption { padding: 12px 14px; font-size: 22px; line-height: 1.2; font-weight: 600; color: var(--vp-c-text-1); } .home-carousel-nav { position: absolute; top: 0; bottom: 0; width: 14%; border: 0; background: transparent; color: #fff; z-index: 2; display: flex; align-items: center; opacity: 0; transition: opacity 0.2s ease; cursor: pointer; } .home-carousel-nav span { display: inline-flex; width: 40px; height: 40px; border-radius: 999px; align-items: center; justify-content: center; background: rgba(17, 24, 39, 0.56); font-size: 28px; line-height: 1; user-select: none; } .home-carousel:hover .home-carousel-nav { opacity: 1; } .home-carousel-prev { left: 0; justify-content: flex-start; padding-left: 12px; background: linear-gradient(90deg, rgba(15, 23, 42, 0.2), transparent); } .home-carousel-next { right: 0; justify-content: flex-end; padding-right: 12px; background: linear-gradient(270deg, rgba(15, 23, 42, 0.2), transparent); } @media (max-width: 640px) { .home-carousel-slide figcaption { font-size: 18px; padding: 10px 12px; } .home-carousel-nav { opacity: 1; width: 18%; } .home-carousel-nav span { width: 34px; height: 34px; font-size: 24px; } } </style> <script setup> import { onBeforeUnmount, onMounted } from 'vue'; let disposeCarousel = null; onMounted(() => { const root = document.querySelector('.home-carousel'); if (!root) return; const track = root.querySelector('.home-carousel-track'); const slides = root.querySelectorAll('.home-carousel-slide'); const prevBtn = root.querySelector('.home-carousel-prev'); const nextBtn = root.querySelector('.home-carousel-next'); if (!track || slides.length === 0) return; const total = slides.length; let index = 0; let timerId = null; const render = () => { track.style.transform = `translateX(-${index * 100}%)`; }; const goNext = () => { index = (index + 1) % total; render(); }; const goPrev = () => { index = (index - 1 + total) % total; render(); }; const stopAutoPlay = () => { if (timerId !== null) { window.clearInterval(timerId); timerId = null; } }; const startAutoPlay = () => { stopAutoPlay(); timerId = window.setInterval(goNext, 3000); }; const onMouseEnter = () => stopAutoPlay(); const onMouseLeave = () => startAutoPlay(); const onPrevClick = () => { goPrev(); startAutoPlay(); }; const onNextClick = () => { goNext(); startAutoPlay(); }; root.addEventListener('mouseenter', onMouseEnter); root.addEventListener('mouseleave', onMouseLeave); prevBtn?.addEventListener('click', onPrevClick); nextBtn?.addEventListener('click', onNextClick); render(); startAutoPlay(); disposeCarousel = () => { stopAutoPlay(); root.removeEventListener('mouseenter', onMouseEnter); root.removeEventListener('mouseleave', onMouseLeave); prevBtn?.removeEventListener('click', onPrevClick); nextBtn?.removeEventListener('click', onNextClick); }; }); onBeforeUnmount(() => { if (typeof disposeCarousel === 'function') { disposeCarousel(); } }); </script>

文档定位

  • 面向新用户:快速搭建和接入
  • 面向维护者:稳定运行、排障和升级
  • 面向贡献者:持续沉淀教程、FAQ 与最佳实践

推荐阅读路径

  1. 快速上手
  2. 部署指南
  3. 配置说明
  4. 客户端接入
  5. 常见问题 FAQ

协作维护

如需新增文档内容,请优先使用统一模板与提交流程:
FAQ/教程贡献规范