Python API
Python bindings for ReasonKit via PyO3.
Installation
pip install reasonkit
# Or with uv (recommended)
uv pip install reasonkit
Quick Start
from reasonkit import ReasonKit, Profile
# Initialize (uses ANTHROPIC_API_KEY from environment)
rk = ReasonKit()
# Run analysis
result = rk.think("Should I take this job offer?", profile=Profile.BALANCED)
# Access results
print(result.synthesis)
Configuration
from reasonkit import ReasonKit, Provider, Model
# Explicit configuration
rk = ReasonKit(
provider=Provider.ANTHROPIC,
model=Model.CLAUDE_3_SONNET,
api_key="sk-ant-...", # Or from env
timeout=120
)
# From config file
rk = ReasonKit.from_config("~/.config/reasonkit/config.toml")
# From environment
rk = ReasonKit.from_env()
Individual ThinkTools
GigaThink
from reasonkit.thinktools import GigaThink
gt = GigaThink(perspectives=15, include_contrarian=True)
result = gt.analyze("Should I start a business?")
for p in result.perspectives:
print(f"{p.category}: {p.content}")
LaserLogic
from reasonkit.thinktools import LaserLogic, Depth
ll = LaserLogic(depth=Depth.DEEP, fallacy_detection=True)
result = ll.analyze("Renting is throwing money away")
for flaw in result.flaws:
print(f"FLAW: {flaw.claim}")
print(f" Issue: {flaw.issue}")
BedRock
from reasonkit.thinktools import BedRock
br = BedRock(decomposition_depth=3, show_80_20=True)
result = br.analyze("How should I think about this decision?")
print(f"Core question: {result.core_question}")
print(f"First principles: {result.first_principles}")
ProofGuard
from reasonkit.thinktools import ProofGuard, SourceTier
pg = ProofGuard(
min_sources=3,
require_citation=True,
source_tier_threshold=SourceTier.TIER2
)
result = pg.analyze("8 glasses of water a day is necessary")
print(f"Verdict: {result.verdict}")
for claim in result.verified:
print(f"✓ {claim.claim}")
BrutalHonesty
from reasonkit.thinktools import BrutalHonesty, Severity
bh = BrutalHonesty(severity=Severity.HIGH, include_alternatives=True)
result = bh.analyze("I'm going to become a day trader")
for truth in result.uncomfortable_truths:
print(f"🔥 {truth}")
PowerCombo
from reasonkit import ReasonKit, Profile
rk = ReasonKit()
result = rk.think("Should I buy a house?", profile=Profile.BALANCED)
# Access individual tool results
print(f"Perspectives: {len(result.gigathink.perspectives)}")
print(f"Flaws: {len(result.laserlogic.flaws)}")
print(f"Core question: {result.bedrock.core_question}")
print(f"Verdict: {result.proofguard.verdict}")
print(f"Truths: {len(result.brutalhonesty.uncomfortable_truths)}")
# Or the synthesis
print(f"Synthesis: {result.synthesis}")
Profiles
from reasonkit import Profile
# Built-in profiles
Profile.QUICK # Fast, 2 tools
Profile.BALANCED # Standard, 5 tools
Profile.DEEP # Thorough, 6 tools
Profile.PARANOID # Maximum, all tools
# Custom profile
from reasonkit import CustomProfile, Tool, Severity
profile = CustomProfile(
tools=[Tool.GIGATHINK, Tool.BRUTALHONESTY],
gigathink_perspectives=8,
brutalhonesty_severity=Severity.HIGH,
timeout=60
)
result = rk.think("question", profile=profile)
Async Support
import asyncio
from reasonkit import ReasonKit, Profile
async def main():
rk = ReasonKit()
# Single async analysis
result = await rk.think_async(
"Should I take this job?",
profile=Profile.BALANCED
)
print(result.synthesis)
# Concurrent analyses
questions = [
"Should we launch feature A?",
"Should we launch feature B?",
"Should we launch feature C?",
]
tasks = [rk.think_async(q) for q in questions]
results = await asyncio.gather(*tasks)
for question, result in zip(questions, results):
print(f"{question}: {result.synthesis[:100]}...")
asyncio.run(main())
Output Formats
from reasonkit import Format
result = rk.think("question")
# Pretty print
print(result.format(Format.PRETTY))
# JSON
json_str = result.format(Format.JSON)
with open("analysis.json", "w") as f:
f.write(json_str)
# Markdown
md = result.format(Format.MARKDOWN)
# As dict
data = result.to_dict()
# As dataclass
from dataclasses import asdict
data = asdict(result)
Error Handling
from reasonkit import ReasonKit, ReasonKitError, ApiError, ConfigError, TimeoutError
rk = ReasonKit()
try:
result = rk.think("question")
except ApiError as e:
print(f"API error: {e}")
except ConfigError as e:
print(f"Config error: {e}")
except TimeoutError:
print("Analysis timed out")
except ReasonKitError as e:
print(f"Error: {e}")
Streaming
from reasonkit import ReasonKit
rk = ReasonKit()
# Stream results as they complete
for tool_result in rk.think_stream("question"):
if tool_result.tool == "gigathink":
print(f"GigaThink: {len(tool_result.perspectives)} perspectives")
elif tool_result.tool == "laserlogic":
print(f"LaserLogic: {len(tool_result.flaws)} flaws")
# ... etc
Context Manager
from reasonkit import ReasonKit
# Automatic cleanup
with ReasonKit() as rk:
result = rk.think("question")
print(result.synthesis)
Integration with pandas
import pandas as pd
from reasonkit import ReasonKit
rk = ReasonKit()
# Analyze multiple questions
questions = pd.Series([
"Should we invest in marketing?",
"Should we hire more engineers?",
"Should we expand to Europe?"
])
# Apply analysis
results = questions.apply(lambda q: rk.think(q).synthesis)
# Create DataFrame
df = pd.DataFrame({
"question": questions,
"analysis": results
})
Full Example
#!/usr/bin/env python3
"""Complete ReasonKit analysis example."""
from reasonkit import ReasonKit, Profile, Format
from reasonkit.thinktools import BrutalHonesty, Severity
def main():
# Initialize
rk = ReasonKit.from_env()
question = "Should I quit my job to start a business?"
# Run deep analysis
print(f"Analyzing: {question}\n")
result = rk.think(question, profile=Profile.DEEP)
# Process results
print("=== Perspectives ===")
for p in result.gigathink.perspectives[:5]: # Top 5
print(f" - {p.category}: {p.content}")
print("\n=== Logical Flaws ===")
for f in result.laserlogic.flaws[:3]: # Top 3
print(f" - {f.claim}")
print(f"\n=== Core Question ===")
print(f" {result.bedrock.core_question}")
print("\n=== Uncomfortable Truths ===")
for t in result.brutalhonesty.uncomfortable_truths[:3]:
print(f" 🔥 {t}")
print("\n=== Synthesis ===")
print(result.synthesis)
# Export
with open("analysis.json", "w") as f:
f.write(result.format(Format.JSON))
print("\nAnalysis saved to analysis.json")
if __name__ == "__main__":
main()