Skip to main content

Intelligent inquiry with structured results - BAML + Deep Research

Project description

inquire-py

Intelligent inquiry with structured results

Combine BAML's structured extraction with deep research capabilities to get type-safe, structured data from research queries.

Quick Start

1. Install Dependencies

# Install inquire-py
pip install inquire-py

# Install BAML CLI (required for code generation)
npm install -g @boundaryml/baml

Note: The package is installed as inquire-py but imported as inquire in Python.

2. Set Up API Keys

Export environment variables:

export OPENAI_API_KEY="sk-..."
export TAVILY_API_KEY="tvly-..."

Get API keys:

3. Create Your Schema

In your project directory, create company.baml:

class CompanyInfo {
  name string @description("Company's legal name")
  description string @description("What the company does")
  founders string[] @description("List of founder names")
  funding string | null @description("Total funding raised")
}

function ExtractCompanyInfo(research_output: string) -> CompanyInfo {
  client CustomGPT4o
  prompt #"
    Extract company information from the research output below.

    Research Output:
    {{ research_output }}

    {{ ctx.output_format }}
  "#
}

4. Initialize BAML Project

Run the initialization command:

inquire init

This automatically:

  • ✅ Creates baml_schemas/ directory structure
  • ✅ Runs baml init to set up the project
  • ✅ Moves your .baml files to baml_schemas/baml_src/
  • ✅ Generates Python types from your schemas
  • ✅ Cleans up original files to avoid duplication

You can also specify a custom directory:

inquire init --dir /path/to/schemas

5. Write Your Python Code

Create research_companies.py:

import asyncio
from inquire import research
from baml_client.types import CompanyInfo
from baml_client import b

async def main():
    result = await research(
        research_instructions="Research Stripe: founders, funding, and what they do",
        schema=CompanyInfo,
        baml_function=b.ExtractCompanyInfo
    )

    # Result is type-safe with full IDE autocomplete
    print(f"Company: {result.name}")
    print(f"Description: {result.description}")
    print(f"Founders: {', '.join(result.founders)}")
    print(f"Funding: {result.funding}")

if __name__ == "__main__":
    asyncio.run(main())

6. Run It

python research_companies.py

Project structure after inquire init:

my_project/
├── baml_schemas/
│   ├── baml_src/
│   │   ├── company.baml           # Your schema (moved here)
│   │   ├── clients.baml           # Auto-generated LLM configs
│   │   └── generators.baml        # Auto-generated settings
│   └── baml_client/               # Generated Python types
│       ├── __init__.py
│       ├── types.py
│       └── ...
└── research_companies.py          # Your Python code

Note: The original .baml files in your project root are automatically moved to baml_schemas/baml_src/ to keep your project clean and avoid duplication.

How It Works

  1. Research Phase: inquire uses Tavily to search the web and OpenAI to synthesize findings
  2. Extraction Phase: Your BAML function extracts structured data from the research
  3. Type Safety: Returns a Pydantic model with full validation and IDE support
  4. Auto-Management: BAML initialization and code generation happen automatically via BamlManager

Features

  • BAML-first - Single source of truth, no sync issues
  • Type-safe - Full IDE autocomplete and validation
  • Extensible - Multiple BAML functions per schema
  • Simple API - One function call does everything
  • Async by default - Built for modern Python async/await
  • Configurable - Customize models, search depth, and more

Advanced Usage

Multiple BAML Functions

Create different extraction functions for different use cases:

// baml_schemas/baml_src/research.baml

function ExtractBasicInfo(research_output: string) -> CompanyInfo {
  client CustomGPT4oMini  // Faster, cheaper
  prompt #"Extract basic company info from: {{ research_output }}"#
}

function ExtractDetailedAnalysis(research_output: string) -> CompanyInfo {
  client CustomGPT4o  // More detailed
  prompt #"
    You are a business analyst. Provide detailed analysis.
    {{ research_output }}
    {{ ctx.output_format }}
  "#
}

Then use different functions based on your needs:

# Quick extraction
basic = await research(
    "Research Stripe",
    schema=CompanyInfo,
    baml_function=b.ExtractBasicInfo
)

# Detailed analysis
detailed = await research(
    "Research Stripe",
    schema=CompanyInfo,
    baml_function=b.ExtractDetailedAnalysis
)

Custom Configuration

from inquire import Researcher, ResearchConfig

config = ResearchConfig(
    research_model="gpt-4o",           # Model for research synthesis
    extraction_model="gpt-4o-mini",    # Model for BAML extraction
    max_search_queries=10,             # Number of web searches
    max_iterations=5,                  # Research depth
    search_api="tavily",               # Search provider
)

researcher = Researcher(config=config)

result = await researcher.research(
    research_instructions="Research OpenAI's latest models",
    schema=ModelInfo,
    baml_function=b.ExtractModelInfo
)

Reusing Researcher Instance

For multiple queries, reuse the Researcher instance:

researcher = Researcher()

# First query
company1 = await researcher.research(
    "Research Stripe",
    schema=CompanyInfo,
    baml_function=b.ExtractCompanyInfo
)

# Second query (BAML already initialized)
company2 = await researcher.research(
    "Research Shopify",
    schema=CompanyInfo,
    baml_function=b.ExtractCompanyInfo
)

Project Structure

A typical project using inquire-py:

my_research_project/
├── baml_schemas/
│   ├── baml_src/
│   │   ├── clients.baml       # LLM configurations
│   │   ├── generators.baml    # Code generation settings
│   │   └── research.baml      # Your schemas and functions
│   └── baml_client/           # Generated (don't edit manually)
│       ├── __init__.py
│       ├── types.py
│       └── ...
├── .env                       # API keys
├── research_companies.py      # Your Python code
└── requirements.txt

Add to .gitignore:

baml_schemas/baml_client/
.env

Requirements

  • Python 3.11+
  • Node.js (for BAML CLI)
  • OpenAI API key
  • Tavily API key

Development

Running Tests

make test

Creating a Release

# Automated release (recommended)
make release VERSION=0.2.0

# Or use the script directly
./scripts/release.sh 0.2.0

This will:

  1. Update version in pyproject.toml
  2. Create a git commit and tag
  3. Push to GitHub
  4. Trigger automated publishing to PyPI via GitHub Actions

See .github/workflows/README.md for more details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run tests: make test
  5. Submit a pull request

Credits

This project builds on the excellent work of:

  • Open Deep Research - Deep research capabilities powered by LangGraph and LangChain. The research and synthesis implementation in inquire is inspired by their approach to automated research workflows.

  • BAML - Boundary ML's BAML framework provides the type-safe structured extraction layer. BAML's schema-first approach enables full type safety from definition to runtime.

Special thanks to the maintainers and contributors of these projects for creating such powerful open source tools.

License

MIT

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

inquire_py-0.1.2.tar.gz (84.3 kB view details)

Uploaded Source

Built Distribution

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

inquire_py-0.1.2-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file inquire_py-0.1.2.tar.gz.

File metadata

  • Download URL: inquire_py-0.1.2.tar.gz
  • Upload date:
  • Size: 84.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.7

File hashes

Hashes for inquire_py-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f08e837495ad741cf36414691110b719f3bbcd4b5f13f1e8407db27a286015bf
MD5 a61af01f61ecca05f042180c28a245da
BLAKE2b-256 7cd120898bf5b44acdb8c988a5014b2f3c2d5f2ea86a6ffb43e79520e008e0fc

See more details on using hashes here.

File details

Details for the file inquire_py-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for inquire_py-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ff16ff2536d4313737b1dbfab5afc4fa9462ef246ee58d1a0dacb4986d9ecb0b
MD5 24979ab6a9763939c0079bcff61b9861
BLAKE2b-256 c65ca9798f8b978934daa713487baab64dd842a4a9014f55668e93e3d52dc219

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