Skip to content

Add output from simonw/llm and pgcli with gemini-2.0-flash #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions docs/llm/01_cli__click_cli_group_.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Chapter 1: cli (Click CLI group)

Welcome to the first step in your journey with `llm`! This chapter will introduce you to the `cli`, which is essentially the control panel for the entire `llm` tool. Think of it like the dashboard of a car - it's how you tell the system what to do.

**Why is a CLI important?**

Imagine you want to ask a large language model (LLM) a question, like "What are the best types of cheese for a cheese board?". Without a command-line interface (CLI), you'd have to write a whole program to interact with the LLM. The `cli` simplifies this by providing a structured way to send commands and receive answers directly from your terminal.

**Core Concept: Click CLI Group**

The `cli` in `llm` is built using a Python library called Click. Click helps create command-line interfaces that are easy to use and understand. The `cli` is organized as a *group* of commands, meaning it can perform various actions, each with its own specific instructions (or "arguments").

**Key Concepts to Understand**

1. **Commands:** These are the specific actions you can perform with `llm`. Examples include `prompt`, `keys`, `logs`, `models`, `templates`, `aliases`, `plugins`, `embed`, `embed_multi`, `similar`, `embed_models`, and `collections`. Each command has a specific purpose.

2. **Arguments:** These are the pieces of information you provide to a command so it knows *how* to execute. They come in two forms:
* **Positional Arguments:** These are required and their meaning depends on their order. For example, with `llm aliases set <alias> <model_id>`, you *must* provide the alias name first, then the model ID.
* **Options:** These are optional arguments that are specified using flags like `-m` or `--model`. Options usually have a default value if you don't specify them.

**Let's solve our use case: Asking a question**

The central use case for `llm` is asking a question to a language model. We'll use the `prompt` command to do this.

To ask "What are the best types of cheese for a cheese board?" you would type the following into your terminal:

```bash
llm "What are the best types of cheese for a cheese board?"
```

This tells the `llm` tool to use the `prompt` command, with the question itself as the main argument. The `llm` tool will then send this question to the default language model and display the answer.

Example output:

```
Here are some of the best types of cheese for a cheese board:

* Brie
* Cheddar
* Gouda
* Blue Cheese
* Goat Cheese
```

**Adding Options: Using a Specific Model**

Let's say you want to use a specific model, like `gpt-4o-mini`. You can do this using the `-m` or `--model` option:

```bash
llm -m gpt-4o-mini "What are the best types of cheese for a cheese board?"
```

Here, `-m gpt-4o-mini` tells the `prompt` command to use the `gpt-4o-mini` model instead of the default one.

**How `cli` works: A High-Level View**

When you run an `llm` command, here's what happens behind the scenes:

1. **Parsing Arguments:** The `cli` uses Click to parse the command and its arguments (like the prompt and the model name).
2. **Calling the Correct Function:** Based on the command and arguments, the `cli` calls the appropriate function within the `llm` code. In the above examples, the relevant `prompt` function in `llm/cli.py` will be called.
3. **Displaying Results:** The function interacts with the language model, gets the response, and the `cli` displays that response in your terminal.

**Diving into the Code (Simplified)**

Let's look at a simplified version of the `prompt` command definition within `llm/cli.py`:

```python
@click.command(name="prompt")
@click.argument("prompt", required=False)
@click.option("model_id", "-m", "--model", help="Model to use")
def prompt(prompt, model_id):
"""
Execute a prompt
"""
# Simplified: Get the model
model = get_model(model_id)

# Simplified: Send the prompt to the model
response = model.prompt(prompt)

# Simplified: Print the response
print(response.text())
```

Explanation:

* `@click.command(name="prompt")`: This tells Click that this function is the code to run for the `llm prompt` command.
* `@click.argument("prompt", required=False)`: This defines a *positional* argument called "prompt". The `required=False` means the user doesn't have to provide it (but usually will).
* `@click.option("model_id", "-m", "--model", help="Model to use")`: This defines an *option* called "model". Users can specify the model using `-m` or `--model` flags. The actual name of the variable in code is `model_id`.
* The function body then gets the model, sends the prompt to the model, and prints the response.

**Internal Implementation Walkthrough**

Let's visualize how this `prompt` command works internally:

```mermaid
sequenceDiagram
participant User
participant CLI
participant LLM Core
participant Model

User->>CLI: llm "Hello, world!" -m gpt-4o-mini
CLI->>LLM Core: Parse command and arguments
CLI->>LLM Core: Call prompt(prompt="Hello, world!", model_id="gpt-4o-mini")
LLM Core->>LLM Core: model = get_model("gpt-4o-mini")
LLM Core->>Model: Initialize gpt-4o-mini model
LLM Core->>Model: prompt("Hello, world!")
Model-->>LLM Core: Response from model
LLM Core-->>CLI: Response text
CLI->>User: Display response in terminal
```

This diagram shows:

1. The user enters the command.
2. The `cli` parses the command and calls the `prompt` function in the `llm` core.
3. The `llm` core figures out the model based on the `-m` option and fetches it, initializing it if needed.
4. The prompt is passed to the model, which generates a response.
5. The response is sent back to the `cli` and displayed to the user.

**Other Useful Commands**

The `cli` provides many more commands! Here's a quick overview:

* `llm keys`: Manages API keys needed to access certain models (like OpenAI).
* `llm models`: Lists the available models.
* `llm templates`: Allows you to create and use pre-defined prompts. See [Template](06_template.md) for details.
* `llm aliases`: Lets you create shorter names for models.

**Conclusion**

The `cli` is the foundation for interacting with `llm`. It provides a structured and easy-to-use interface for running prompts, managing models, and much more. As you continue through the tutorial, you'll explore the individual commands and options in greater detail.

Now that you have a grasp of the `cli`, let's move on to understanding the concept of a [Prompt](02_prompt.md).


---

Generated by [AI Codebase Knowledge Builder](https://github.com/The-Pocket/Tutorial-Codebase-Knowledge)
169 changes: 169 additions & 0 deletions docs/llm/02_prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Chapter 2: Prompt

In the previous chapter, [cli (Click CLI group)](01_cli__click_cli_group_.md), you learned how to use the command-line interface (`cli`) to interact with `llm`. Now, we'll dive into the heart of that interaction: the `Prompt`.

Imagine you're at a restaurant. The `cli` is like the waiter, and the `Prompt` is your order. You need to clearly specify what you want so the kitchen (the Large Language Model, or LLM) can prepare the right dish (the response).

**Why do we need a `Prompt` object?**

Think about asking an LLM a question. You don't just send the question directly. You might also need to specify which LLM to use, any additional instructions, or even files to reference. The `Prompt` object bundles all of this information together in a structured way. Without it, things could get messy and the LLM might not understand what you're asking!

**Core Concepts: What's inside a `Prompt`?**

The `Prompt` object has a few key ingredients:

1. **`prompt` (The Main Text):** This is the core of your request – the actual question or instruction you want the LLM to process. Like "Summarize this article" or "Translate this sentence into French."

2. **`model` (The LLM to Use):** This specifies which Large Language Model you want to use. Think of it as choosing a chef at the restaurant. Different LLMs (like `gpt-4o-mini` or `llama-3`) have different strengths.

3. **`attachments` (Additional Files):** Sometimes you want the LLM to consider extra information, like a document or an image. These are called attachments. Imagine showing the chef a picture of the dish you want!

4. **`system` (System Instructions):** This provides high-level instructions to guide the LLM's behavior. Think of it as telling the chef your dietary restrictions or preferred cooking style. For example, "You are a helpful AI assistant."

5. **`options` (Configuration Settings):** These are extra settings that control *how* the LLM generates its response, like the maximum length of the response or how "creative" it should be. These are covered in detail in the [Options](05_options.md) chapter.

**Solving the Use Case: Asking a Question with a Specific Model**

Let's revisit our cheese board question from the last chapter. This time, we'll look at how the `Prompt` object is constructed behind the scenes when you use the `cli`.

When you run the command:

```bash
llm -m gpt-4o-mini "What are the best types of cheese for a cheese board?"
```

The `cli` creates a `Prompt` object that looks something like this (in Python-like terms):

```python
prompt_object = Prompt(
prompt="What are the best types of cheese for a cheese board?",
model=gpt_4o_mini_model, # Assume we have access to a gpt-4o-mini model object
attachments=[],
system=None,
prompt_json=None,
options={}
)
```

Explanation:

* `prompt="What are the best types of cheese for a cheese board?"`: This sets the main question.
* `model=gpt_4o_mini_model`: This specifies that we want to use the `gpt-4o-mini` model. The `cli` figures out which model you meant based on the `-m gpt-4o-mini` option.
* `attachments=[], system=None, prompt_json=None, options={}`: We're not using any attachments, system instructions, or special options in this case.

The `cli` then passes this `prompt_object` to the `Model` object (we'll learn more about [Model](03_model.md) in the next chapter) to generate a response.

**Adding System Instructions**

Let's say we want to tell the LLM to respond in a funny way. We can use the `--system` option (via the `cli` or when constructing the `Prompt` object directly if writing Python code):

```bash
llm --system "Respond in the style of a pirate." "What are the best types of cheese for a cheese board?"
```

Now the `Prompt` object would look like this:

```python
prompt_object = Prompt(
prompt="What are the best types of cheese for a cheese board?",
model=default_model, # Assuming the default model is being used
attachments=[],
system="Respond in the style of a pirate.",
prompt_json=None,
options={}
)
```

The LLM should now respond in a pirate-like tone!

Example output:

```
Ahoy, matey! For a cheese board fit for a pirate, ye'll be wantin' these:

* Cheddar, aged like buried treasure!
* Brie, smooth as calm waters.
* Gouda, round like a doubloon!
```

**Internal Implementation Walkthrough**

Let's see what happens under the hood when the `cli` uses the `Prompt` object:

```mermaid
sequenceDiagram
participant User
participant CLI
participant LLM Core
participant Model

User->>CLI: llm "Tell me a joke." -m gpt-4o-mini
CLI->>LLM Core: Parse command, create Prompt object
LLM Core->>Model: model.prompt(prompt_object)
Model->>Model: Execute prompt using LLM API
Model-->>LLM Core: Response from LLM
LLM Core-->>CLI: Response text
CLI->>User: Display response in terminal
```

Here's the breakdown:

1. The user enters a command with a prompt and, optionally, a model choice.
2. The `cli` parses the command and creates a `Prompt` object, packaging the prompt text, model ID, and any other options.
3. The `cli` calls the `prompt` method on the selected [Model](03_model.md) (like `gpt-4o-mini`).
4. The `Model` object then interacts with the actual LLM API to get a response based on the information provided in the `Prompt` object.
5. Finally, the LLM's response is displayed to the user.

**Code Example (Simplified)**

Here's a simplified view of how the `Prompt` object is used within the `llm` code (referencing the `llm/models.py` file):

```python
@dataclass
class Prompt:
prompt: str
model: "Model" # type: ignore
attachments: Optional[List[Attachment]]
system: Optional[str]
options: "Options" # type: ignore

# ... later in the code ...

class Model(ABC):
# ...
def prompt(
self,
prompt: str,
*,
attachments: Optional[List[Attachment]] = None,
system: Optional[str] = None,
stream: bool = True,
**options
):
return self.response(
Prompt(
prompt,
attachments=attachments,
system=system,
model=self,
options=self.Options(**options),
),
stream=stream,
)
```

Explanation:

* The `Prompt` class (using `@dataclass`) clearly defines the structure of a prompt object, including the prompt text, model, attachments, system instructions, and options. The `type: ignore` comments are for static type checking and can be ignored for understanding the core concepts.
* The `Model.prompt` method creates a `Prompt` object using the provided arguments and then calls the `response` method (returning a [Response](04_response.md) object, which we'll explore in a future chapter). This illustrates how the `Prompt` object is constructed and then passed to the model for processing.

**Conclusion**

The `Prompt` object is a container that holds all the information needed to get a response from a Large Language Model. It ensures that your requests are structured and clear, allowing you to get the most out of `llm`.

In the next chapter, we'll explore the [Model](03_model.md) object, which is responsible for actually interacting with the LLM and generating the response based on the `Prompt`.


---

Generated by [AI Codebase Knowledge Builder](https://github.com/The-Pocket/Tutorial-Codebase-Knowledge)
Loading