Skip to content

daochild/agentic-search-optimization-engine

Repository files navigation

agentic-search-optimization-engine

Python CLI + API приложение для базового SEO-анализа целевого сайта, сравнения с конкурентами и генерации SEO-ядра.

Текущий статус: Phase 4 backend MVP: CLI + FastAPI + async jobs + file-backed artifacts.

Что уже реализовано

  • CLI-команда analyze
  • CLI-команда search
  • анализ локального HTML-файла, URL или домена
  • эвристическое определение ниши по SEO-сигналам страницы
  • извлечение title, meta description, headings, links, keywords
  • сравнение целевой страницы с конкурентами
  • генерация SEO-core / keyword opportunities
  • прямой поиск по ключевой фразе через SERP provider
  • query-driven competitor discovery из SERP
  • поддержка geo, language, device, search_engine
  • сохранение до 10 SERP результатов и выбор primary top-5 shortlist
  • page type classification для target / SERP / competitors
  • bounded crawl mode для target site с --page-limit
  • LLM provider abstraction
  • local heuristic enrichment provider по умолчанию
  • Ollama provider for external local or cloud LLM inference
  • task-aware prompt versioning (phase3-v3/*) for structured enrichment
  • automatic Ollama retry on invalid/truncated JSON responses
  • niche summary, opportunity scoring и content-gap explanations
  • page recommendations и content brief draft
  • FastAPI server mode (serve)
  • async background jobs for analyze and search
  • file-backed persistence for job metadata and result artifacts
  • export artifacts in json, text, markdown, and csv
  • default report output in data/
  • default report naming: <website>_analysis_<date> and <website>_search_<date>
  • вывод в text и json
  • загрузка списка конкурентов из JSON через --serp-file

Что пока не реализовано

  • реальный SERP crawling из Google / Perplexity API
  • кластеризация на уровне всего сайта
  • PostgreSQL / Redis production persistence
  • dashboard и scheduled re-runs

Структура проекта

agentic-search-optimization-engine/
├── main.py
├── pyproject.toml
├── README.md
├── SOW.md
├── ARCHITECTURE.md
├── TODO.md
├── seo_agent_cli/
│   ├── __init__.py
│   ├── __main__.py
│   ├── analyzer.py
│   ├── cli.py
│   ├── crawler.py
│   ├── extractors.py
│   ├── heuristics.py
│   ├── jobs.py
│   ├── llm.py
│   ├── models.py
│   ├── reporters.py
│   ├── search.py
│   ├── server.py
│   └── serp.py
└── tests/
	├── fixtures/
	├── test_analyzer.py
	├── test_cli.py
  ├── test_extractors.py
  ├── test_llm.py
  ├── test_search.py
  └── test_server.py

Требования

  • Python >= 3.14
  • зависимости backend MVP: fastapi, uvicorn, httpx

Быстрый старт

Из корня проекта:

cd /c/dev/agentic-search-optimization-engine
python -m pip install -e .
python -m unittest discover -s tests -v
python main.py analyze --site tests/fixtures/target_site.html --competitor tests/fixtures/competitor_agency.html --competitor tests/fixtures/competitor_content.html --max-core 10 --format text
python main.py search --query "купить машину украина" --top 5 --format text
python main.py analyze --site tests/fixtures/target_site.html --competitor tests/fixtures/competitor_agency.html --competitor tests/fixtures/competitor_content.html --llm-provider local --brief-audience "SEO manager" --max-core 8 --format text
python main.py analyze --site tests/fixtures/target_site.html --competitor tests/fixtures/competitor_agency.html --competitor tests/fixtures/competitor_content.html --llm-provider ollama --llm-model deepseek-v3.2:cloud --llm-timeout 250 --brief-audience "SEO manager" --max-core 8 --format json
python main.py serve --host 127.0.0.1 --port 8000 --artifacts-dir data

Примеры использования

1. Анализ локального HTML

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --competitor tests/fixtures/competitor_agency.html \
  --competitor tests/fixtures/competitor_content.html \
  --format text

2. Анализ с JSON-выводом

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --competitor tests/fixtures/competitor_agency.html \
  --format json

Если --output не задан, отчёт по умолчанию будет сохранён в data/ c именем вида:

target-site_analysis_20260405.json

3. Конкуренты через --serp-file

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --serp-file tests/fixtures/serp_results.json \
  --max-competitors 5 \
  --max-core 15

4. Прямой поиск по ключевой фразе

Пример:

python main.py search \
  --query "купить машину украина" \
  --top 5 \
  --format text

JSON-режим:

python main.py search \
  --query "купить машину украина" \
  --top 5 \
  --format json

Если --output не задан, search report по умолчанию будет сохранён в data/ c именем вида:

auto-ria_search_20260405.json

Если нужен дополнительный анализ найденных страниц:

python main.py search \
  --query "купить машину украина" \
  --top 5 \
  --analyze-pages \
  --format text

5. Offline test mode для поиска

python main.py search \
  --query "купить машину украина" \
  --provider file \
  --serp-source tests/fixtures/duckduckgo_search_results.html \
  --top 3 \
  --format text

6. Query-driven analysis по ключевой фразе

Если у тебя есть целевой сайт и нужно автоматически подтянуть конкурентов из SERP по ключу:

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --query "купить машину украина" \
  --provider file \
  --serp-source tests/fixtures/duckduckgo_search_results.html \
  --geo ua \
  --language uk \
  --device mobile \
  --search-engine google \
  --max-competitors 5 \
  --max-core 10 \
  --format text

7. Bounded crawl mode для target site

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --crawl-site \
  --page-limit 3 \
  --format text

Этот режим берёт seed page и анализирует ограниченное число внутренних ссылок.

8. Phase 3 enrichment с локальным LLM provider

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --competitor tests/fixtures/competitor_agency.html \
  --competitor tests/fixtures/competitor_content.html \
  --llm-provider local \
  --brief-audience "SEO manager" \
  --max-core 8 \
  --format text

Если enrichment временно не нужен:

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --competitor tests/fixtures/competitor_agency.html \
  --llm-provider none \
  --format json

9. Phase 3 enrichment через Ollama

Если у тебя доступен Ollama-compatible endpoint:

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --competitor tests/fixtures/competitor_agency.html \
  --competitor tests/fixtures/competitor_content.html \
  --llm-provider ollama \
  --llm-model deepseek-v3.2:cloud \
  --llm-host http://127.0.0.1:11434 \
  --llm-timeout 250 \
  --brief-audience "SEO manager" \
  --max-core 8 \
  --format text

10. Реальный smoke test для deepseek-v3.2:cloud

python main.py analyze \
  --site tests/fixtures/target_site.html \
  --competitor tests/fixtures/competitor_agency.html \
  --competitor tests/fixtures/competitor_content.html \
  --llm-provider ollama \
  --llm-model deepseek-v3.2:cloud \
  --llm-host http://127.0.0.1:11434 \
  --llm-timeout 250 \
  --brief-audience "SEO manager" \
  --max-core 8 \
  --format json

Примечания:

  • если Ollama недоступен, приложение автоматически откатится на local enrichment и добавит warning;
  • по умолчанию модель для Ollama: deepseek-v3.2:cloud;
  • по умолчанию latency/timeout budget для Ollama: 250 секунд;
  • для cloud/remote Ollama-compatible моделей можно отдельно увеличить --llm-timeout без изменения основного HTTP timeout для страниц;
  • для deepseek-v3.2:cloud запросы отправляются с think=false, task-aware prompt versions (phase3-v3/*) и automatic retry при invalid/truncated JSON;
  • также поддерживаются переменные окружения OLLAMA_HOST и OLLAMA_MODEL.

Реально проверенный smoke test на этой машине (2026-04-05):

  • endpoint http://127.0.0.1:11434 доступен;
  • модель deepseek-v3.2:cloud установлена;
  • команда выше успешно вернула structured Phase 3 output без fallback warnings;
  • в live output были подтверждены niche_summary, opportunity_scores, gap_explanations, page_recommendations и content_brief.

11. Phase 4 backend server mode

Запуск API-сервера:

python main.py serve \
  --host 127.0.0.1 \
  --port 8000 \
  --artifacts-dir data

Ключевые endpoints:

  • GET /health
  • GET /api/v1/jobs
  • POST /api/v1/jobs/analyze
  • POST /api/v1/jobs/search
  • GET /api/v1/jobs/{job_id}
  • GET /api/v1/jobs/{job_id}/result
  • GET /api/v1/jobs/{job_id}/artifacts
  • GET /api/v1/jobs/{job_id}/artifacts/{artifact_name}

Пример создания analyze job:

curl -X POST "http://127.0.0.1:8000/api/v1/jobs/analyze" \
  -H "Content-Type: application/json" \
  -d '{
    "target_source": "tests/fixtures/target_site.html",
    "competitor_sources": ["tests/fixtures/competitor_agency.html"],
    "llm_provider_name": "none",
    "max_core_terms": 8
  }'

Пример создания search job:

curl -X POST "http://127.0.0.1:8000/api/v1/jobs/search" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "купить машину украина",
    "limit": 2,
    "preserve_limit": 3,
    "provider": "file",
    "serp_source": "tests/fixtures/duckduckgo_search_results.html"
  }'

Artifacts сохраняются в каталоге, указанном через --artifacts-dir, в структуре:

data/
├── jobs/
│   └── <job_id>.json
└── artifacts/
    └── <job_id>/
        ├── <website>_analysis_<date>.json
        ├── <website>_analysis_<date>.txt
        ├── <website>_analysis_<date>.md
        └── <website>_analysis_<date>.csv

Файл serp_results.json должен содержать массив строк или объектов с полем url, domain или source.

Пример:

[
  "https://example.com",
  { "url": "https://competitor.example" },
  { "source": "tests/fixtures/competitor_agency.html" }
]

Контракт результата

CLI возвращает:

  • niche_hypotheses — 2–3 гипотезы ниши
  • target — on-page SEO сигналы целевой страницы
  • search_result — SERP context и preserved/primary results при --query
  • competitors — анализ пересечений и gaps по конкурентам
  • crawled_pages — дополнительные страницы target site при --crawl-site
  • niche_summary — краткое резюме ниши и evidence band
  • opportunity_scores — score/label/explanation по возможностям
  • gap_explanations — объяснения content gaps по конкурентам
  • page_recommendations — рекомендации по типу страницы и кластеру
  • cluster_bundles — сгруппированные кластеры термов
  • content_brief — draft брифа для контента
  • seo_core — итоговое SEO-ядро с полями:
    • term
    • cluster
    • intent
    • priority
    • source
    • competitor_count
    • target_score
    • competitor_score
    • supporting_terms
    • rationale

Текущее позиционирование MVP

Это Phase 4 backend MVP с CLI и API, а не финальный production SEO engine. Он полезен для:

  • прототипирования пайплайна
  • проверки формата результата
  • быстрой локальной проверки HTML-страниц
  • query-driven competitor discovery
  • черновой генерации priorities, page recommendations и content briefs
  • фонового запуска анализов через jobs API
  • экспорта артефактов в несколько форматов
  • подготовки к следующему этапу: PostgreSQL / Redis / dashboard / scheduled jobs

Следующие шаги

См. SOW.md, ARCHITECTURE.md и TODO.md.

About

Python CLI + API application for basic SEO-analys of the target website, competitors comparision and and SEO-core generation.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages