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
  • ✅ Copies your .baml files to baml_schemas/baml_src/
  • ✅ Generates Python types from your schemas

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/
├── company.baml                    # Your original schema
├── baml_schemas/
│   ├── baml_src/
│   │   ├── company.baml           # Copied here by inquire init
│   │   ├── 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

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.0.tar.gz (84.2 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.0-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for inquire_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 602b13813dd742f2d7e03e751e08636a8dfb5eceda74c0162bfe3de01e9de723
MD5 5f60c399eae52522aadfdc035af596b6
BLAKE2b-256 0e29632ba471824b679f1c00ef8d3178fb3d6b4a7415b426cd8a0657a832f49c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for inquire_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2dc620d748e9d35d50a98f33fd2d383420287ebab8d682e2031b6c3f08bd5681
MD5 93014a09d2739e115aea1cc53b449137
BLAKE2b-256 677d37b3eb1b3e59837bf75d785a6e270978fa70317d65f4a3b349f44d1423ea

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