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-pybut imported asinquirein Python.
2. Set Up API Keys
Export environment variables:
export OPENAI_API_KEY="sk-..."
export TAVILY_API_KEY="tvly-..."
Get API keys:
- OpenAI: https://platform.openai.com/api-keys
- Tavily: https://tavily.com/ (for web search)
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 initto set up the project - ✅ Moves your
.bamlfiles tobaml_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
.bamlfiles in your project root are automatically moved tobaml_schemas/baml_src/to keep your project clean and avoid duplication.
How It Works
- Research Phase:
inquireuses Tavily to search the web and OpenAI to synthesize findings - Extraction Phase: Your BAML function extracts structured data from the research
- Type Safety: Returns a Pydantic model with full validation and IDE support
- 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:
- Update version in
pyproject.toml - Create a git commit and tag
- Push to GitHub
- Trigger automated publishing to PyPI via GitHub Actions
See .github/workflows/README.md for more details.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
make test - 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
inquireis 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f08e837495ad741cf36414691110b719f3bbcd4b5f13f1e8407db27a286015bf
|
|
| MD5 |
a61af01f61ecca05f042180c28a245da
|
|
| BLAKE2b-256 |
7cd120898bf5b44acdb8c988a5014b2f3c2d5f2ea86a6ffb43e79520e008e0fc
|
File details
Details for the file inquire_py-0.1.2-py3-none-any.whl.
File metadata
- Download URL: inquire_py-0.1.2-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff16ff2536d4313737b1dbfab5afc4fa9462ef246ee58d1a0dacb4986d9ecb0b
|
|
| MD5 |
24979ab6a9763939c0079bcff61b9861
|
|
| BLAKE2b-256 |
c65ca9798f8b978934daa713487baab64dd842a4a9014f55668e93e3d52dc219
|