Lee Foot

Representative Keyword Normaliser

Suggest a cleaner representative keyword for each keyword using an LLM.

View the source

#about

Sends each keyword to any OpenAI-compatible endpoint (Ollama with qwen2.5:7b by default, or the OpenAI API) and asks for a more descriptive representative keyword in the same language.

Uses structured JSON schema responses with tenacity retry (3 attempts, 2-second wait).

Strips non-printable characters outside ASCII, Arabic and Devanagari ranges before sending.

Requires an API key

Platform
Python script (requires Python 3.x)
Input
CSV with a keyword columnAPI endpoint URL and optional API key
Output
CSV with all original columns plus a Suggested Keyword column containing the normalised representative keyword for each row.

Use cases

  • Cleaning messy or truncated keyword exports before clustering
  • Normalising scraped page titles into search-style keywords
  • Pre-processing multilingual keyword lists for grouping

#features

  • Any OpenAI-compatible endpoint (Ollama qwen2.5:7b default, or OpenAI)
  • Structured JSON schema response format
  • tenacity retry: 3 attempts with 2-second fixed wait
  • Input cleaning: strips characters outside ASCII, Arabic and Devanagari
  • Language preservation: output in the same language as input
  • Changed-count and error-count metrics in results

#how-to-use

  1. Set the API base URL in the sidebar (Ollama default or OpenAI)
  2. Enter the model name and optional API key
  3. Upload your keyword CSV
  4. Select the keyword column
  5. Click Suggest Representative Keywords
  6. Download the CSV with the Suggested Keyword column

#faq

Does it require an API key?
Not if you use a local Ollama server (the default). The default base URL is http://127.0.0.1:11434/v1 with the api_key set to 'not-needed'. For OpenAI or other hosted endpoints, enter a real key in the sidebar.
What model does it use by default?
qwen2.5:7b via Ollama. This is a local model that runs without API costs. You can change it to any model name your endpoint supports, such as gpt-4o-mini for OpenAI.
How does it handle non-Latin scripts?
Before sending each keyword, it strips characters outside printable ASCII (0x20-0x7E), Arabic (0x0600-0x06FF) and Devanagari (0x0900-0x097F) ranges. Characters in other scripts are removed. The prompt instructs the model to respond in the same language as the source keyword.
What happens when the API call fails?
Each keyword is retried up to 3 times with a 2-second fixed wait between attempts (using the tenacity library). If all retries fail, the Suggested Keyword column for that row contains an error message starting with 'Error:'.
Does it batch keywords or process them one at a time?
One API call per keyword. Each call uses structured JSON schema response format, so the output is a single JSON object with one 'keyword' field. This means processing time and cost scale linearly with keyword count.

/contact

Want me to run this for you? I run this tool as a managed service, or build something custom around your data. You get the insights without touching the code.