The code
The whole tool is about 250 lines of plain Python — no framework, no platform, nothing hidden. run.py asks the engines the questions and saves a dated snapshot; report.py turns those snapshots into the weekly report. Open any file raw:
run.py · report.py · prompts.json
run.py — the engine probe
#!/usr/bin/env python3
"""GIG AI-Visibility runner. Asks a prompt set across answer engines, detects whether
GIG Gulf (and competitors) get cited, scores by GEO phase, saves a dated snapshot."""
import json, os, re, datetime, urllib.request, concurrent.futures as cf
ROOT = os.path.dirname(os.path.abspath(__file__))
CRED = os.path.expanduser("~/ClaudeWork/Claude/credentials.md")
def key(section, pat):
f=False
for l in open(CRED, errors="ignore"):
if l.startswith("### "+section): f=True; continue
if f and re.search(pat, l): return re.search(pat, l).group(0)
ANTH = key("Anthropic API", r"sk-ant-[A-Za-z0-9_-]{20,}")
OAI = key("OpenAI", r"sk-[A-Za-z0-9_-]{20,}")
SERP = key("Serper", r"[a-f0-9]{40}")
# GIG Gulf is the rebrand of AXA Gulf. AXA legacy equity is OWNED demand, so an
# "AXA" mention counts as GIG-favourable, not a competitor.
GIG = [r"gig gulf", r"gulf insurance group", r"gig-gulf", r"\baxa\b"]
COMP = {"Sukoon":["sukoon"],"Tawuniya":["tawuniya"],"Salama":["salama"],
"Orient":["orient"],"Daman":["daman"],"ADNIC":["adnic"],
"RSA/Liva":["liva"],"Yallacompare":["yallacompare","policybazaar"]}
def mentioned(t, pats): t=t.lower(); return any(re.search(p,t) for p in pats)
def http(url, data, headers):
req=urllib.request.Request(url, data=json.dumps(data).encode(), headers=headers)
with urllib.request.urlopen(req, timeout=30) as r: return json.loads(r.read())
def ask_openai(q):
d=http("https://api.openai.com/v1/chat/completions",
{"model":"gpt-4o-mini","max_tokens":400,"messages":[
{"role":"system","content":"Insurance shopping assistant for the UAE. Name specific insurers."},
{"role":"user","content":q}]},
{"Authorization":"Bearer "+OAI,"Content-Type":"application/json"})
return d["choices"][0]["message"]["content"]
ENGINES={"ChatGPT":ask_openai, "Claude":ask_claude, "Google":ask_google}
def run_one(p, eng):
txt=ENGINES[eng](p["q"])
return {"id":p["id"],"phase":p["phase"],"lob":p["lob"],"engine":eng,
"gig":mentioned(txt,GIG),"competitors":[c for c,ps in COMP.items() if mentioned(txt,ps)]}
def main():
prompts=json.load(open(os.path.join(ROOT,"prompts.json")))
jobs=[(p,e) for p in prompts for e in ENGINES]
with cf.ThreadPoolExecutor(max_workers=12) as ex:
rows=[f.result() for f in cf.as_completed([ex.submit(run_one,p,e) for p,e in jobs])]
date=datetime.date.today().isoformat()
json.dump({"date":date,"rows":rows}, open(os.path.join(ROOT,"snapshots",date+".json"),"w"))
if __name__=="__main__": main()
Abridged for reading — Claude and Google callers follow the same shape as ChatGPT. Full file via the link above.
How to run
cd ~/ClaudeWork/Clients/GIG/AIVisibility python3 run.py # asks the engines, writes snapshots/YYYY-MM-DD.json python3 report.py # builds the weekly report from the snapshots
The roadmap is the same shape, about 80 lines more: add Perplexity and Gemini callers, run each prompt three times for a confidence band, and capture the cited URLs.