Think of this AI system as a news analyst for Starbucks’ suppliers. It reads news articles about your suppliers and tells you if there are red flags that could disrupt your coffee supply chain.
Imagine you have a coffee supplier in Brazil. One day, a news article comes out saying:
“Factory closes after environmental violations. Workers staged a strike over unsafe conditions. Company faces bankruptcy risk.”
The AI reads this article and asks itself: “How risky is this supplier right now?” Then it gives you a score from 0 to 100.
The AI acts like a trained detective investigating a supplier. It looks for clues:
The AI reads the tone of the article—is it positive or negative?
It’s like if I told you, “The factory is thriving!” vs. “The factory is collapsing!”
The AI looks for specific danger words in four categories:
| Category | Warning Signs |
|---|---|
| Labor Violations | strike, union dispute, worker injury, unsafe conditions |
| Environmental Damage | pollution, spill, waste, contamination |
| Political Instability | protest, sanction, military unrest |
| Financial Distress | bankruptcy, debt, credit rating downgrade |
When it finds these keywords, it’s like finding clues at a crime scene. More clues = bigger problem.
The AI counts how many risk keywords appear relative to article length.
Example:
Article A is clearly more concerning.
This is the trickiest part, but stay with me.
Imagine you have a mental catalog of past supply chain disasters in your memory. When a new article comes in, the AI asks: “Does this article sound like one of those disasters?”
It doesn’t look for exact word matches. Instead, it looks for similar meaning and context. Here’s an analogy:
These are different words but same meaning. The AI would recognize they’re similar.
It does this using something called an embedding—think of it as a unique fingerprint of what an article is about. If the fingerprint matches past disaster fingerprints, that’s a red flag.
The AI combines all these clues into one number (0–100):
Final Risk Score = (Negative Sentiment × 25) + (Theme Score × 25) + (Keyword Intensity × 25) + (Disaster Similarity × 25)
In plain English:
Sample Article:
“A major factory was forced to close after pollution complaints. Workers staged a strike as management failed to meet safety demands. The company is facing mounting debt and rumors of bankruptcy.”
What the AI Finds:
✅ Sentiment: Negative (-0.25 on scale of -1 to +1)
✅ Risk Themes Detected:
✅ Keyword Intensity: 5 risk words in ~30 total words = about 13% intensity
✅ Disaster Similarity: Compares to past crisis cases = slight match
✅ Final Score: 9.81 out of 100
Translation: Low-to-moderate risk. The supplier has real problems, but they’re not catastrophic yet. Starbucks should monitor the situation but doesn’t need to panic.
Instead of having a person manually read thousands of news articles every day, the AI does it automatically. It’s like having a tireless news analyst who:
This helps Starbucks prevent supply shocks—if a coffee supplier is having problems, you find out before your stores run out of beans.
The AI doesn’t “think” the way humans do. Instead, it uses two key tricks:
We taught it by saying: “These words usually mean labor problems. These words usually mean environmental problems.” The AI just counts them.
We gave it a smart model trained on millions of articles. This model learned to recognize meaning beyond just words. So it can tell that “factory closure” and “facility shutdown” mean the same thing, even though they use different words.
The model itself (all-MiniLM-L6-v2) is pre-trained — it came from a library of AI models. We don’t need to train it ourselves; we just use it offline in your system.
⚠️ Important: This AI runs entirely on your computer. It doesn’t send your supplier data anywhere—no cloud, no API, no external companies. It’s all private and secure.
cd /workspaces/blank-app
source .venv/bin/activate
pip install textblob numpy sentence-transformers streamlit pandas plotly PyPDF2 st-aggrid
Note on PyPDF2: Required for PDF article uploads. Install with pip install PyPDF2
Optional: Install st-aggrid for enhanced interactive tables (pip install st-aggrid)
That’s it! No API keys, no external service subscriptions needed.
streamlit run app.py
When you upload a JSON file with supplier data through the Streamlit app, the system automatically:
suppliers.db)In the Streamlit app, after uploading suppliers:
The system uses two main tables:
suppliers table:
id: Unique identifiername: Supplier name (unique)data: Original supplier JSON datarisk_score: Latest risk score (0-100)risk_level: Risk category (LOW, MODERATE, HIGH, SEVERE)created_at: First upload timestampupdated_at: Last update timestampscoring_history table:
id: Unique identifiersupplier_id: Reference to supplierrisk_score: Risk score from this evaluationrisk_level: Risk level from this evaluationsubscores: Component scores (JSON) - food safety, regulatory, operational, financialscored_at: When this score was calculatedYou can also use the database directly in your own Python code:
from database import SupplierDatabase
# Initialize database
db = SupplierDatabase()
# Save a supplier
supplier_id = db.save_supplier({
"name": "Acme Suppliers",
"foodSafetyQuality": {...},
...
})
# Save scoring result
db.save_scoring_result(
supplier_id=supplier_id,
risk_score=35,
risk_level="MODERATE",
subscores={"foodSafety": 0.45, "regulatory": 0.35, ...}
)
# Retrieve suppliers
all_suppliers = db.get_all_suppliers()
by_risk = db.get_suppliers_by_risk_level("HIGH")
history = db.get_scoring_history(supplier_id)
# Get statistics
stats = db.get_summary_stats()
When you upload and analyze news articles in Tab 2, the system automatically:
news_articles.db)News Database Schema:
news_articles table:
id: Unique identifierfilename: Original filenamecontent: Full article textcontent_length: Length of article in charactersuploaded_at: Upload timestampnews_scoring_results table:
id: Unique identifierarticle_id: Reference to articleoverall_risk_score: Risk score (0-100)risk_level: Risk category (LOW, MODERATE, HIGH, SEVERE)sentiment_score: Sentiment analysis scorekeyword_intensity_score: Intensity of risk keywordsdisruption_similarity_score: Similarity to past disruptionstheme_scores: JSON with scores for each risk themefull_results: Complete analysis results as JSONscored_at: When this analysis was performedNews Database Features:
Python API for News Database:
from news_database import NewsDatabase
# Initialize database
db = NewsDatabase()
# Save an article
article_id = db.save_article("article.txt", "Article content here...")
# Save scoring result
db.save_scoring_result(
article_id=article_id,
overall_risk_score=65.5,
risk_level="HIGH",
sentiment_score=-0.45,
keyword_intensity_score=0.75,
disruption_similarity_score=0.60,
theme_scores={"labor": 0.8, "environmental": 0.6, ...},
full_results={...}
)
# Retrieve articles
all_articles = db.get_all_articles()
high_risk_articles = db.get_articles_by_risk_level("HIGH")
search_results = db.search_articles("environmental")
# Get scoring history
scores = db.get_scoring_results_for_article(article_id)
# Get statistics
stats = db.get_summary_stats()
A new third tab in the Streamlit app merges supplier records with related news article metrics so you can evaluate risk using both structured supplier data and unstructured news content.
When you open the Combined Insights tab you will see:
This tab makes it easy to spot suppliers whose inherent profile is concerning and are being mentioned in risky news items.
You can also access this functionality programmatically:
from database import SupplierDatabase
from news_database import NewsDatabase
sup_db = SupplierDatabase()
news_db = NewsDatabase()
suppliers = sup_db.get_all_suppliers()
news_stats = news_db.get_supplier_news_stats() # returns stats keyed by supplier name
# merge data manually if you need custom reports
combined = []
for sup in suppliers:
name = sup["name"]
stats = news_stats.get(name, {})
combined_score = None
if stats:
combined_score = (sup["risk_score"] + stats["avg_score"]) / 2
combined.append({
"name": name,
"supplier_score": sup["risk_score"],
"news_avg_score": stats.get("avg_score"),
"combined_score": combined_score,
})
Use combined for further analysis or reporting.
streamlit run app.py
This will open the web app where you can:
python supplier_news_risk.py
This will score a sample article and print results showing the risk score and breakdown.
python test_database.py
This will verify that the database is working correctly and create a test database file.
The AI is like a hyperintelligent, always-on news scanner for your suppliers that:
No magic, no secrets—just smart pattern matching and keyword counting, powered by modern machine learning.