From wiki, Custom GPT and CLAUDE.md to a skill: distilling team knowledge

A team's knowledge is spread across docs, GPTs, CLAUDE.md files and people's heads. How to turn it into AI skills without copying dead documentation.

Cover for From wiki, Custom GPT and CLAUDE.md to a skill: distilling team knowledge

The largest file in the Illuminate skill still says it is for a Custom GPT.

It is in the header of database-structure.md, the nearly 1,600 lines describing the Blackboard Data / Illuminate schema: “Do not use, index, retrieve, or generate SQL against LEARN, CDM_CRM, or CDM_SIS for this custom GPT”. We built the skill, illuminate-sql-support, at eLearning Media, and it is packaged as a plugin; it grew out of an earlier Custom GPT that did the same job, generating and reviewing Snowflake SQL for that data warehouse. The sentence survived the migration, probably because it was in a data file and not in the instructions, which is where people usually look.

Installation details will be published on Consultas SQL para Blackboard (in Spanish) once ChatGPT accepts new skills again or once we push it to a repository.

That line sums up what happens when you turn existing knowledge into skills. The content is almost never written from scratch: it is moved from somewhere it already worked for a different reader and a different format, and it drags along leftovers from that origin. The same happens in my team’s internal plugin, with all sorts of sources. This article goes through the Illuminate case in detail and then the other usual sources, focusing on the process and on what each one forces you to change. Which content deserves to be in a skill I covered in skills as living documentation.

What the agent needs that the sources do not give it

A useful skill gives the agent three things: the rules that cannot be broken, along with their consequences; the material it needs to look up without inventing (schemas, signatures, catalogs); and the limits of what it can claim. It also needs a description that triggers it at the right moment, and a way to reach only the part of the material it needs. I go into those two pieces in how to create a skill that works.

The sources you start from rarely come in that shape. Documentation explains everything with the same weight. A CLAUDE.md takes its repository for granted. A Custom GPT is designed for a person asking questions in a separate window. And operational know-how is not written down anywhere.

From Custom GPT to skill: the Illuminate case

The move from GPT to skill was forced by the deprecation of the Illuminate GPTs, and it brought a change that has nothing to do with format. The GPT had access control: a custom action validated a token, and only people who had one could use it. The skill has been left open to everyone.

It is a consequence of moving to a skill that rarely gets discussed. A GPT lives inside a platform that lets you put a check in front of it; a skill is a folder of files that gets installed and read, and there is no point at which to validate who is using it. Whatever you package in it becomes, for all practical purposes, open knowledge. In this case that fits, because the skill does not connect to any tenant or run queries: it distributes knowledge about the schema, and the data remains behind the Snowflake access of whoever uses it. But it changes the question you review the content with. Before, it was enough to know who had a token; now you have to go file by file checking whether anyone can read all of it, and if something cannot be public, take it out of the skill and leave the control where it still exists, in the distribution channel or in data access.

A Custom GPT has instructions and knowledge files that the product itself queries when needed. Whoever uses it opens a conversation, asks for a query, copies it and takes it to their Snowflake client. A skill, on the other hand, is loaded by an agent that may be working in a repository, inside a tool like Claude Code or Codex, and that only reads the files the SKILL.md points it to.

That change of reader explains almost every decision visible in the skill.

The schema is regenerated, not copied

The database structure does not come from documentation but from an export of the current schema. The file header says so (“Generated from database export/query-1”) and adds an instruction that gives away the earlier source: “Prefer this file over older PDF-derived schema lists when there is a conflict”. There were schema lists extracted from PDFs, and the skill explicitly demotes them.

This is the most important decision in the migration. A model generating SQL fails mostly by inventing plausible table and column names, and the only defense is a schema that matches the real database. The file summarizes seven schemas with 72 views and 998 columns, and each table has its own section with types and nullability.

Derived material so the agent can search well

Alongside the schema there are two files that add no new information: they are ways of getting to it. valid-fields.txt has one line per column (CDM_LMS.COURSE.COURSE_NUMBER), 998 in total, so a name can be validated with an exact search without reading whole sections. illuminate-relations.csv indexes which tables share columns that look like keys.

Distilling for an agent includes this kind of work: generating indexes designed around how it will search. A person browses a document; an agent searches for strings.

Every source carries its level of trust

The relationships CSV is not presented as truth. The references guide clarifies that it does not include the column on the primary side or the cardinality, and that each row is “a candidate navigation hint, not a guaranteed foreign-key declaration”. Before using a join, the agent has to check the column in both tables, compare types, confirm that the business meaning fits and prefer joins that already appear in a valid example.

The SQL examples rank even lower: “Some examples are duplicated, abbreviated, incomplete, or may predate the current schema. Use them for intent and style, not object validation”. And the guide sets an order of priority for when sources disagree: current schema, field index, relationships, examples and domain notes.

This is what most clearly separates careful distillation from a dump. In a Custom GPT it is common to upload the knowledge files as they are, and the model treats them all the same. In the skill, each file says how far it can be trusted.

Not everything gets cleaned up

The notes file on tool types and semi-structured data (tool-assignment-types-stage.md) still shows signs of having been extracted from another document: it starts with “Here is a detailed breakdown of what this SQL query does” and has empty bullets before the list they should introduce. It is in the skill because it contains something that is nowhere else, how to access the JSON keys in the STAGE column, and the guide labels it as domain notes whose keys “are payload keys, not physical database columns”.

It is a reasonable decision. Rewriting that file would not change what the agent needs from it, and the router already limits its use to one specific task. Distilling does not require polishing everything; it requires knowing what role each piece plays.

What did not exist in the GPT, or was not needed

Some parts of the skill respond directly to the new context. The limit written at the start (“It does not authenticate users, connect to an Illuminate tenant, inspect live data, execute queries…”) matters more when the agent has access to a terminal and might try to run something. The mandatory cost warning for any query on CDM_TLM, which can scan a lot of event data and consume Illuminate credits, separates a fact about the system (the cost) from a policy (always warn). And the plugin includes an agents/openai.yaml for Codex: the same skill folder works in more than one tool, something a Custom GPT does not allow.

The other sources: wiki, CLAUDE.md, documentation and operations

The Illuminate case is one type of source. There are other common ones, and each demands different work.

CLAUDE.md files are already written for a model, but for a specific repository, and they are always loaded. If you gather the ones from several projects, you usually find repeated text with small differences. Distilling them means keeping what they share in a skill and leaving only the project-specific parts in each CLAUDE.md, and deciding, when two repos disagree, which of them reflects the actual convention.

A wiki is written for people, with context, history and decisions that no longer apply. What you can salvage from it are the decisions still in force, and to know which ones those are you have to check them against the code. A convention nobody has verified against the repositories is an opinion, and an agent applies it as if it were a rule.

A vendor’s official documentation involves two jobs of its own. You have to extract the decisions from explanations that all carry the same weight, and separate what the vendor says from what the team decides, marking each one. If the documentation has errata or contradictions, the skill should record them together with the version in use, because otherwise the agent will copy the error.

Operations (deployments, pipelines, incidents) is the source that contributes the most new knowledge, because it was never written down. Two formatting decisions make it useful: writing errors exactly as they appear, because that is how they reach the agent, and marking unknown values as “to be confirmed” so the agent asks for them instead of inferring them. This kind of skill fits with something we see at work: we use n8n for automations less and less, because with AI a script gets written quickly and deployed dockerized. A skill that knows how to do it in our environment is what makes that script come out right the first time.

The process that repeats

Whatever the source, the route to the skill has the same steps, although each source weighs more heavily on one of them:

  1. Identify the source of truth and regenerate from it whatever you can (a schema from the database, not from a PDF).
  2. Separate rules, reference material and limits. Rules go into the SKILL.md with their consequences; material goes into references.
  3. Label each reference with its level of trust and set which source wins when they disagree.
  4. Generate the indexes the agent needs to search, even if they add no new information.
  5. Mark what is not known and separate what the vendor says from what the team decides.
  6. Look for leftovers from the origin (paths, project names, “this custom GPT”) in the data files too, not just in the instructions.
  7. Write the description last, based on real requests, not on the title of the topic.

How those skills are then packaged alongside commands and hooks is in the article on Claude Code plugins, and the overall map is in the agent skills guide.

The question that remains open

Distilling a skill separates it from its source, and the source keeps changing. The Illuminate schema will change with product versions, and the skill will only be reliable as long as its export matches the real database. The field index and the relationships CSV depend on that same schema, so any regeneration has to carry all three files along.

For a schema, the answer seems clear: automate the export and regenerate the derived files on every change. For a team convention or a deployment procedure there is no export possible, and I am not sure what should trigger the review. What I do know is that a distilled skill with nobody maintaining it ends up being exactly the dead documentation you wanted to avoid, with the added problem that the agent follows it to the letter.

OshyTech

Backend and data engineering focused on scalable systems, automation, and AI.

Navigation

Copyright 2026 OshyTech. All Rights Reserved