Skip to content

Add AI chat demo with prompt-based embedding ad targeting#1187

Draft
ericholscher wants to merge 4 commits intomainfrom
claude/chat-ai-ethical-ads-ZPWS7
Draft

Add AI chat demo with prompt-based embedding ad targeting#1187
ericholscher wants to merge 4 commits intomainfrom
claude/chat-ai-ethical-ads-ZPWS7

Conversation

@ericholscher
Copy link
Copy Markdown
Member

Summary

Prototype of an AI chat interface that targets ethical ads based on conversation context using embeddings.

  • Chat UI at /chat/ sends user prompts to OpenAI (gpt-4o-mini) for responses
  • In parallel, the same prompt is sent to the ad decision API with a new prompt field
  • The backend generates an embedding (OpenAI text-embedding-3-small) from the prompt text and computes cosine similarity against advertiser content embeddings
  • Flights with niche_targeting set in their targeting_parameters are filtered by this similarity score
  • When no prompt is provided, the existing URL-based niche targeting via ethicalads_ext.embedding is used as a fallback
  • Keywords are also extracted client-side from the prompt as a secondary targeting signal

Targeting approach

  1. Prompt embedding: The full prompt text is embedded via OpenAI's text-embedding-3-small model and cached for 1 hour
  2. Advertiser embedding: Each flight's live ad creatives (headline, content, CTA) are embedded the same way
  3. Cosine similarity: The distance between prompt and advertiser embeddings is compared against each flight's niche_targeting threshold (lower distance = better match)
  4. Keyword fallback: Significant words are extracted client-side from the prompt and passed as pipe-delimited keywords for standard keyword targeting

Local setup

# Install and migrate
pip install openai
python manage.py migrate

# Prep the database with test data (uses first existing objects, creates what's missing)
python manage.py shell < scripts/prep_chat_demo_db.py

# Set env vars (publisher slug is printed by the script above)
export OPENAI_API_KEY="sk-your-key-here"
export ADSERVER_CHAT_DEMO_PUBLISHER="your-publisher-slug"

# Run and open http://localhost:8000/chat/
python manage.py runserver

The prep script grabs the first existing Publisher, Advertiser, Campaign, Flight, Advertisement, and AdType, then patches them to be live and wired together for the demo.

Test plan

  • Run python manage.py shell < scripts/prep_chat_demo_db.py on a fresh DB and verify it creates all needed objects
  • Run on a DB with existing data and verify it reuses first objects without creating duplicates
  • Open /chat/, send a message, verify chat response appears
  • Verify ad decision request fires in the browser network tab with prompt and keywords params
  • Verify ads render in the sidebar when matching ads exist
  • Test with OPENAI_API_KEY unset: chat returns error, ad API still works via keyword targeting
  • Test the decision API directly: curl 'http://localhost:8000/api/v1/decision/?publisher=SLUG&div_ids=ad1&ad_types=AD_TYPE&prompt=python+web+development'

https://claude.ai/code/session_01YGtppBeFRZNHxdEguYKxnY

claude and others added 4 commits March 26, 2026 23:12
Introduces a chat prototype that sends prompts to OpenAI (gpt-4o-mini)
and simultaneously passes the prompt to the ethical ads decision API.
The backend generates an embedding from the prompt text and uses cosine
similarity against advertiser content embeddings for niche ad targeting.

- Add `prompt` field to AdDecisionSerializer for embedding-based targeting
- Create chatdemo app with embedding utility, views, and jQuery frontend
- Wire prompt embeddings into ProbabilisticFlightBackend for niche targeting
- Add ChatCompletionProxyView to keep OpenAI API key server-side
- Frontend at /chat/ shows chat + contextual ad sidebar

https://claude.ai/code/session_01YGtppBeFRZNHxdEguYKxnY
A convenience script that wires up existing model instances (or creates
minimal ones) so the /chat/ demo can request and display ads locally.

https://claude.ai/code/session_01YGtppBeFRZNHxdEguYKxnY
Publishes total queue depth (celery + analyzer + priority) to CloudWatch
every minute as EthicalAds/Celery/QueueDepth. Used by the celery ASG
target tracking autoscaling policy in the ops repo.
Run ruff --fix on scripts/prep_chat_demo_db.py to resolve 8 lint errors
(unused imports, f-strings without placeholders). Add comprehensive tests
for the chatdemo embedding utilities, views, and the publish_celery_queue_depth
task to bring coverage back above the 94% threshold.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants