Proxies + AI

Run an AI Research Agent Across Multiple US Cities

October 2026·9 min read·AI agents, local SEO, price monitoring, geo QA

Most "local" questions can't be answered from one place: what a search shows in Denver, what a store charges in Miami, whether a geo-targeted page renders in Houston. This guide builds a small research agent that runs the same task from several US cities using one proxy, a RelayKit Multi Location mobile proxy, whose city you switch in the dashboard between runs. It verifies the city before every pass and writes everything to a CSV you can compare.

In this guide

  1. How one proxy covers many cities
  2. The run loop
  3. The runner (Python)
  4. Writing the task
  5. Running it
  6. Comparing results
  7. Good habits

1. How one proxy covers many cities

A Multi Location proxy is one dedicated Verizon mobile proxy. In the RelayKit dashboard, its card has a city picker; choosing a city connects the proxy to a modem there and gives it an IP in that city. You can do this as often as you like during the plan, with no extra purchase. The host, ports and credentials don't change when the city changes, only the IP does. That's what makes the loop below simple: the script never has to know which city is next. It just checks where it is.

Scope: the proxy is in one city at a time, so cities run one after another, not in parallel. For a handful of cities that's a few minutes each. If you need many cities at the same moment, use one proxy per city instead.

2. The run loop

  1. Script checks the proxy's current exit IP and city (a geolocation lookup through the proxy).
  2. If the city is new, it runs the task, and saves the result with the city, IP and time.
  3. It then waits: "Switch the proxy to the next city in the dashboard, then press Enter (or q to finish)."
  4. You switch the city on the proxy card, press Enter, and it loops.

The city switch stays a human step on purpose; it's one click in the dashboard, and it keeps the script free of anything but research. The script does guard against a run where the switch hasn't taken effect yet, by refusing to record the same city twice.

3. The task

The runner uses Playwright so it works with any site, and leaves the collect() function to you. Two starting points:

If you prefer a model-driven agent, replace collect() with a browser-use task; the loop around it is unchanged. Before any of this, get your proxy details from the card: 🤖 Use with AI tools → Playwright (Python) gives you the PROXY dict below pre-filled.

4. The runner (Python)

multi_city_agent.py
import csv, json, sys, time from datetime import datetime, timezone from playwright.sync_api import sync_playwright # pip install playwright && playwright install chromium PROXY = {"server": "http://HOST:8000", "username": "USER", "password": "PASS"} # from your proxy card OUT = "results.csv" GEO_URL = "https://ipapi.co/json/" # tells us the city the proxy is in right now def where_am_i(page): page.goto(GEO_URL, timeout=45_000) g = json.loads(page.inner_text("body")) return {"ip": g.get("ip"), "city": g.get("city"), "region": g.get("region_code") or g.get("region")} def collect(page): """Your research task. Return a dict of the fields you want in the CSV.""" page.goto("https://example.com/pricing", timeout=60_000, wait_until="domcontentloaded") # the page you're researching page.wait_for_selector(".price", timeout=30_000) # adjust to the site prices = [el.inner_text().strip() for el in page.query_selector_all(".price")] return {"prices": " | ".join(prices)} def main(): seen = set() rows = [] with sync_playwright() as p: browser = p.chromium.launch(proxy=PROXY) while True: page = browser.new_page() try: loc = where_am_i(page) key = (loc["city"], loc["region"]) if key in seen: print(f"Still in {loc['city']}, {loc['region']} — the switch hasn't taken effect yet. Wait ~30s and retry.") else: print(f"Running from {loc['city']}, {loc['region']} ({loc['ip']})…") data = collect(page) row = {"ran_at": datetime.now(timezone.utc).isoformat(timespec="seconds"), **loc, **data} rows.append(row); seen.add(key) print(" ->", data) except Exception as e: print(" run failed:", e) finally: page.close() ans = input("Switch the proxy to the next city in the dashboard, then press Enter (q to finish): ").strip().lower() if ans == "q": break time.sleep(5) # give the new connection a moment browser.close() if rows: with open(OUT, "w", newline="") as f: w = csv.DictWriter(f, fieldnames=list(rows[0].keys())) w.writeheader(); w.writerows(rows) print(f"Saved {len(rows)} rows to {OUT}") if __name__ == "__main__": main()

5. Running it

  1. In the dashboard, open your Multi Location proxy card and pick the first city. Wait for the card to show an IP.
  2. Run python multi_city_agent.py. It prints the city it detected and the collected data.
  3. Back in the dashboard, pick the next city. When the card shows the new IP, press Enter in the terminal.
  4. Repeat for each city, then type q. Results are in results.csv.

The detected city comes from a public IP geolocation database and usually matches the proxy's city or its metro area; occasionally it names a neighboring city. The region column is the reliable one for grouping.

6. Comparing results

compare.py
import pandas as pd # pip install pandas df = pd.read_csv("results.csv") print(df[["city", "region", "prices"]].to_string(index=False)) # Any city whose 'prices' differs from the most common value: mode = df["prices"].mode().iloc[0] print("\nDiffers from the common result:") print(df[df["prices"] != mode][["city", "region", "prices"]].to_string(index=False))

For a recurring study, run the loop on a schedule (one city per scheduled run works well: the dashboard remembers the proxy's city until you change it) and append to the CSV instead of overwriting.

7. Good habits

One proxy, every US city on the list

A Multi Location mobile proxy switches between US cities from the dashboard, with unlimited data, HTTP and SOCKS5. Weekly and monthly plans; pay with crypto.

Related guides