Skip to main content

An open research toolkit powered by LLMs. Branch into questions through tree structures, navigate the full space of perspectives, and grid-search evaluate across prompts and models to find what works best.

Project description

spaceshift

An open research toolkit powered by LLMs. Branch into questions through tree structures, navigate the full space of perspectives, and grid-search evaluate across prompts and models to find what works best.

from spaceshift import research_tree

# Decompose a topic and generate responses for every angle
result = research_tree("What are the second-order effects of AI on labor markets?")
# Saves markdown files + tree visualization for every sub/super/side angle

Research Tree

Decompose a question, explore it from every direction, and generate responses for every node. Saves structured markdown with YAML frontmatter and a graphviz tree visualization.

from spaceshift import research_tree

result = research_tree(
    "How do general-purpose technologies reshape economic structures?",
    sub_n=[5, 3],      # 5 subtopics, each split into 3 more
    super_n=[5],        # 5 broader framings
    side_n=[3],         # 3 lateral perspectives
    search=True,        # web search for current information
)

print(result["root_output"])       # Response to the original question
print(len(result["outputs"]))     # Responses for every node in the tree
# All saved to markdown files with metadata + tree.svg visualization

Directional Prompt Exploration

Most prompt decomposition only goes downward — breaking big into small. spaceshift moves in three directions:

from spaceshift import subprompt, superprompt, sideprompt, prompt_tree

# Down — decompose into focused subtopics
subs = subprompt("What are the effects of AI on labor markets?", n=[5])

# Up — discover the bigger question this is a piece of
supers = superprompt("What are the effects of AI on labor markets?", n=[3])
# e.g. "How do general-purpose technologies reshape economic structures?"

# Sideways — explore sibling questions at the same abstraction level
sides = sideprompt("What are the effects of AI on labor markets?", n=[4])
# e.g. "What are the effects of AI on education systems?"

# All three at once, with tree visualization
tree = prompt_tree(
    "What are the effects of AI on labor markets?",
    sub_n=[5], super_n=[3], side_n=[4],
    viz=True,
)
tree["graph"].render("exploration_tree", cleanup=True)  # saves SVG

Language Transform

Route a question through another language to sample different reasoning. Not a translation utility — an exploration axis.

from spaceshift import language_transform

# Think about the question in Korean, get the answer back in English
result = language_transform(
    "What is the role of honor in modern society?",
    language="korean",
    save="honor_korean.md",
)

print(result["translated_prompt"])     # The question in Korean
print(result["translated_response"])   # Response generated in Korean
print(result["output_response"])       # That response translated back to English

Built-in languages: Chinese, Korean, Hindi, French, Arabic — or pass any language string.


Compare Models

Run the same question across multiple models, auto-evaluate and rank the responses.

from spaceshift import compare_models

result = compare_models(
    "Explain why the sky is blue",
    models=[1, 2, 3, 4, 5],               # top 5 ranked models
    save="sky_comparison",                  # saves ranked markdown files
)

print(result["top_model"])                 # which model won
print(result["rankings"])                  # full ranking
print(result["scores"])                    # normalized scores

Supports shorthand selection (1, "best", "fast3"), explicit model names ("claude-opus-4-6"), and inline reasoning effort ("gpt-5.4(xhigh)").


Grid Search

Search across models and prompt transforms simultaneously. Find the best combination.

from spaceshift import grid_search

# 4 transforms x 4 models = 16 cells + 4 original = 20 total, all evaluated
result = grid_search(
    "Explain quantum entanglement",
    models=[1, 2, 3, 4],
    n_transforms=4,                        # auto-select 4 random transforms
    save="quantum_grid",
)

print(result["top_output"])                # best response across entire grid
print(result["top_model"])                 # which model won
print(result["top_transform"])             # which transform won
print(result["grid"][:3])                  # top 3 cells with scores

Prompt Probe

Sample the output space by applying transforms to your question, generating responses for each variant, and evaluating to find the best one.

from spaceshift import prompt_probe

result = prompt_probe(
    "Explain why the sky is blue",
    n=6,                                   # try 6 random transforms
    save="sky_probe",
)

print(result["top_output"])                # best response found
print(result["top_transform"])             # which transform produced it
print(result["rankings_transforms"])       # full ranking of transforms

Pairwise Evaluate

Rank any set of LLM outputs. Uses position-swap bias mitigation, auto-generated metrics, and Bradley-Terry sampling for large sets.

from spaceshift import LLM, pairwise_evaluate

# Generate responses however you want, then evaluate
responses = [LLM(model=m).user("Explain dark matter").res() for m in [1, 2, 3]]

result = pairwise_evaluate(
    results=responses,
    metrics=["How accessible is this for a general audience?"],
)

print(result["rankings"])                  # [2, 0, 1] = third response was best
print(result["scores"])                    # normalized scores per response

Score a single response:

llm = LLM().user("Write a haiku about recursion").chat()
score = llm.evaluate_last(
    metrics={"How well does this follow 5-7-5 structure?": "1-10"}
)
print(score["score"])                      # 0.0 - 1.0

Prompt Transforms

20+ built-in transforms that reframe questions in different ways. Used internally by prompt_probe and grid_search, but available directly.

from spaceshift import prompt_transform, list_transforms

list_transforms()                          # see all available transforms

# Apply a single transform
result = prompt_transform("Explain gravity", "abstract_up")
# e.g. "Explain fundamental forces in physics"

result = prompt_transform("Explain gravity", "inverse")
# e.g. "What would a universe without gravity look like?"

Available transforms include abstraction shifts, perspective changes, dimensional manipulation, language translations, and more.


Everything Saves to Markdown

Every tool supports save= to write structured markdown with YAML frontmatter. Outputs are ranked, labeled, and organized for comparison.

# Compare models — saves ranked files: 1_claude-opus-4-6.md, 2_gpt-5.2.md, ...
compare_models("Explain dark matter", save="dark_matter")

# Research tree — saves per-node files + tree.svg visualization
research_tree("Effects of AI on education", save="ai_education")

# Grid search — saves per-cell files with transform + model in filename
grid_search("Explain gravity", save="gravity_grid")

The LLM Interface

Everything above is built on a clean, composable LLM class. One class, all providers via litellm.

from spaceshift import LLM

# Basic usage
LLM().user("Explain quantum computing").chat(stream=True)

# LLM as function — define with {placeholders}, returns parsed JSON
sentiment = LLM().sys("Classify sentiment. Return JSON with key 'sentiment'.").user("{text}")
sentiment.run("I love this product!")    # {"sentiment": "positive"}
sentiment.run(text="This is terrible")   # {"sentiment": "negative"}

# Batch processing
results = sentiment.run_batch(
    [{"text": "Love it!"}, {"text": "Terrible"}, {"text": "It's okay"}],
    concurrency=10,
)

# Model selection
LLM(model="gpt-5.2")
LLM(model="best")       # top intelligence rankings
LLM(model="fast")       # optimized for speed
LLM(model="cheap")
LLM(model="open")       # open-source models
LLM(model=1)            # top overall (default)

# Multi-turn conversation
chat = (
    LLM(model="fast")
    .sys("You are a bitcoin analyst")
    .user("What is proof of work?").chat()
    .user("Steel man the case for bitcoin mining").chat()
)

# Tool calling
def search_docs(query: str):
    """Search internal documentation."""
    return f"Found: '{query}' appears in onboarding.md"

LLM().tools(fns=[search_docs]).user("Find the onboarding guide").chat()

# Images and audio
LLM().user("What's in this image?", image="photo.jpg").chat()
LLM().user("Summarize this", audio="meeting.mp3").chat()

# Cost tracking
llm = LLM(model="best").user("Explain quantum computing").chat()
print(f"Cost: ${llm.total_cost():.6f}")

# Save, load, export
llm.save_llm("agents/researcher.json")
loaded = LLM.load_llm("agents/researcher.json")
llm.to_md("conversation.md")

Prompt queues, context compaction, web search, reasoning, vision auto-switching, and more — see the source for full capabilities.


Install

pip install spaceshift

Your access to models is based on your API keys from the various providers — keys are available for free from most providers. Create a local .env file with at least one API key:

OPENAI_API_KEY=sk-proj-...
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=AIza...
TOGETHERAI_API_KEY=...
XAI_API_KEY=xai-...

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spaceshift-1.0.0.tar.gz (60.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spaceshift-1.0.0-py3-none-any.whl (79.1 kB view details)

Uploaded Python 3

File details

Details for the file spaceshift-1.0.0.tar.gz.

File metadata

  • Download URL: spaceshift-1.0.0.tar.gz
  • Upload date:
  • Size: 60.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for spaceshift-1.0.0.tar.gz
Algorithm Hash digest
SHA256 2f6541ba611dff0c8ed23dda60eda82244854df8b50bdd833116c3d8024cfe42
MD5 638890feddf6b4697fb6a70aa2bd80f9
BLAKE2b-256 6c84598a8d9be5a2692d413ce9d0aa9cec4cf50dbba415c5c3484fcccecffb8f

See more details on using hashes here.

File details

Details for the file spaceshift-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: spaceshift-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 79.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for spaceshift-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c7541923b51be2f6e73a09273f14d5c27d7f6d5aa30bde9ff16b4577ed86ac90
MD5 5d26d45c3416f885eedef6c910df336d
BLAKE2b-256 c79dab08a5295e57def25ee274c517a305567a51de22eb781921392a12abd4b4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page