iusztinpaul/ai-research-os-workshop/research-distill
Claude Code and agent skill by iusztinpaul/ai-research-os-workshop
- community
Checking that the SKILL.md file is still in the repository.
Distill a research directory (produced by /research) into a single compact research.md containing a guideline-relative distillation of only the sources that were actually used in a piece of content. Use this skill whenever the user wants to extract used references from research, create a research appendix for an article, distill research into what was actually cited, or produce a portable reference file from a research directory. Trigger when the user says things like "distill my research", "extract used sources", "which research did I actually use", "create research.md", "compile references from research", or after finishing an article that used a research directory.
Install
npx vskill@latest install iusztinpaul/ai-research-os-workshop/research-distillSKILL.md
Research Distill
You take a research directory (produced by /research) and a set of content files the user is working on, and produce a single research.md containing only the sources that were actually used in that content, distilled to just the claims, quotes, and nuances the content actually leans on. Every source keeps its full metadata + URI envelope so the writer agent can drill back to the wiki source page or raw file when it needs more depth.
This is the audit/export side of the research system — it answers "which sources from my research actually made it into the final content, and what specifically from each one?" The output is a working appendix sized for a writer agent's context window, not a verbatim mirror of the research directory.
Step 1 — Gather inputs
You need two things:
The content files
These are the files the user is actively working on — article guidelines, draft articles, notes, outlines, etc. The user may provide:
- A single file path (e.g.,
Projects/Content/My Article/guideline.md) - A directory path (read all
.mdfiles in it) - Multiple file paths
- A reference to "the current project" (look for article/guideline files in the current working directory)
Read all content files and concatenate their text into a single content corpus for matching.
The research directory
Locate the research directory using the same logic as /research:
- If the user provides a path, use it
- Look for
research-*/in the content's parent directory - Look in
working-dir/(the default research root, relative to where the skill is run) forresearch-*/ - If multiple exist, ask the user which one
Read index.yaml from the research directory.
Step 2 — Match sources against content
For each source in index.yaml, determine whether it was actually used in the content. A source counts as "used" if either condition is met:
Explicit references
The content mentions the source by:
- Title or partial title (e.g., "The Anatomy of an Agent Harness" or "Anatomy of an Agent Harness")
- Author name (e.g., "Mitchell Hashimoto", "Anthropic")
- URL or partial URL (e.g., "mitchellh.com", "blog.langchain.com")
- Citation number that maps to the source (e.g., "[3]" where reference 3 is this source)
- Filename reference (e.g., the
uri_highlightsoruri_fullfilename) - NotebookLM notebook title or source URL (for
notebooklmorigin sources) - GitHub repo URL, repo name, or any entry in
github_files(forgithuborigin sources). Only one source entry exists per repo — theuri_fullARCHITECTURE.md — so matching a single referenced file path is enough to include that whole entry. The module docs it links to live in the same subfolder and are available via those links, not as separate sources. - YouTube URL, video ID, title, channel, or timestamped claim reference (for
youtubeorigin sources). A timestamped mention like12:30near the video title or URL is enough to include the source.
Traceable ideas
The content contains ideas, patterns, or concepts that are clearly traceable to the source. To check this:
- Pick the best available content file for the source, in this order:
uri_highlightsif set (user-curated condensation — highest signal, smallest read)- otherwise
uri_full(the complete document — standard Obsidian notes, web seeds, and NotebookLM content land here because they have no Layer 2) - if both are
null, fall back to thesummaryinindex.yamlalone
- Extract the key ideas, specific terminology, unique frameworks, or distinctive phrasings from whichever layer you read
- Check whether those specific ideas appear (even paraphrased) in the content
Be conservative with traceable matches. Generic concepts like "agent loop" or "context window" appear in many sources — only match if the content uses a specific framing, example, or detail that's distinctive to that source. For example:
- "flush-before-discard invariant" is distinctive to the OpenClaw architecture articles
- "Ralph Loop pattern" is distinctive to the LangChain harness article
- A general mention of "ReAct" is NOT enough to match the original ReAct paper unless the content discusses specifics from it
Step 3 — Build research.md
Create research.md in the same directory as the content files. The file contains one <details> block per matched source, ordered by relevance_score descending.
File structure
Rules for building each block
- `<summary>` tag (the HTML one, child of
<details>): Source title + score in parentheses. This is what's visible when the block is collapsed. Forgithubsources, suffix the title with— GitHub reposo the origin is legible at a glance (e.g.,weave-cli — GitHub repo (score: 1.00)).
- Metadata XML tags: One tag per field from
index.yaml:
<uri_highlights>: Filename of the key-highlights file<uri_full>: Filename of the full document file, ornullif none<uri_source_page>: The Layer 1.5 wiki source page (wiki/sources/<slug>.md) if present inindex.yaml, elsenull. This is the writer agent's primary drill-down target when it needs more depth than the distilled body provides without jumping all the way to raw.<original_path>: The original vault path or URL<origin>:obsidian,readwise,web,notebooklm,github,pdf, oryoutube<relevance_score>: The numeric relevance score fromindex.yaml(1.0 = seed; otherwise derived from the researcher's high/medium tag)<tags>: Comma-separated tag list<summary>: The source summary from index.yaml<readwise_location>: (Readwise sources only)library(user manually saved) orfeed(ingested from an RSS subscription the user chose). Emit this tag only whenoriginisreadwiseand the field is present inindex.yaml.<nlm_source_id>: (NotebookLM sources only) The NLM source UUID<nlm_notebook_title>: (NotebookLM sources only) The notebook's human-readable title<github_repo_url>,<github_commit_sha>,<github_branch>,<github_files>: (GitHub sources only) Emit these whenoriginisgithub.<github_files>is a comma-separated list of the referenced file paths — surfacing it here makes the distilledresearch.mdself-contained for audit.<youtube_video_id>,<youtube_url>,<youtube_channel>,<duration_seconds>,<transcript_source>,<transcript_language>,<transcript_language_code>,<transcript_is_generated>,<timestamps_available>: (YouTube sources only) Emit these when present inindex.yaml.
- `<match_reason>`: A 1-2 sentence explanation of why this source was included — what explicit reference or traceable idea linked it to the content. This helps the user (and future agents) understand the connection.
- Distilled body: Replace the source's prose with a guideline-relative distillation. Each block has up to four subsections — emit any subsection only if it has content for this source; omit it entirely otherwise. Do not reproduce the raw layer verbatim; the URI tags above already point at it.
#### Subsections
- `### Relevant Claims` — One bullet per specific claim, datum, framing, or example from the source that the content draws on (or directly supports). Each bullet is one line, ≤30 words, concrete. Generic concepts the source shares with many others ("uses an agent loop", "RAG matters") never earn a bullet — only source-distinctive content does. If the source contributes nothing the content actually leans on beyond an explicit citation, this subsection can be a single bullet naming what was cited.
- `### Verbatim Quotes` — Up to ~3 short quotes preserved byte-for-byte (punctuation, casing, ellipses included), rendered as Markdown blockquotes. Only include quotes the guideline plausibly cites or that anchor a distinctive framing the writer agent might want to reproduce. This is the only lossless element of the body — it exists so the writer never round-trips to raw just to cite a phrase. When uncertain about exact wording, prefer pulling the phrase as a quote rather than paraphrasing it into a Relevant Claims bullet.
- `### Nuances` — Caveats, counter-positions, edge cases, scope limits, or qualifications from the source that the guideline depends on or could miss without. Skip the subsection if none apply.
- `### Wiki Pointers` — Paths (relative to the research dir) of
wiki/concepts/<slug>.md,wiki/entities/<slug>.md,wiki/comparisons/<a>-vs-<b>.md, orwiki/questions/<file>.mdpages that exist on disk and are relevant to this content via this source. One bullet per pointer, with a one-phrase reason. These are drill-down targets, not embedded content. Skip the subsection if no relevant wiki pages exist for this source.
#### Read order for building the body
Read in this order and stop once you have enough signal to populate the subsections:
- `uri_source_page` (
wiki/sources/<slug>.md) if present — already condensed Layer 1.5 by thesource_writeragent (extended summary, key claims, quotes, connections, entities, concepts). This is the primary distillation seed. Pull claims and quote candidates from here first. - `uri_highlights` if present (Readwise-curated highlights — high signal per token, good for quote sourcing).
- `uri_full` as fallback, or to confirm exact wording for verbatim quotes.
- `summary` from
index.yamlif every layer above is missing.
Then re-read the content corpus and filter aggressively: keep only items the content actually draws on or plausibly cites. Everything else stays in the raw file, reachable via <uri_full> / <uri_source_page>.
#### Length
Soft cap ~300 words per source body (sum across all subsections). Exceed it only when nuance genuinely demands. If the only available layer is summary, the body may be just one or two bullets — that's the expected shape, not an error. Note any missing layers in <match_reason>.
#### GitHub repos
GitHub sources use the same four-subsection contract with two adjustments: rename ### Relevant Claims to ### Relevant Contracts, and rename ### Wiki Pointers to ### Module Pointers. Soft cap rises to ~500 words to accommodate the breadth across modules.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingplugins/ai-research-os/skills/research-distill/SKILL.md
Popularity
- Repository stars
- 178
- Repository forks
- 34
- 7-day trend score
- 26
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/iusztinpaul/ai-research-os-workshop/research-distill)