Part II: Discovery Through Software Engineering and Vibe Coding
Chapter 10: Prompting to Programming

Prompting to Programming

"I used to write prompts. Now I write type signatures and let a compiler argue with the language model on my behalf."

A Prompt Engineer Who Learned to Love the Schema

Overview

The previous chapter introduced vibe coding as the practice of steering AI through natural language while a model generates the code. Vibe coding is powerful, but its outputs are fragile: free-form text goes in, free-form text comes out, and any downstream system that consumes the model's response must parse, validate, and hope. This chapter shows how to replace hope with guarantees.

The core idea is simple: treat a language model call not as a chat message, but as a function call with typed inputs and typed outputs. Once you do that, an entire software engineering toolkit becomes available. You can define schemas, validate responses at compile time, compose calls into pipelines, and even optimize prompts automatically by treating them as parameters in a search problem. The journey goes from raw prompts to structured outputs, from structured outputs to typed agent interfaces, and from typed interfaces to compiled programs that optimize their own instructions.

This chapter sits at the pivot point of Part II. Everything before it (Chapters 7 through 9) treats AI as an assistant that generates code for humans to review. Everything after it (Chapters 11 through 24) treats AI as a component in engineered systems. The transition happens here, when prompts become programs.

Prerequisites

You should be comfortable with the foundations from Chapter 4 (reasoning in language models, chain-of-thought prompting) and Chapter 9 (vibe coding workflows and specification practices). Familiarity with Python type hints, dataclasses, and basic API usage (REST, JSON) is assumed. If you have used Pydantic for data validation, Section 10.1 will feel natural; if not, we introduce the essentials from scratch. The Discovery Workbench from Chapter 6 provides the scaffold that this chapter extends with typed agent interfaces.

Learning Outcomes

After completing this chapter, you will be able to:

Sections

10.1 Structured Outputs and Tool Use

JSON Schema, constrained generation, function calling, and the Model Context Protocol. How to guarantee that every LLM response is machine-readable, composable, and validated at the type level. Typed agent interfaces with Pydantic across the Anthropic SDK, OpenAI Agents SDK, and MCP.

10.2 Programmatic Prompt Optimization

DSPy signatures, predictors, and modules. Prompt optimization as discrete search over instruction space. Compiling prompts with BootstrapFewShot, MIPROv2, and quality metrics. When optimization helps and when it does not.

10.3 Building a DSPy Literature Program

Recipe: convert a brittle prompt chain into a typed, compiled DSPy program that retrieves papers, extracts claims, and synthesizes findings. Integration with the Discovery Workbench, evaluation, and deployment patterns.

What's Next

The next bottleneck is what the model sees. Chapter 11: Context Engineering at Repository Scale tackles the problem of assembling the right context window for large codebases and scientific corpora. You will learn retrieval strategies, chunking, reranking, and the art of fitting a million-line repository into a hundred-thousand-token window, using the typed interfaces from this chapter as the plumbing that connects retrieval to generation.

Bibliography

Foundational Papers

Khattab, O. et al. (2023). DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines.

The foundational DSPy paper. Introduces signatures, modules, teleprompters (optimizers), and the idea that prompt engineering should be replaced by prompt compilation. Core reading for Sections 10.2 and 10.3.

Opsahl-Ong, K. et al. (2024). Optimizing Instructions and Demonstrations for Multi-Stage Language Model Programs.

Introduces MIPROv2, DSPy's second-generation optimizer that jointly searches over instructions and demonstrations using Bayesian surrogate models. The optimizer of choice for production DSPy programs.

Schick, T. et al. (2023). Toolformer: Language models can teach themselves to use tools.

Demonstrates self-supervised tool-use learning, where models decide when and how to call external APIs. Conceptual ancestor of structured function calling.

Tools and Libraries

Pydantic Documentation. (2024). Pydantic v2: Data Validation Using Python Type Annotations.

The de facto standard for runtime data validation in Python. Used throughout this chapter for defining structured output schemas and agent interfaces.

Anthropic. (2024). Tool Use (Function Calling) Documentation.

Official reference for structured outputs and tool use with Claude. Covers JSON Schema constraints, tool definitions, and multi-turn tool-use patterns.

OpenAI. (2025). New Tools for Building Agents: Agents SDK and Responses API.

Introduces the OpenAI Agents SDK with typed tool definitions, handoffs, and guardrails. Reference for the multi-SDK comparison in Section 10.1.

Anthropic. (2024). Model Context Protocol (MCP) Specification.

The open standard for connecting LLMs to external tools and data sources. Section 10.1 shows how MCP tool schemas map onto structured function calling.

DSPy Project. (2024). DSPy: The Framework for Programming, Not Prompting, Foundation Models.

Official DSPy documentation and tutorials. The primary reference for the programming model in Sections 10.2 and 10.3.

Tutorials and Guides

JSON Schema. (2024). Getting Started Step by Step.

The official tutorial for JSON Schema, the constraint language underlying structured outputs in every major LLM API.

Wang, L. et al. (2024). A Survey on Large Language Model Based Autonomous Agents.

Comprehensive survey of LLM agent architectures, covering tool use, planning, memory, and multi-agent coordination. Provides the broader context for the typed agent interfaces built in this chapter.

Khattab, O. et al. (2024). DSPy Assertions: Computational Constraints for Self-Refining Language Model Pipelines.

Extends DSPy with runtime assertions that constrain LLM outputs programmatically. Shows how to build self-correcting pipelines that retry on constraint violations.