Live, Hands-On Case Study
From Looking It Up to Using It: An AI-Collaborated Build of a Drug Ingredient Matching Tool
If the data is already public, why build a tool? Because once you have the data, you still have to identify the drug, match it, and read the result correctly.
What the tool does
It looks up a drug’s ingredients from Taiwan Food and Drug Administration (TFDA) open data, then runs an exact match against a list the user builds themselves. It’s a front-end-only web page — the list lives only in the user’s own browser.
My role on this project
Defining requirements, breaking the work into AI tasks, reviewing what the AI produced, fixing it, deploying, and maintaining it. At runtime, the tool matches against public data using fixed rules — it does not use AI to interpret anything.

The tool is bilingual (Traditional Chinese / English). On your first visit, try the demo mode — it uses fictional drugs to show all three types of results, with no personal information required.
What Used to Be Done by Hand
The problem was never that the data couldn’t be found. TFDA license data is public — anyone can download it. The hard part is everything that comes after the download.

① Finding the data
The license number, Chinese name, and English name on the box are three separate systems. The dataset itself is a CSV of 60,000+ rows — not something you scroll through one line at a time.
② Identifying the drug
A single combination tablet can contain six or seven ingredients, and the same ingredient may appear across rows with different strengths, spellings, or salt suffixes.
③ Matching item by item
Your list has to be compared against every single ingredient. It’s the classic “one mistake causes real trouble, so no one dares automate it” workflow.
What I Was Responsible For
This tool was built through AI collaboration. To be precise: AI was used to build it; the tool does not use AI when it runs. When a user hits search, it runs a fixed data index and fixed matching rules — nothing is handed to a model to interpret. That choice determines whether results are reproducible, and whether a mistake can be traced back to its cause.
- Defining requirements and boundaries: First decide what the tool won’t do — no cross-allergy inference, no alternative-drug suggestions, no judgment on whether a drug can be taken. Those boundaries shaped every technical choice that followed.
- Breaking down the AI tasks: Splitting “build a matching tool” into smaller pieces that could each be accepted on their own — data cleaning, index building, normalization rules, interface, offline testing.
- Reviewing the output: Every piece of AI-generated code had to be read and actually run. All four issues in Section 4 below were caught at this step.
- Fixing and turning fixes into checks: After each fix, the judgment was written into an automated check so the same mistake can’t quietly come back in the next version.
- Deployment and maintenance: Launch on a custom domain, a data-update pipeline, and a review of the diff on every update.
Four Key Problems and How I Solved Them
Each one follows the same pattern: problem → how it was found → what changed → how it was verified. These four are the part that transfers to other industries.
Matching on the license number’s digits alone can point to a different drug
- Problem
- Different license types reuse the same digits. 內衛成製字第000012號 and 衛署藥製字第000012號 are two different drugs — keep only the number, and you get the wrong one.
- How it was found
- While building the index, a duplicate-key check on the primary key showed numeric keys overwriting each other at scale. The actual count: of 62,696 licenses, 35,388 fall into duplicate-number groups, with up to 11 licenses sharing the same number.
- What changed
- The full license number became the unique primary key, and no digits-only key is built. When a user types only digits, the tool always lists every candidate so they can compare against the box and choose — it never auto-selects one.
- How it was verified
- The build script stops on any duplicate primary key and lists the collisions — silent overwrites are not allowed. The index-check script prints collision-group statistics on every run.
Making users categorize their own entries hands them the blame for mistakes
- Problem
- The list originally asked users to choose “Is this an ingredient or a drug name?” Picking wrong doesn’t just look bad — the entry never gets matched at all.
- How it was found
- I picked the wrong option myself while actually using it. A field that users will get wrong can’t be rescued with helper text.
- What changed
- The category selector was removed. Every list entry is matched against all of a drug’s ingredients and its Chinese name at the same time — users just type, no categorizing first.
- How it was verified
- It’s now an automated check: no category field may appear anywhere in the interface or the code, and any violation is blocked.
Data can update automatically — but it can’t go live automatically
- Problem
- TFDA data gets updated, but an automated download might come back empty, missing columns, or even as an HTML error page. Overwriting directly means swapping good data for bad.
- How it was found
- When designing the update pipeline, I asked first: what happens if this step fails? The answer: “users get fewer ingredients back, and nobody notices.”
- What changed
- The pipeline became: download → rebuild index → structural check → old-vs-new diff with a circuit breaker → full test run → open a PR only, never auto-merge. If the license count drops past a threshold (5% by default), the pipeline fails outright; a large loss of Chinese drug names is blocked too.
- How it was verified
- It runs on a monthly schedule. A change summary (added / removed / ingredient-change counts, with samples) is attached to the PR, and a person reviews it before deciding to merge.
A bug no screenshot would reveal: ingredients starting with 0.9% didn’t match
- Problem
- A normalization rule used a word-boundary pattern, so “0.9% sodium chloride” was never reduced to “sodium chloride.” The screen looked perfectly normal, but what should have matched didn’t — the most dangerous kind of bug.
- How it was found
- By testing, one by one, real ingredients from the dataset that include a percentage strength — which showed the two forms weren’t equal after normalization.
- What changed
- The rule was fixed, and both sides — the user’s list and the drug ingredients — now go through the exact same normalization code, so the two can never drift apart.
- How it was verified
- It’s now a regression test: forms like 0.9%, 5%, and 20% must normalize to exactly the same value as the form without the strength, so this rule can’t be broken again.
These problems aren’t unique to drug data. Any job that involves repeatedly looking things up, cross-checking lists, combining different sources, or running a process where “one mistake causes real trouble” will hit similar data, interface, and update problems.
And here’s what it cost
I decided not to put search content in the URL — no query strings, nothing written to browser history. The cost: a “share these results with family” feature became impossible. It’s a real trade-off, not a best-of-both-worlds. Calls like this are even more common in business projects: convenience and data boundaries usually only let you pick one.
How It Works
① Build your list → ② Look up a drug → ③ View the match. All three steps happen on one page.

There are only three possible results, and the wording is deliberately fixed:
- Matched an ingredient on your list — prompts the user to tell their doctor or pharmacist.
- No match with the ingredients currently on your list — it only means nothing matched the list you entered; it does not mean you won’t have a reaction. The tool never says “safe” or “OK to use” here.
- No ingredient data found — unable to compare — it honestly says there’s no data, instead of filling the gap with a guess.
The third state is the easiest to leave out, but it matters most: a tool that says “I don’t know” when it isn’t sure is more trustworthy than one that always has an answer.

The appointment card is a PNG generated locally with the browser’s built-in drawing capability. It can be downloaded or printed to show healthcare staff. It contains only the names and notes the user recorded, plus the date it was generated — no lookup results of any kind. Long names wrap instead of being cut off, and long content splits across pages automatically; if it exceeds the page limit, the tool clearly suggests exporting to JSON instead of producing a card with missing content.
Current Capabilities, Limits, and Maintenance
Data Scale
| Data source | TFDA open data: license prescription ingredient details and the license master table |
| Index contents | 62,696 licenses, 7,034 ingredients, 122,645 ingredient mappings |
| Search by | Chinese drug name (including partial names), English drug name, English ingredient name, full license number |
| Loading | Index file about 8.1 MB (about 2.0 MB compressed), with a progress percentage and retry on failure |
| Languages | Traditional Chinese / English — fixed translations ship with the code; no translation API is called |
Limits (Things It Deliberately Doesn’t Do)
- No cross-allergy inference, and no extending a match on one drug to other drugs in the same class.
- No alternative-drug suggestions, no judgment on whether a drug can be taken, and no medication advice.
- Exact matches only. A partial drug name can be used to look up a drug, but it doesn’t count as an exact list match.
- Not an official TFDA service; official TFDA announcements take precedence for all drug data.
Privacy Boundaries
- The list is written only to local storage in the user’s own browser. It is never sent to any server, analytics service, or error-tracking service.
- No third-party scripts, fonts, or images; the page’s Content Security Policy allows same-origin resources only. No Google Analytics, no Meta Pixel, no ads.
- Drug names and license numbers are never written into the URL or browser history.
- All on-screen text is rendered as plain text — ingredient names in the data that contain angle brackets are shown as-is and never executed as code.
- None of this is a verbal promise: every network request was recorded with browser automation to verify it — no third-party requests, no list or search content in request URLs, no list content leaked to the console, and no query string in the address bar.
How It’s Maintained
A data update runs automatically once a month: download TFDA open data → rebuild the index → structural check → old-vs-new diff with a circuit breaker → full test run → open a PR only if something changed. No auto-merge, no direct push to production — a person always reviews the change summary first. Only the first step touches the internet; everything else runs offline.
There are currently 142 automated checks covering normalization rules, matching logic, index integrity, the download tool’s URL allowlist and decompression limit, interface copy red lines, and real interactions and network requests in a mobile browser.
Note: these are software checks. They confirm that the code’s behavior and data handling match the design — they are not medical performance validation and do not represent any clinical or professional review.
Common Questions
Q1. Does this tool use AI to determine allergies?
Q2. If there’s no match with my list, does that mean I can take the drug?
Q3. Is the allergy list I enter uploaded anywhere?
Q4. How often is the data updated? Could an update break it?
Q5. My industry has nothing to do with drugs. How is this case relevant to me?
Is There a Workflow Like This in Your Work?
The same approach works for:
- List matching that someone has to cross-check by hand every time — food allergens, regulatory items, supplier part numbers, ingredient lists.
- Internal lookup tables rebuilt regularly from public data — government open data, published lists, price or spec updates.
- Information scattered across many files that needs to be organized for colleagues — Excel files everywhere, and everyone has a different version.
- Workflows where one mistake causes real trouble, so no one has dared to automate them — what these need most isn’t speed; it’s being checkable, able to block errors, and confirmed by a person.
This tool shows how I bring public data, matching rules, and a user workflow together into a web tool people can actually use.
If your work also involves repeatedly looking things up, cross-checking lists, or organizing scattered information for colleagues, bring one concrete workflow and let’s talk. We’ll start by confirming the data sources, the use case, and the scope of delivery, then work out the right form for the tool.
Step One: Assess a Single Workflow for Tooling
You’ll get an inventory of the current workflow, a feasible scope, data requirements, and a prototype proposal. Development and maintenance are estimated after that’s confirmed. Before we talk, thinking through these four questions is enough (just describe the workflow — please don’t share any sensitive data yet):
- What do you need to look up, organize, or match right now?
- Where does the data live?
- How often is it done, and by whom?
- What result do you want at the end?
About This Tool
This tool is for personal record-keeping and communication reference only. It does not provide diagnosis, treatment, prediction, or medication decisions, and it cannot replace the judgment of a doctor or pharmacist. Please confirm your actual drug allergy list with a doctor or pharmacist before recording it in the tool. Drug data comes from Taiwan Food and Drug Administration (TFDA) open data; copyright and terms of use follow the original dataset, and official announcements take precedence. This tool is not an official TFDA service.
