一键导入
researchit
ResearchIt — DIY Deep Research Engine. SearXNG + httpx/BS4 + deepseek-v4-flash + Typst. Investigación profunda asíncrona con entrega de PDF por WhatsApp.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
ResearchIt — DIY Deep Research Engine. SearXNG + httpx/BS4 + deepseek-v4-flash + Typst. Investigación profunda asíncrona con entrega de PDF por WhatsApp.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when generating scheduled reports from Reddit subreddits via Composio Reddit tools (REDDIT_GET_R_TOP, REDDIT_SEARCH_ACROSS_SUBREDDITS, REDDIT_RETRIEVE_POST_COMMENTS). Covers fetching posts, computing engagement, extracting top comments, and producing either a single-page PDF (fpdf2) or a text summary for group chat delivery.
Author in-repo SKILL.md: frontmatter, validator, structure, and writing-quality principles.
Manage the Hermes WebUI (nesquena/hermes-webui) deployment, configuration, and troubleshooting. Covers systemd service, settings.json, send_key behavior, Caddy reverse proxy, CI/CD integration via deploy.sh.
Systematically orient in a new project repository using Kairos governance, Hindsight memory banks, and documentary axis reading order. Covers REPOMAP, MASTER-SPEC, RULES, infrastructure exploration, and state verification.
Process, summarize, and extract information from YouTube videos. Covers metadata lookup, transcript extraction, and content analysis for wrestling analysis and general video research.
Workflow completo para mantener la Knowledge Base Personal (Narrativa Mitologica) de Martin. Cubre sesion de actualizacion, clasificacion KR2, propuesta KR1, ejecucion via Kilo CLI, compile y push.
| name | researchit |
| description | ResearchIt — DIY Deep Research Engine. SearXNG + httpx/BS4 + deepseek-v4-flash + Typst. Investigación profunda asíncrona con entrega de PDF por WhatsApp. |
| version | 1.2.0 |
| author | Hermes Agent / Toolset Personal |
| license | MIT |
| platforms | ["linux"] |
| metadata | {"hermes":{"tags":["research","deep-research","searxng","typst","pdf"],"related_skills":["kilo-code","markitdown-converter"]}} |
ResearchIt es un motor de investigación profunda auto-hospedado que reemplaza a Gemini Deep Research. Corre completamente en el VPS (ARM64, OL9), 100% gratuito, sin APIs de pago.
_md_to_typst()vault/ y lo envía por WhatsApp como attachment nativo.
MEDIA: tag debe estar en su PROPIA LÍNEA, SIN backticks, SIN markdown, SIN emojis decorativos en la misma línea. Ejemplo correcto:
MEDIA:/opt/researchit/vault/researchit_tema_20260706_123456.pdf
MEDIA:/opt/researchit/vault/...ls -la /opt/researchit/vault/*.pdf ANTES de referenciarlo en MEDIA/opt/researchit/vault/...)searxng en el docker-compose de toolset, kirlts/toolset/infrastructure/docker-compose.yml). Corre como --user root por compatibilidad ARM64/SELinux./opt/researchit/ (clonado desde kirlts/researchit)pip install -r requirements.txtHermes invoca ResearchIt como subproceso Python. La API key requiere set -a para exportarse correctamente:
set -a && source /home/opc/.hermes/.env && set +a && cd /opt/researchit && python3 -m src.research "tema" --max-sources 30
Parámetros clave:
--max-sources 30 (default, antes era 10): mínimo 30 fuentes para reportes robustos--no-pdf: solo Markdown, sin PDF--language en: búsqueda en inglésOutput:
vault/researchit_{topic}_{timestamp}.mdvault/researchit_{topic}_{timestamp}.pdfEl PDF se genera con Typst usando templates/report.typ. Configuración:
| Parámetro | Valor |
|---|---|
| Fuente | DejaVu Sans 11pt |
| Alineación | Justificado |
| Márgenes | 1.6cm laterales, 1.2cm verticales |
| Títulos H1 | 17pt bold, con pagebreak |
| Títulos H2 | 14pt bold |
| Títulos H3 | 12pt bold |
| Links | Azul #1a56db |
NO usar cmarker — no funciona en este entorno. La conversión MD→Typst es directa vía report._md_to_typst().
NO fallback raw — la compilación es una sola ruta limpia sin cmarker.
Si el PDF no se genera, revisar:
typst compile corre desde el directorio del output (cwd)templates/# Investigación básica
python -m src.research "impacto de la IA en la medicina 2026"
# Sin PDF (solo Markdown)
python -m src.research "tema" --no-pdf
# Control de fuentes
python -m src.research "tema" --max-sources 5 --language en
# Directorio custom
python -m src.research "tema" --output-dir /tmp/reports
| Módulo | Función |
|---|---|
src/search.py | Cliente SearXNG (localhost:4000, formato JSON) |
src/scrape.py | Scraping async con httpx+BS4 |
src/synthesize.py | Síntesis con deepseek-v4-flash vía OpenCode Go |
src/report.py | Generación PDF con Typst |
src/research.py | Orquestador principal (pipeline 7 etapas) |
--max-sources, default 30)docker restart researchit-searxngdocker logs researchit-searxng/tmp/researchit.lock (eliminar si una investigación se queda colgada)vault/| Problema | Causa | Solución |
|---|---|---|
| 401 en OpenCode Go | API key no exportada | Usar set -a && source .env && set +a |
| 0 resultados SearXNG | SearXNG caído | docker restart researchit-searxng |
| PDF no generado | Typst compilation error | Revisar template en templates/report.typ y fuentes disponibles (typst fonts). Ver references/typst-escaping-pitfalls.md para errores comunes como unclosed delimiter, label does not exist, unknown font family. |
.env con *** | El archivo .env tiene valores masked (***) que Python lee literalmente | NO usar .env con valores masked. Usar set -a && source /home/opc/.hermes/.env && set +a para heredar env vars de Hermes. El .env de researchit solo debe contener valores reales o no existir. |
| 401 en OpenCode Go | API key no exportada | Usar set -a && source .env && set +a |
| Reporte corto | Pocas fuentes con contenido útil | Aumentar --max-sources (default 30) o mejorar queries de SearXNG |
| Síntesis devuelve 0 caracteres | El LLM puede devolver vacío en el primer pase si las fuentes scrapeadas son de baja calidad | Es normal. El refine (segunda llamada LLM) expande automáticamente si <8000 chars. Verificar que el refine sí produjo contenido antes de reintentar. |
| MEDIA tag no entrega PDF en WhatsApp | MEDIA: fue escrita dentro de backticks o markdown (MEDIA:/path) en lugar de línea aparte sin formato | La línea MEDIA:/ruta/al/archivo.pdf debe estar SOLA, sin backticks, sin emojis, sin markdown alrededor. Solo así el bridge de WhatsApp la parsea como attachment. |
ResearchIt puede incluir hasta 15 resultados de Reddit como fuentes adicionales. Los resultados se obtienen vía Composio MCP (herramienta REDDIT_SEARCH_ACROSS_SUBREDDITS) y se pasan al pipeline como archivo JSON.
Flujo:
mcp_composio_COMPOSIO_MULTI_EXECUTE_TOOL con queries en inglés y españolvault/reddit_{topic}.json--reddit-file vault/reddit_{topic}.jsonEjemplo:
python -m src.research "tema" --max-sources 30 --reddit-file vault/reddit_tema.json
Los secrets de Composio (API key, connection_id) se manejan vía Infisical/env vars, NO hardcodeados.
ResearchIt puede ejecutarse como cron job semanal para entregar informes periódicos vía WhatsApp. El patrón típico:
researchit cargada y deliver: originvault/ls -t /opt/researchit/vault/*.pdf | head -1), verifica que existe, y lo entrega con MEDIA: en línea aparte (sin backticks, sin markdown alrededor de la línea MEDIA)Pitfall — múltiples PDFs generados en una ejecución: El agente del cron no debe asumir un solo PDF. Si el cron generó N reportes (e.g., dos temas diferentes en la misma ejecución programada), TODOS deben entregarse. NO hacer ls -t ... | head -1. En su lugar, encontrar todos los PDFs creados después del inicio de la ejecución actual, ordenar por tiempo de creación, y entregar cada uno con su propia línea MEDIA:.
import glob, os, time
batch_start = time.time()
pdfs = sorted(glob.glob("/opt/researchit/vault/researchit_*.pdf"), key=os.path.getctime)
for pdf in pdfs:
if os.path.getctime(pdf) >= batch_start - 60: # created during this run
print(f"MEDIA:{pdf}") # one line per PDF
Si ocurre que un PDF no se entrega (síntoma: el reflect lo menciona como "pendiente" días después), verificar:
vault/? (Si pasaron 4+ días, puede haber sido limpiado.)Ver references/weekly-cron-patterns.md para el patrón completo de inteligencia laboral semanal y ejemplos de configuración.
El PDF está optimizado para lectura en teléfonos móviles:
| Parámetro | Valor |
|---|---|
| Fuente | DejaVu Sans 11pt (disponible en ARM64/OL9) |
| Alineación | Justificado con leading 0.7em |
| Márgenes | 1.6cm laterales, 1.2cm verticales |
| Títulos H1 | 17pt bold, con pagebreak, fondo azul marino (texto blanco), radius 4pt |
| Títulos H2 | 14pt bold, fondo gris claro (#e8f0fe), texto azul (#1e3a5f) |
| Títulos H3 | 12pt bold, texto azul (#2d5a87) |
| Links | Azul #1a56db |
| Raw blocks | Fondo gris (#f1f5f9), texto 7.5pt |
| Strong/Bold | Texto #1e293b |
| Encabezado/Footer | Texto gris suave (#94a3b8 / #cbd5e1) |
NO usar cmarker — no funciona en este entorno. La conversión MD→Typst es directa vía report._md_to_typst().
NO hay bold/italic conversion — el texto con * y _ se escapa completamente para evitar errores de "unclosed delimiter" en Typst. Los únicos formatos inline convertidos son: codigo → raw(), y [texto](url) → #link().
Todos los secrets se manejan vía Infisical + GitHub Secrets. NO hardcodear en código.
Variables requeridas:
COMPOSIO_API_KEY — API key de Composio (para Reddit via MCP)COMPOSIO_REDDIT_CONNECTION_ID — connection ID de Reddit en ComposioOPENCODE_GO_API_KEY — API key de OpenCode GoOPENCODE_GO_BASE_URL — URL base de OpenCode Go (default: https://opencode.ai/zen/go/v1)Resolución de secrets (por orden de prioridad):
INFISICAL_SERVICE_TOKEN en env → InfisicalClient.get_secret())os.getenv())Exportación correcta:
set -a && source /home/opc/.hermes/.env && set +a
Sin set -a, las variables no se exportan a procesos hijo (Kilo, Python) y fallan con 401 o "Missing API key".