# Guidance

Build *guidance prompts* to effectively control language models to accomplish specific tasks.

## Install

```python
pip install guidance
```

## Getting started

**Note the guidance package is in alpha, and so syntax may change.**

Guidance prompts allow you to specifcy the structure of your prompt through a simple templating syntax, then compile those into a form that can be executed via a large language model API. 

```python
import guidance

guidance.default_generator = guidance.generators.OpenAI(model="text-davinci-002", token=TOKEN)

# define a guidance prompt
prompt = guidance.Prompt('''Use the following statements to answer the query "{{query}}".
STATEMENTS{{#each statements}}
- {{this}}{{/each}}
---
Answer the query "{{query}}":{{generate 'answer'}}''')

# execute the prompt
completion = prompt(
    query="What fruits does Joe like?",
    statements=["Joe likes Apples", "Joe dislikes Oranges", "Sue likes Bananas"]
)

print("The answer is", completion["answer"])

# display the completion in a notebook environment
completion
```
<img width="567" src="https://raw.githubusercontent.com/slundberg/guidance/master/docs/artwork/demo_output.png" />

## Template syntax

The guidance templating syntax should feel familar (it is an extension of Handlebars), but it is parsed differently than traditional templating libaries. Every guidance template has a linear execution order associated with it that corresponds to the order in which it is read and/or generated by the language model. This means you can both read and write using the template (as shown in the example above).

### {{variable}}
A variable name inside double curly braces is substituted directly into the prompt string. In the example above `{{query}}` interpolates the query parameter.

### {{generate 'variable'}}
The generate command can read in a chunk of text generated by the language model into a variable. For example `{{generate 'answer' max_tokens=100}}` will read in up to 100 tokens from the language model into the 'answer' variable. The prompt given to the language model with be all of the content produces by the template before the call to `{{generate 'answer'}}`. Other parameters like `temperature` and `top_p` are also supported.

### {{#if variable}} {{\if}}
Conditionals can be expressed with an opening `#if` tag and a closing `/if` tag. For example:
```python
{{#if flag_variable}}Yes{{else}}No{{\if}}
```

### {{#unless variable}} {{\unless}}
Inverted conditionals can be expressed with an opening `#unless` tag and a closing `/unless` tag just like for `#if`.

### {{#each list}} {{/each}}
Loops can be expressed with an opening `#each` tag and a closing `/each` tag. Inside a loop the special boolean variables `this`, `@first`, `@last`, and `@index` are automatically defined. Where `this` is the current element in the list.

### {{#select 'variable'}} {{or}} {{/select}}
You can force the language model to choose between a restricted set of possible completions using the `#select` command. This commands is similar to the `generate` command in that it uses the language model to generate a completion that is then stored in 'variable', but instead of an unconstrained generation, the LM must choose one of the text chunks. For example:
```python
Answer Yes/No:{{#select 'answer'}} Yes{{or}} No{{/select}}
```

### {{add val1 val2 ...}}
You can add any number of values together using the `add` function. This can be useful for example to change 0-based indexing to 1-based:
```python
{{#each statements}}
- [{{add @index 1}}] {{this}}{{/each}}
```