Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Execute Exa findSimilar, getContents, answer, and streaming answer workflows. Use when finding pages similar to a URL, retrieving content for known URLs, or getting AI-generated answers with citations. Trigger with phrases like "exa find similar", "exa get contents", "exa answer", "exa similarity search", "findSimilarAndContents".
.claude/skills/jeremylongshore-exa-core-workflow-b/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 73% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 87% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 81% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 33% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 62% | 0% |
Secondary Exa workflow covering three endpoints beyond search: findSimilar (discover pages semantically related to a URL), getContents (retrieve text/highlights for known URLs), and answer (get AI-generated answers with web citations). These complement the primary search workflow in exa-core-workflow-a.
exa-js installed and EXA_API_KEY configuredexa-core-workflow-a search patternstypescriptimport Exa from "exa-js"; const exa = new Exa(process.env.EXA_API_KEY); // findSimilar takes a URL (not a query string) and returns // pages with semantically similar content const similar = await exa.findSimilar( "https://openai.com/research/gpt-4", { numResults: 10, excludeSourceDomain: true, // exclude openai.com from results startPublishedDate: "2024-01-01T00:00:00.000Z", excludeDomains: ["reddit.com", "twitter.com"], } ); for (const r of similar.results) { console.log(`${r.title} — ${r.url}`); }
typescript// findSimilarAndContents combines similarity search + content extraction const results = await exa.findSimilarAndContents( "https://huggingface.co/blog/llama3", { numResults: 5, text: { maxCharacters: 2000 }, highlights: { maxCharacters: 500, query: "open source LLM" }, excludeSourceDomain: true, } ); for (const r of results.results) { console.log(`## ${r.title}`); console.log(`URL: ${r.url}`); console.log(`Highlights: ${r.highlights?.join(" | ")}`); console.log(`Text preview: ${r.text?.substring(0, 300)}...\n`); }
typescript// getContents retrieves page content for a list of URLs you already have // Useful when you have URLs from a previous search or external source const contents = await exa.getContents( [ "https://arxiv.org/abs/2401.00001", "https://arxiv.org/abs/2401.00002", "https://blog.example.com/article", ], { text: { maxCharacters: 3000 }, highlights: { maxCharacters: 500 }, summary: { query: "key findings and methodology" }, livecrawl: "preferred", // try fresh, fall back to cache livecrawlTimeout: 15000, // 15s timeout // Subpage crawling: retrieve linked pages from each URL subpages: 3, // crawl up to 3 subpages per URL subpageTarget: "documentation", // find subpages matching this term } ); for (const r of contents.results) { console.log(`${r.title}: ${r.text?.length || 0} chars`); if (r.summary) console.log(`Summary: ${r.summary}`); }
typescript// answer() searches the web and returns an AI-generated answer with sources const answer = await exa.answer( "What are the key differences between RAG and fine-tuning for LLMs?", { text: true, // The answer response includes citations linking to source results } ); console.log("Answer:", answer.answer); console.log("\nSources:"); for (const r of answer.results) { console.log(` - ${r.title}: ${r.url}`); }
typescript// streamAnswer returns chunks as they're generated for await (const chunk of exa.streamAnswer( "What is the current state of quantum computing in 2025?" )) { if (chunk.content) { process.stdout.write(chunk.content); } if (chunk.citations) { console.log("\n\nCitations:", JSON.stringify(chunk.citations, null, 2)); } }
| Error | HTTP Code | Cause | Solution | |-------|-----------|-------|----------| | INVALID_URLS | 400 | Malformed URLs in getContents | Validate URLs have protocol | | CRAWL_NOT_FOUND | 404 | Content unavailable at URL | Verify URL is accessible | | CRAWL_TIMEOUT | 504 | Live crawl exceeded timeout | Increase livecrawlTimeout | | SOURCE_NOT_AVAILABLE | 403 | Paywalled or blocked content | Try without livecrawl: "always" | | UNABLE_TO_GENERATE_RESPONSE | 501 | Insufficient data for answer | Rephrase query or add context | | Empty similar.results | 200 | Seed URL not indexed | Try a more popular seed URL |
typescriptasync function findCompetitors(companyUrl: string) { // Find companies similar to a given company const similar = await exa.findSimilarAndContents(companyUrl, { numResults: 10, excludeSourceDomain: true, text: { maxCharacters: 500 }, category: "company", }); return similar.results.map(r => ({ name: r.title, url: r.url, description: r.text?.substring(0, 200), })); }
typescriptasync function enrichUrls(urls: string[]) { // Process URLs in batches to stay within rate limits const batchSize = 10; const allContents = []; for (let i = 0; i < urls.length; i += batchSize) { const batch = urls.slice(i, i + batchSize); const contents = await exa.getContents(batch, { text: { maxCharacters: 1500 }, summary: { query: "main topic and key points" }, }); allContents.push(...contents.results); } return allContents; }
For common errors, see exa-common-errors. For SDK patterns, see exa-sdk-patterns.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 12,049 | 15,053 | +25% | 1 | 1 | 0% | 1,885 | 3,269 | +73% | 0 | 0 | — |
case-02 | fail→pass | 8,405 | 4,566 | -46% | 1 | 1 | 0% | 1,274 | 2,384 | +87% | 0 | 0 | — |
case-03 | pass→pass | 7,086 | 3,642 | -49% | 1 | 1 | 0% | 1,249 | 2,339 | +87% | 0 | 0 | — |
case-04 | pass→pass | 7,969 | 5,920 | -26% | 1 | 1 | 0% | 1,423 | 2,941 | +107% | 0 | 0 | — |
case-05 | fail→pass | 8,554 | 5,084 | -41% | 1 | 1 | 0% | 1,569 | 2,836 | +81% | 0 | 0 | — |
case-06 | fail→pass | 12,087 | 7,481 | -38% | 1 | 1 | 0% | 2,287 | 3,033 | +33% | 0 | 0 | — |
case-07 | pass→pass | 8,317 | 5,525 | -34% | 1 | 1 | 0% | 1,580 | 2,349 | +49% | 0 | 0 | — |
case-08 | pass→pass | 4,459 | 4,087 | -8% | 1 | 1 | 0% | 722 | 2,464 | +241% | 0 | 0 | — |
case-09 | pass→pass | 13,683 | 4,531 | -67% | 1 | 1 | 0% | 1,899 | 2,549 | +34% | 0 | 0 | — |
case-10 | pass→pass | 9,753 | 10,226 | +5% | 1 | 1 | 0% | 1,460 | 3,438 | +135% | 0 | 0 | — |
case-11 | pass→pass | 15,601 | 10,640 | -32% | 1 | 1 | 0% | 2,205 | 3,650 | +66% | 0 | 0 | — |
case-12 | pass→pass | 18,228 | 13,778 | -24% | 1 | 1 | 0% | 3,024 | 3,875 | +28% | 0 | 0 | — |
case-13 | pass→pass | 7,427 | 4,432 | -40% | 1 | 1 | 0% | 1,431 | 2,683 | +87% | 0 | 0 | — |
case-14 | pass→pass | 12,813 | 6,183 | -52% | 1 | 1 | 0% | 2,076 | 2,957 | +42% | 0 | 0 | — |
case-15 | pass→pass | 6,784 | 3,845 | -43% | 1 | 1 | 0% | 1,196 | 2,426 | +103% | 0 | 0 | — |
case-16 | pass→pass | 6,907 | 3,923 | -43% | 1 | 1 | 0% | 1,356 | 2,500 | +84% | 0 | 0 | — |
case-17 | pass→pass | 7,819 | 5,227 | -33% | 1 | 1 | 0% | 1,488 | 2,764 | +86% | 0 | 0 | — |
case-18 | fail→pass | 8,101 | 4,403 | -46% | 1 | 1 | 0% | 1,609 | 2,604 | +62% | 0 | 0 | — |
case-19 | pass→pass | 6,623 | 3,281 | -50% | 1 | 1 | 0% | 1,094 | 2,208 | +102% | 0 | 0 | — |
case-20 | fail→fail | 6,302 | 7,680 | +22% | 1 | 1 | 0% | 1,170 | 2,717 | +132% | 0 | 0 | — |
case-21 | pass→pass | 11,916 | 7,881 | -34% | 1 | 1 | 0% | 1,853 | 3,271 | +77% | 0 | 0 | — |
case-22 | pass→pass | 5,131 | 3,313 | -35% | 1 | 1 | 0% | 923 | 2,169 | +135% | 0 | 0 | — |
case-23 | pass→pass | 12,093 | 6,413 | -47% | 1 | 1 | 0% | 1,900 | 2,745 | +44% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +22 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.