# Core AI Fast First Token and the Right Compute Unit: Lesson 03. Use prefill for long prompts

Lesson id: `core-ai-fast-first-token/03-prefill-and-decode-functions`
Human lesson: https://edgefde.dev/courses/core-ai-fast-first-token/03-prefill-and-decode-functions.html

## Goal

Cut first-token time on long prompts by loading and using the prefill function, and set the right options for dynamic decode.

## Prerequisites

- Lesson 02 cache handling
- A language model exported with coreai-models

## Inputs

- `.aimodel` with prefill and decode functions

## Outputs and artifacts

- Function list from `functionNames`
- `loadLMFunctions` at app idle
- `dynamicLMOptions` if the decode function has dynamic shapes
- Prefill vs decode timing log

## Steps

1. Print `model.functionNames` and confirm the prefill and decode names in the Xcode Functions tab.
2. Load both functions at app idle with `loadFunction(named:)`.
3. For prompts above one chunk, run prefill chunks first, then decode steps for the tail, following your recipe's inputs.
4. If decode has dynamic shapes, specialize and load with `expectFrequentReshapes = true`.
5. Log time for prefill and for the first decode step separately.
6. Compare first-token time for a 2,000 token prompt with and without the prefill function.

## Constraints

- Do not hard-code function names from another recipe.
- Swift only.

## Acceptance checks

- Long-prompt first-token time drops with the prefill path.
- Function load does not appear on the first user request in the trace.

## Key concepts

- Prefill reads the prompt and fills the KV cache. Decode makes tokens. The first token waits for prefill.
- coreai-models recipes can export a `prefill` function beside `main`, and Neural Engine exports use `prompt_opt_*` and `extend_*` functions.
- `loadFunction(named:)` can be expensive. Load needed functions before the first request.
- `expectFrequentReshapes` skips per-shape optimization for dynamic LLM functions.

## Takeaways

- Read function names from your export. Do not guess.
- Send long prompts through the prefill function in chunks.
- Use the same SpecializationOptions for specialize and load.
