🤖 Content-adaptive GEO in one click: multi-turn rewriting with minimal feedback.
| - 🧩 **What**: Optimize document *visibility & attribution* in black‑box generative search engines (Generative Engine Optimization, GEO). - 🔧 **How**: Model GEO as **content‑conditioned problem**, then train a MAP‑Elites strategy archive + co‑evolving critic for rewriting strategy selection. - 🚀 **Why it matters**: GEO often relies on an assumed globally-optimal fixed prompt; AgenticGEO learns a content-adaptive strategy selection policy, optmizing with fewer GE calls. |
|

AgenticGEO consists of three stages:
We use GEO‑Bench impression metrics: - Attributed Word Count (word) - Position‑Weighted Citation Order (pos) - Overall (combination of word & pos)
pip install -r requirements.txt
src/run_geo.py loads a base model for architecture/tokenizer (e.g. Qwen/Qwen2.5-1.5B-Instruct). You can download it into base_model/ using the provided script:
python base_model/download_base_model.py
src/run_geo.py reads sources from src/global_cache.json. Preloading avoids missing sources at runtime.
python src/preload_cache_from_geobench.py
python src/preload_cache_from_msdata.py
The repo reads OpenAI-compatible settings from config.ini (or environment variables).
Set in config.ini:
USE_LOCAL_LLM = TrueLOCAL_LLM_BASE = http://localhost:8000/v1LOCAL_LLM_MODEL = <your served model name>Using OpenAI or a hosted compatible provider:
USE_LOCAL_LLM = False and provide OPENAI_API_KEY / OPENAI_API_BASE in config.ini# Dataset type and split
$env:DATASET_TYPE = "geobench" # geobench | msdata | ecommerce
$env:DATASET_SPLIT = "test" # train | test | val
# Base model path (for Critic structure/tokenizer)
$env:EVOLVED_BASE_MODEL = "E:\AICling\agentic_geo\base_model"
evolved/ by default)No extra weights are required by default; src/run_geo.py will auto-load:
evolved/archive/strategies.jsonevolved/critic/lora_adapter/evolved/critic/value_head.binIf you want to override any of them, set these optional environment variables (paths can be absolute or relative to the project root):
# Optional: override strategies file
# $env:EVOLVED_STRATEGIES = "E:\path\to\strategies.json"
# Optional: override value head
# $env:EVOLVED_VALUE_HEAD = "E:\path\to\value_head.bin"
# Optional: override LoRA adapter
# $env:EVOLVED_LORA_ADAPTER = "E:\path\to\lora_adapter"
# Optional: override backbone weights (e.g. pytorch_model.bin)
# $env:EVOLVED_PRETRAINED_BACKBONE = "E:\path\to\pytorch_model.bin"
$env:USE_CONCURRENT = "True"
$env:MAX_WORKERS = "10"
# Optional: cache file location (default: src/global_cache.json)
# $env:GLOBAL_CACHE_FILE = "E:\AICling\agentic_geo\src\global_cache.json"
python src/run_geo.py
The script prints the final output path. Results are saved under src/results/ with a filename like:
geo_results_{model}_{split}.jsonWhere {model} comes from:
LOCAL_LLM_MODEL in config.ini (when USE_LOCAL_LLM=True), orMODEL_NAME (when USE_LOCAL_LLM=False)This project is released under the MIT License. See LICENSE.
We thank the GEO‑Bench authors and the open‑source LLM ecosystem.
$ claude mcp add agentic_geo \
-- python -m otcore.mcp_server <graph>