agentsclimarketplace

Mixedbread search

Skill mixedbread-ai/skills/skills/mixedbread-search

Agent skills for search, RAG, and document parsing with Mixedbread. Install with: npx skills add mixedbread-ai/skills

Install
npx -y skills add mixedbread-ai/skills --skill mixedbread-search

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Build and query managed search indexes (Stores) using the Mixedbread Python and TypeScript SDKs. Use when creating knowledge bases, uploading documents, performing semantic or vector search, asking questions over documents, using agentic multi-step retrieval, combining store search with web results, filtering by metadata, reranking, or discovering metadata facets.

SKILL.md

20.5 KB, as published. Nobody here has run it

Mixedbread Search

Create and search managed knowledge bases using the Stores API. Stores are multimodal search indexes that handle text, images, tables, audio, and video across 100+ languages.

Docs: https://www.mixedbread.com/docs/stores/overview.md Agent-readable docs: https://www.mixedbread.com/docs/llms.txt Latest docs search: https://www.mixedbread.com/question?q=stores&section=docs

Setup

pip install mixedbread          # Python
npm install @mixedbread/sdk     # TypeScript
export MXBAI_API_KEY=your_api_key

Quick Start

Python:

import os
from mixedbread import Mixedbread

mxbai = Mixedbread(api_key=os.environ["MXBAI_API_KEY"])

store = mxbai.stores.create(name="my-docs", description="Product documentation")

mxbai.stores.files.upload(
    store_identifier=store.id,
    file=open("guide.pdf", "rb"),
    metadata={"category": "guides", "version": "2.0"},
)

results = mxbai.stores.search(
    query="How does authentication work?",
    store_identifiers=["my-docs"],
    top_k=5,
)
for chunk in results.data:
    print(f"{chunk.score:.3f} | {chunk.filename}: {chunk.text[:100]}")

TypeScript:

import { Mixedbread } from '@mixedbread/sdk';
import fs from 'fs';

const mxbai = new Mixedbread({
    apiKey: process.env.MXBAI_API_KEY!,
});

const store = await mxbai.stores.create({
    name: 'my-docs',
    description: 'Product documentation',
});

await mxbai.stores.files.upload({
    storeIdentifier: store.id,
    file: fs.createReadStream('guide.pdf'),
    body: { metadata: { category: 'guides', version: '2.0' } },
});

const results = await mxbai.stores.search({
    query: 'How does authentication work?',
    store_identifiers: ['my-docs'],
    top_k: 5,
});

Decision Tree

  • What kind of retrieval do you need?
    • Simple keyword/semantic lookup → Standard search() with top_k
    • Natural-language answer with citations → question_answering() (citations are on by default)
    • Complex multi-hop question → search() with agentic enabled
    • Exact token/regex match (error codes, identifiers, literal phrases) → POST /v1/stores/grep. See Grep and Chunk Listing.
    • Combine internal docs with live web → Add "mixedbread/web" to store_identifiers
  • Do you need metadata filtering?
    • Don't know what metadata exists → Call metadata_facets() first
    • Know the fields → Build filters with all/any/none combinators
  • Do you need higher relevance?
    • Yes → Set "rerank": true in search_options (uses the default model, mixedbread-ai/mxbai-rerank-v3-listwise), or pass a config object: {"rerank": {"model": "...", "with_metadata": true, "top_k": 10}} to choose a model, include metadata in reranking, or cap post-rerank results.
  • Do you need OCR, summaries, or transcriptions from files?
    • Yes → Upload files with config: {"parsing_strategy": "high_quality"}. Stores auto-extract OCR text, summaries, and transcriptions — no separate parsing needed. For PDFs, slides, Word documents, and images, chunks additionally carry per-page layout in generated_metadata.layout: each detected element with its bounding box ([x1, y1, x2, y2] in page-image pixels), element type, and OCR text, in reading order.
    • No / text-only documents → Default parsing_strategy ("fast") is sufficient.
  • Does the user's query language overlap with metadata fields (titles, categories, authors)?
    • Yes → Enable contextualization at store creation so embeddings carry that metadata. See Contextualization.
    • No → Leave it off (the default).
  • Do you need the exact stored chunks for a known file (not a query)?
    • Yes → Call stores.files.retrieve() with return_chunks=True (or a list of indices). See Retrieve Chunks by File.
    • No, you want relevance ranking → Use search().
  • Is the store temporary (e.g., PR review)?
    • Yes → Set expires_after with a day limit at creation

Workflows

Build a Searchable Knowledge Base

Create a store, upload documents, and search. Most of the time you do not need to poll for finished files. Only gate on processing when the workflow depends on complete batch coverage, such as benchmarks or recall evaluation.

Python:

store = mxbai.stores.create(
    name="product-docs",
    description="Product documentation",
    config={"contextualization": {"with_metadata": ["title", "category"]}},
)

mxbai.stores.files.upload(
    store_identifier=store.id,
    file=open("guide.pdf", "rb"),
    metadata={"title": "Setup Guide", "category": "guides"},
)
mxbai.stores.files.upload(
    store_identifier=store.id,
    file=open("faq.md", "rb"),
    metadata={"title": "FAQ", "category": "support"},
)

results = mxbai.stores.search(
    query="How do I reset my password?",
    store_identifiers=["product-docs"],
    top_k=5,
    search_options={"rerank": True},  # file metadata is returned by default
)
for chunk in results.data:
    print(f"{chunk.score:.3f} | {chunk.filename}: {chunk.text[:100]}")

# Optional: poll store.file_counts if you need deterministic full-batch coverage (benchmarks, migrations).

TypeScript:

const store = await mxbai.stores.create({
    name: 'product-docs',
    description: 'Product documentation',
    config: { contextualization: { with_metadata: ['title', 'category'] } },
});

await mxbai.stores.files.upload({
    storeIdentifier: store.id,
    file: fs.createReadStream('guide.pdf'),
    body: { metadata: { title: 'Setup Guide', category: 'guides' } },
});
await mxbai.stores.files.upload({
    storeIdentifier: store.id,
    file: fs.createReadStream('faq.md'),
    body: { metadata: { title: 'FAQ', category: 'support' } },
});

const results = await mxbai.stores.search({
    query: 'How do I reset my password?',
    store_identifiers: ['product-docs'],
    top_k: 5,
    search_options: { rerank: true },  // file metadata is returned by default
});

// Optional: poll store.file_counts if you need deterministic full-batch coverage (benchmarks, migrations).

Filter-Driven Search

Discover available metadata, then build targeted filters.

Python:

facets = mxbai.stores.metadata_facets(store_identifiers=["product-docs"])
for key, values in facets.facets.items():
    print(f"{key}: {values}")

results = mxbai.stores.search(
    query="deployment guide",
    store_identifiers=["product-docs"],
    top_k=10,
    filters={
        "all": [
            {"key": "category", "operator": "eq", "value": "guides"},
            {"key": "status", "operator": "not_eq", "value": "archived"},
        ]
    },
    search_options={"rerank": True},
)

TypeScript:

const facets = await mxbai.stores.metadataFacets({
    store_identifiers: ['product-docs'],
});
for (const [key, values] of Object.entries(facets.facets ?? {})) {
    console.log(`${key}: ${JSON.stringify(values)}`);
}

const results = await mxbai.stores.search({
    query: 'deployment guide',
    store_identifiers: ['product-docs'],
    top_k: 10,
    filters: {
        all: [
            { key: 'category', operator: 'eq', value: 'guides' },
            { key: 'status', operator: 'not_eq', value: 'archived' },
        ],
    },
    search_options: { rerank: true },
});

Filter operators: eq, not_eq, gt, gte, lt, lte, in, not_in, like, not_like, contains, starts_with, regex. Combine with all (AND), any (OR), none (NOT).

Web-Augmented Search

Include "mixedbread/web" in store_identifiers to combine store search with live web results. This is a reserved store identifier — no setup required. You can also search the web alone.

Python:

results = mxbai.stores.search(
    query="latest best practices",
    store_identifiers=["my-docs", "mixedbread/web"],
)

TypeScript:

const results = await mxbai.stores.search({
    query: 'latest best practices',
    store_identifiers: ['my-docs', 'mixedbread/web'],
});

Contextualization

Appends selected file metadata to chunk text before embedding, so queries that overlap with fields like title, category, or author rank more accurately. Configured on the store's config.contextualization at creation time and only affects files uploaded afterward. Look up the modes (false / true / {"with_metadata": [...]}) in the Stores docs — fetch llms.txt (linked at the top of this skill) and follow the link to the Stores configuration page.

Retrieve Chunks by File

When you already know the file (preview, export, ingestion debugging) and don't need ranking, call stores.files.retrieve() with return_chunks=True (all chunks) or return_chunks=[indices] (specific chunk_index positions). For the exact request/response shape, look up the "Get Store File" endpoint in the API reference — fetch llms.txt and follow the link, or search the docs.

Grep and Chunk Listing (REST)

Two endpoints without dedicated SDK methods yet — call them over HTTP (or the SDK's generic post):

  • POST /v1/stores/grep — match chunks against an RE2 regular expression instead of semantic search. Finds chunks containing a literal token, identifier, error code, or phrase. Body: pattern (regex, up to 1024 chars), store_identifiers (exactly one store), targets (default ["text", "generated"] — original chunk text vs. ingestion-derived OCR text, transcriptions, and summaries), case_sensitive (default false), top_k, filters. No pagination — raise top_k for more matches. Response chunks come back under data.
  • POST /v1/stores/list-chunks — list chunks by metadata filters without a search query, optionally ordered by a metadata field: sort_by: "price" or ["price", false] for descending (unprefixed paths target file metadata, generated_metadata.* targets chunk metadata). Single store only.

Question Answering

Get a generated answer with cited sources. The answer may contain <cite i="n"/> tags referencing the sources list. Citations (qa_options.cite) and multimodal context (qa_options.multimodal) are both on by default. Optional top-level parameters: instructions (up to 8,000 chars) to steer answer style and focus, and stream: true to stream the answer.

Python:

result = mxbai.stores.question_answering(
    query="What are the rate limits?",
    store_identifiers=["my-docs"],
    top_k=10,
    search_options={"rerank": True},
)
print(result.answer)
for source in result.sources:
    print(f"  {source.filename} (score: {source.score:.3f})")

TypeScript:

const result = await mxbai.stores.questionAnswering({
    query: 'What are the rate limits?',
    store_identifiers: ['my-docs'],
    top_k: 10,
    search_options: { rerank: true },
});
console.log(result.answer);
for (const source of result.sources) {
    console.log(`  ${source.filename} (score: ${source.score.toFixed(3)})`);
}

Question Answering with Agentic Fallback

When QA returns no sources, retry with agentic search for deeper retrieval. Always re-call question_answering() — do not fall back to raw search(), which loses the generated answer.

Python:

result = mxbai.stores.question_answering(
    query="Compare the pricing tiers and their feature differences",
    store_identifiers=["my-docs"],
    top_k=10,
    search_options={"rerank": True},
)

if not result.sources:
    result = mxbai.stores.question_answering(
        query="Compare the pricing tiers and their feature differences",
        store_identifiers=["my-docs"],
        top_k=10,
        search_options={
            "rerank": True,
            "agentic": {"max_rounds": 3},
        },
    )

print(result.answer)
for source in result.sources:
    print(f"  {source.filename} (score: {source.score:.3f})")

Agentic Search

For complex questions requiring multi-step retrieval. The system decomposes your query into sub-queries and runs multiple rounds. Works in both search() and question_answering().

Python:

results = mxbai.stores.search(
    query="Compare the pricing tiers and their feature differences",
    store_identifiers=["product-docs"],
    search_options={
        "agentic": {
            "max_rounds": 3,
            "queries_per_round": 2,
            "instructions": (
                "Prioritize official pricing pages over blog posts. "
                "Surface tier names, monthly cost, and included feature lists."
            ),
        }
    },
)

TypeScript:

const results = await mxbai.stores.search({
    query: 'Compare the pricing tiers and their feature differences',
    store_identifiers: ['product-docs'],
    search_options: {
        agentic: {
            max_rounds: 3,
            queries_per_round: 2,
            instructions:
                'Prioritize official pricing pages over blog posts. ' +
                'Surface tier names, monthly cost, and included feature lists.',
        },
    },
});

Agentic options

  • agentic: true — enable with defaults.
  • agentic: { ... } — override individual fields:
    • max_rounds (default 3, range 1–10) — maximum retrieval rounds.
    • queries_per_round (default 4, range 1–10) — sub-queries generated per round.
    • instructions (string, up to 5000 chars) — the agent prompt input. Tells the agent how to plan and rank its searches: which entities, metrics, or source types to prioritize; what to treat as authoritative; what to ignore. The top-level query remains the user's question — use instructions for guidance that shouldn't appear in every sub-query.
    • strict_top_k (default false) — require the final chunk list to contain exactly top_k ranked chunks.
    • media_content (default "auto") — when retrieved image content is sent to the agent: "auto" only when no OCR text or summary is available, "never" disables it, "always" sends it whenever available.

When agentic is enabled, search_options.rewrite_query and search_options.rerank are ignored — the agent handles query decomposition and ranking itself.

Writing good agentic instructions

  • Prefer directive phrases ("prioritize X", "ignore Y", "treat Z as authoritative") over restating the question.
  • Name the concrete fields, metrics, or document types to surface so ranking is grounded in what you care about.
  • Keep the question itself in query; put ranking/planning guidance in instructions.

Response Shapes

Search results (search() returns):

response.data  # list of chunks
chunk.text       # str — the matched text
chunk.score      # float — relevance score (0–1)
chunk.filename   # str — source file name
chunk.file_id    # str — source file ID
chunk.store_id   # str — store the chunk belongs to
chunk.metadata   # dict — attached file metadata (returned by default; disable with return_metadata=False)
chunk.type       # str — chunk type (e.g. "text", "image_url")
chunk.image_url  # dict | None — image payload for image chunks
chunk.ocr_text   # str | None — OCR text for image-heavy chunks
chunk.summary    # str | None — auto-generated summary for image chunks (high_quality mode)
chunk.transcription # str | None — transcription for audio/video chunks (high_quality mode)
chunk.generated_metadata # dict | None — ingestion-derived metadata (page counts, dimensions, headings, ...)

In high_quality mode, PDF, slides, Word, and image chunks also expose the OCR layout in generated_metadata.layout: the page-image width/height plus elements in reading order, each with bbox ([x1, y1, x2, y2] in page-image pixel coordinates), type (e.g. table, figure, text), and the element's OCR text. Use it to highlight evidence regions or map answers back to a location on the page.

QA results (question_answering() returns):

result.answer    # str — generated answer, may contain <cite i="n"/> tags
result.sources   # list of source objects
source.filename  # str
source.score     # float
source.file_id   # str
source.text      # str — the source chunk text
source.image_url # dict | None — image payload with url/format for image chunks

Store Management

stores = mxbai.stores.list(limit=20)
for store in stores.data:
    print(store.name)

store = mxbai.stores.retrieve(store_identifier="my-docs")
print(store.file_counts)  # {"completed": 5, "in_progress": 2, "failed": 0}

mxbai.stores.delete(store_identifier="my-docs")

files = mxbai.stores.files.list(store_identifier="my-docs", limit=20)
for file in files.data:
    print(file.filename, file.status)

Rules

CRITICAL

  • Store names must be lowercase letters, numbers, hyphens, and periods only. Invalid names cause creation to fail. No spaces, underscores, or uppercase.
  • For field-level contextualization, use the documented {"with_metadata": [...]} form. The other documented modes are true (all metadata) and false (none). Dot notation is supported for nested fields.

HIGH

  • Do not block on full ingestion unless completeness matters. Stores process files asynchronously, and completed files become searchable as they finish. Most of the time, especially for interactive flows, upload and search immediately without polling. Poll file status or file_counts only when the workflow depends on complete batch coverage, such as benchmarks, migrations, or sync verification.
  • Use metadata_facets() before building filters. Don't guess metadata keys — discover them. Typos in filter keys silently return no results.
  • Enable rerank for production search. Reranking significantly improves relevance. Only skip it for latency-sensitive prototyping.
  • Use parsing_strategy: "high_quality" to enable automatic content extraction. When set in per-file config at upload time, high quality mode extracts OCR text and summaries for images, and transcriptions for audio and video. These fields are directly usable as LLM context. It also populates generated_metadata.layout on PDF, slides, Word, and image chunks — per-element bounding boxes alongside the OCR text. The default "fast" strategy indexes content without these additional extractions.
  • Use standard search for simple lookups. Agentic search adds latency from multiple retrieval rounds. Only use it for complex, multi-hop questions.

MEDIUM

  • Set expires_after for temporary stores. PR review stores, demo stores, and test stores should auto-expire to avoid accumulating unused indexes.
  • One store per knowledge domain, not per query. Stores are persistent indexes meant to be reused. Create once, search many times.
  • Use score_threshold to filter low-relevance noise. Set search_options: {"score_threshold": 0.3} to drop chunks below a minimum relevance server-side — no need to post-filter on chunk.score client-side.
  • Start with default agentic settings. Only increase max_rounds if results are insufficient.
  • Use agentic.instructions to steer retrieval, not query. Keep query as the user's natural-language question. Put "prioritize X", "ignore Y", source-type preferences, and ranking hints in search_options.agentic.instructions (up to 5000 chars).
  • Image queries only support plain semantic search. Combining an image query with rerank, rewrite_query, or agentic raises a validation error.

Troubleshooting

SymptomCauseFix
No results returnedNewly uploaded files are still processing, or the store name/query is wrongRetry after processing completes for at least one file. For completeness-sensitive runs, verify the expected files are completed before evaluating results.
No results returnedScore cutoff too highLower or remove search_options.score_threshold (or any client-side cutoff).
No results returnedWrong store_identifiersVerify the store name or ID matches exactly.
Metadata filters return nothingWrong key name or valueUse metadata_facets() to discover actual keys and values.
Slow agentic searchToo many rounds or queriesReduce max_rounds or queries_per_round. Use standard search if the query is simple.
API key errorInvalid or missing keyVerify MXBAI_API_KEY is set. Get a key at https://platform.mixedbread.com/platform?next=api-keys

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.