Custom GPT, five minutes.
A Custom GPT reads its attached Knowledge files when its Instructions tell it to. So you do two things: upload the SKILL.md files as Knowledge, and paste a short routing block into Instructions that points the model at them. After that, ask a question and it works the case the way the skill says to.
What you'll upload.
Unzip the bundle from your dashboard. The skill files you want live one folder deep, each in its own directory:
osint-foundations-2026/
└── osint-foundations/
└── skills/
├── seed-discovery-from-email/SKILL.md ← upload these
├── ssl-certificate-pivoting/SKILL.md
├── username-enumeration-across-platforms/SKILL.md
└── …You want the SKILL.md files themselves. The optional references/, scripts/, and assets/ subfolders are extras — attach a reference file too if a skill leans on it, but the SKILL.md is the methodology.
Build the GPT.
Pick your skills
SKILL.md files for the case types this GPT should handle. Keep them under the 20-file Knowledge limit (see the note below) — a themed GPT beats a kitchen-sink one.Create the GPT & upload Knowledge
Go to ChatGPT → Explore GPTs → Create, open the Configure tab, and under Knowledge click Upload files. Add each SKILL.md you selected.
Rename files to something self-describing before uploading if they all read SKILL.md — e.g. ssl-certificate-pivoting.md. It makes the routing block in step 3 land more reliably.
Paste the routing block into Instructions
In the Instructions field, paste this (edit the bracketed line to name your skills):
You are an investigation assistant. Attached to your Knowledge are skill files (SKILL.md) — each is a methodology for one investigative task, with a "when to use" header, numbered steps, and stop-points. On every request: 1. Identify which attached skill(s) the task matches. 2. Open and FOLLOW that skill's methodology step by step. Do not improvise an order it doesn't describe. 3. Honor every stop-point and jurisdictional limit it names. 4. Cite each finding to a source, with a timestamp and a confidence grade. Never invent a source. If no attached skill fits, say so before proceeding. Available skills: [seed-discovery-from-email, ssl-certificate-pivoting, username-enumeration-across-platforms]
Save & test
Save the GPT, then give it a real task and watch it cite the skill:
> Work up jane.doe@example.com. GPT: Applying seed-discovery-from-email. Phase 1 — Confirm the address … Phase 2 — Pivot to personas … (each finding: source · timestamp · confidence)
A Custom GPT consults Knowledge files via retrieval, not by loading all of them into every prompt. Naming the skill in your request (or keeping the GPT themed to a few skills) makes it reliably pull the right one. If it answers without naming a skill, remind it: "use the attached skill for this."
The 20-file ceiling.
OpenAI caps Knowledge at 20 files per GPT. A full bundle has more skills than that, so don't try to load everything into one GPT. Two clean ways around it:
- AThemed GPTs. One GPT per case type — a "Domain Attribution" GPT with the infrastructure skills, a "Person Workup" GPT with the people skills. Each stays well under 20 files and routes more sharply.
- BMerge into combined files. Concatenate related skills into one Markdown file (keep each skill's frontmatter header as a section divider) so several methodologies count as a single Knowledge file.
Pick skills to fit the GPT, not the catalog.
Don't bulk-upload 600 skills hoping retrieval sorts it out — it won't, and you'll blow the file limit. Choose the handful of skills the GPT actually needs for its job, name them in the routing block, and spin up a second themed GPT when the next case type comes along.
