上周团队直播讨论Claude Skill时,我突然想到:GitHub上有大量Agent/Claude Skill相关的仓库,但缺乏一个集中展示和搜索的平台。于是,agentskill.work这个项目诞生了——从构思到上线仅用了半天时间。这个速度背后,不是简单的代码堆砌,而是一系列深思熟虑的技术决策。

技术栈选择上,我采用了Next.js + FastAPI的组合。这不是随意的决定:
提示:现代全栈项目选型时,建议优先考虑框架的"开发体验"和"问题解决成本",而不仅仅是技术新颖度。
整个开发过程中,AI工具承担了大部分编码工作:
但关键在于,我始终把控着几个核心方向:
直接从前端调用GitHub API是灾难的开始。我设计了多层防护:
python复制# 限流中间件示例
from fastapi import Request, HTTPException
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@app.get("/api/repos")
@limiter.limit("10/minute")
async def get_repos(request: Request):
# 先从缓存读取
cached_data = cache.get("github_repos")
if cached_data:
return cached_data
# 缓存未命中才请求GitHub API
try:
data = await fetch_github_repos()
cache.set("github_repos", data, timeout=3600) # 缓存1小时
return data
except Exception as e:
# 降级返回最近一次成功数据
last_success = cache.get("last_success_data")
if last_success:
return last_success
raise HTTPException(status_code=503, detail="Service unavailable")
这个方案解决了几个关键问题:
很多新手会直接用setTimeout或cron,我选择了Celery方案:
python复制# celery_config.py
from celery import Celery
from celery.schedules import crontab
app = Celery('tasks', broker='redis://localhost:6379/0')
app.conf.beat_schedule = {
'fetch-github-every-hour': {
'task': 'tasks.fetch_github_repos',
'schedule': crontab(minute=0), # 每小时执行
'options': {
'expires': 3600, # 任务过期时间
'retry': True, # 启用重试
'retry_policy': {
'max_retries': 3,
'interval_start': 10,
'interval_step': 10,
'interval_max': 30,
}
}
},
}
选择Celery的核心考量:
AI最初推荐了Caddy,但我坚持使用Nginx,原因很实际:
| 对比维度 | Nginx | Caddy |
|---|---|---|
| 生产环境验证 | 15年+ | 相对较新 |
| 配置灵活性 | 极高 | 较高 |
| 性能调优 | 文档丰富 | 文档较少 |
| 问题排查 | 社区资源多 | 相对较少 |
| 模块生态 | 极其丰富 | 正在发展 |
在线上环境,当半夜出现502错误时,Nginx的排查经验和工具链会让你感激当初的选择。
HTTPS不是简单加个证书就完事。我的方案:
bash复制# docker-compose片段示例
services:
web:
image: nginx
volumes:
- ./certs:/etc/nginx/certs
environment:
- VIRTUAL_HOST=agentskill.work
- LETSENCRYPT_HOST=agentskill.work
- LETSENCRYPT_EMAIL=your@email.com
这个配置确保了:
上线第一天就集成Umami,这是很多项目容易忽视的。我的配置:
javascript复制// _app.js
import { useEffect } from 'react'
import Script from 'next/script'
export default function App({ Component, pageProps }) {
useEffect(() => {
window.umami = function(...args) {
if (window._umami) window._umami(...args)
else console.log('[Umami]', ...args) // 开发环境降级
}
}, [])
return (
<>
<Script
src="/umami.js"
data-website-id="YOUR_WEBSITE_ID"
strategy="afterInteractive"
/>
)
}
这样做的价值:
新手常犯的错误是只关注功能实现,而忽略系统生存能力。我的检查清单:
当AI能写大部分代码时,程序员的竞争力在于:
这些能力不是靠看文档就能获得的,需要实际踩过坑、背过锅。
yaml复制version: '3.8'
services:
web:
build: ./web
ports:
- "3000:3000"
depends_on:
- api
environment:
- NEXT_PUBLIC_API_URL=http://api:8000
api:
build: ./api
ports:
- "8000:8000"
depends_on:
- redis
- celery
environment:
- REDIS_URL=redis://redis:6379/0
celery:
build: ./api
command: celery -A main.celery worker --loglevel=info
depends_on:
- redis
environment:
- REDIS_URL=redis://redis:6379/0
celery-beat:
build: ./api
command: celery -A main.celery beat --loglevel=info
depends_on:
- redis
environment:
- REDIS_URL=redis://redis:6379/0
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./certs:/etc/nginx/certs
depends_on:
- web
- api
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- "3001:3000"
environment:
- DATABASE_URL=postgresql://umami:umami@db:5432/umami
depends_on:
- db
db:
image: postgres:alpine
environment:
- POSTGRES_DB=umami
- POSTGRES_USER=umami
- POSTGRES_PASSWORD=umami
volumes:
- umami_db:/var/lib/postgresql/data
volumes:
redis_data:
umami_db:
nginx复制http {
upstream web {
server web:3000;
}
upstream api {
server api:8000;
}
server {
listen 80;
server_name agentskill.work;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name agentskill.work;
ssl_certificate /etc/nginx/certs/live/agentskill.work/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/agentskill.work/privkey.pem;
location / {
proxy_pass http://web;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/ {
proxy_pass http://api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
}
GitHub API限流
curl -i https://api.github.com/rate_limitCelery任务堆积
celery -A proj inspect reserved证书续期失败
openssl x509 -enddate -noout -in cert.pemNext.js优化
next/image自动优化图片FastAPI优化
Redis缓存策略
SETEX key ttl value + 随机过期时间基础监控
docker stats观察容器资源使用业务监控
日志收集
这个项目的快速上线验证了一个观点:在AI时代,资深工程师的价值不在于写更多代码,而在于做出更明智的技术决策。当代码变得越来越容易生成时,对系统全局的把控能力和工程实践经验反而变得更加珍贵。