You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/README.md
+46-38Lines changed: 46 additions & 38 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,11 +5,12 @@ hide:
5
5
--- -->
6
6
# Prompt Declaration Language
7
7
8
-
LLMs will continue to change the way we build software systems. They are not only useful as coding assistants, providing snippets of code, explanations, and code transformations, but they can also help replace components that could only previously be achieved with rule-based systems. Whether LLMs are used as coding assistants or software components, reliability remains an important concern. LLMs have a textual interface and the structure of useful prompts is not captured formally. Programming frameworks do not enforce or validate such structures since they are not specified in a machine-consumable way. The purpose of the Prompt Declaration Language (PDL) is to allow developers to specify the structure of prompts and to enforce it, while providing a unified programming framework for composing LLMs with rule-based systems.
8
+
LLMs will continue to change the way we build software systems. They are not only useful as coding assistants, providing snippets of code, explanations, and code transformations, but they can also help replace components that could only previously be achieved with rule-based systems. Whether LLMs are used as coding assistants or software components, reliability remains an important concern. LLMs have a textual interface and the structure of useful prompts is not captured formally. Programming frameworks do not enforce or validate such structures since they are not specified in a machine-consumable way. The purpose of the Prompt Declaration Language (PDL) is to allow developers to specify the structure of prompts and to enforce it, while providing a unified programming framework for composing LLMs with rule-based systems.
9
9
10
10
PDL is based on the premise that interactions between users, LLMs and rule-based systems form a *document*. Consider for example the interactions between a user and a chatbot. At each interaction, the exchanges form a document that gets longer and longer. Similarly, chaining models together or using tools for specific tasks result in outputs that together form a document. PDL allows users to specify the shape of data in such documents in a declarative way (in YAML), and is agnostic of any programming language. Because of its document-oriented nature, it can be used to easily express a variety of data generation tasks (inference, data synthesis, data generation for model training, etc...).
11
11
12
12
PDL provides the following features:
13
+
13
14
- Ability to use any LLM locally or remotely via [LiteLLM](https://www.litellm.ai/), including [IBM's watsonx](https://www.ibm.com/watsonx)
14
15
- Ability to templatize not only prompts for one LLM call, but also composition of LLMs with tools (code and APIs). Templates can encompass tasks of larger granularity than a single LLM call
15
16
- Control structures: variable definitions and use, conditionals, loops, functions
@@ -20,7 +21,7 @@ PDL provides the following features:
20
21
- Support for chat APIs and chat templates
21
22
- Live Document visualization
22
23
23
-
The PDL interpreter takes a PDL program as input and renders it into a document by execution its instructions (calling out to models, code, etc...).
24
+
The PDL interpreter takes a PDL program as input and renders it into a document by execution its instructions (calling out to models, code, etc...).
24
25
25
26
See below for a quick reference, followed by [installation notes](#interpreter_installation) and an [overview](#overview) of the language. A more detailed description of the language features can be found in this [tutorial](https://ibm.github.io/prompt-declaration-language/tutorial).
Most examples in this repository use IBM Granite models on [Replicate](https://replicate.com/).
52
53
In order to run these examples, you need to create a free account
53
54
on Replicate, get an API key and store it in the environment variable:
54
-
-`REPLICATE_API_TOKEN`
55
+
56
+
-`REPLICATE_API_KEY`
55
57
56
58
In order to use foundation models hosted on [watsonx](https://www.ibm.com/watsonx) via LiteLLM, you need a watsonx account (a free plan is available) and set up the following environment variables:
59
+
57
60
-`WATSONX_URL`, the API url (set to `https://{region}.ml.cloud.ibm.com`) of your watsonx instance. The region can be found by clicking in the upper right corner of the watsonx dashboard (for example a valid region is `us-south` ot `eu-gb`).
58
61
-`WATSONX_APIKEY`, the API key (see information on [key creation](https://cloud.ibm.com/docs/account?topic=account-userapikey&interface=ui#create_user_key))
59
62
-`WATSONX_PROJECT_ID`, the project hosting the resources (see information about [project creation](https://www.ibm.com/docs/en/watsonx/saas?topic=projects-creating-project) and [finding project ID](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-project-id.html?context=wx)).
@@ -84,7 +87,7 @@ The PDL repository has been configured so that every `*.pdl` file is associated
84
87
85
88
The interpreter executes Python code specified in PDL code blocks. To sandbox the interpreter for safe execution,
86
89
you can use the `--sandbox` flag which runs the interpreter in a Docker-compatible container. Without this flag, the interpreter
87
-
and all code is executed locally. To use the `--sandbox` flag, you need to have a Docker daemon running, such as
90
+
and all code is executed locally. To use the `--sandbox` flag, you need to have a Docker daemon running, such as
88
91
[Rancher Desktop](https://rancherdesktop.io).
89
92
90
93
The interpreter prints out a log by default in the file `log.txt`. This log contains the details of inputs and outputs to every block in the program. It is useful to examine this file when the program is behaving differently than expected. The log displays the exact prompts submitted to models by LiteLLM (after applying chat templates), which can be
@@ -108,10 +111,10 @@ This can also be done by passing a JSON or YAML file:
108
111
pdl --data-file <JSON-or-YAML-file> <my-example>
109
112
```
110
113
111
-
The interpreter can also output a trace file that is used by the Live Document visualization tool (see [Live Document](#live_document)):
114
+
The interpreter can also output a trace file that is used by the Live Document visualization tool (see [Live Document](#live-document-visualizer)):
112
115
113
116
```
114
-
pdl --trace <file.json> <my-example>
117
+
pdl --trace <file.json> <my-example>
115
118
```
116
119
117
120
For more information:
@@ -181,19 +184,19 @@ containing the source code and some information regarding the repository where i
181
184
182
185
For example, given the data in this JSON [file](https://github.com/IBM/prompt-declaration-language/blob/main/examples/code/data.yaml):
183
186
```yaml
184
-
source_code:
187
+
source_code:
185
188
|
186
189
@SuppressWarnings("unchecked")
187
190
public static Map<String, String> deserializeOffsetMap(String lastSourceOffset) throws IOException {
188
191
Map<String, String> offsetMap;
189
-
if (lastSourceOffset == null || lastSourceOffset.isEmpty()) {
190
-
offsetMap = new HashMap<>();
192
+
if (lastSourceOffset == null || lastSourceOffset.isEmpty()) {
Here is some info about the location of the function in the repo.
389
-
repo:
392
+
repo:
390
393
${ CODE.repo_info.repo }
391
394
path: ${ CODE.repo_info.path }
392
395
Function_name: ${ CODE.repo_info.function_name }
@@ -409,7 +412,7 @@ text:
409
412
"""
410
413
# (In PDL, set `result` to the output you wish for your code block.)
411
414
result = textdistance.levenshtein.normalized_similarity(expl, truth)
412
-
- data:
415
+
- data:
413
416
input: ${ CODE }
414
417
output: ${ EXPLANATION }
415
418
metric: ${ EVAL }
@@ -432,46 +435,51 @@ PDL has a Live Document visualizer to help in program understanding given an exe
432
435
To produce an execution trace consumable by the Live Document, you can run the interpreter with the `--trace` argument:
433
436
434
437
```
435
-
pdl --trace <file.json> <my-example>
438
+
pdl --trace <file.json> <my-example>
436
439
```
437
440
438
-
This produces an additional file named `my-example_trace.json` that can be uploaded to the [Live Document](https://ibm.github.io/prompt-declaration-language/viewer/) visualizer tool. Clicking on different parts of the Live Document will show the PDL code that produced that part
439
-
in the right pane.
441
+
This produces an additional file named `my-example_trace.json` that can be uploaded to the [Live Document](https://ibm.github.io/prompt-declaration-language/viewer/) visualizer tool. Clicking on different parts of the Live Document will show the PDL code that produced that part
442
+
in the right pane.
440
443
441
444
This is similar to a spreadsheet for tabular data, where data is in the forefront and the user can inspect the formula that generates the data in each cell. In the Live Document, cells are not uniform but can take arbitrary extents. Clicking on them similarly reveals the part of the code that produced them.
442
445
443
446
## Best Practices
444
447
445
448
1. **Template Organization**:
446
-
- Keep templates modular and reusable
447
-
- Use variables for dynamic content
448
-
- Document template purpose and requirements
449
+
- Keep templates modular and reusable
450
+
- Use variables for dynamic content
451
+
- Document template purpose and requirements
449
452
450
453
2. **Error Handling**:
451
-
- Validate model inputs/outputs
452
-
- Include fallback logic
453
-
- Log intermediate results
454
+
455
+
- Validate model inputs/outputs
456
+
- Include fallback logic
457
+
- Log intermediate results
454
458
455
459
3. **Performance**:
456
-
- Cache frequent LLM calls
457
-
- Use appropriate temperature settings
458
-
- Implement retry logic for API calls
460
+
461
+
- Cache frequent LLM calls
462
+
- Use appropriate temperature settings
463
+
- Implement retry logic for API calls
459
464
460
465
4. **Security**:
461
-
- Enabling sandbox mode for untrusted code
462
-
- Validate all inputs
463
-
- Follow API key best practices
466
+
467
+
- Enabling sandbox mode for untrusted code
468
+
- Validate all inputs
469
+
- Follow API key best practices
464
470
465
471
466
472
## Additional Notes
467
473
468
474
When using Granite models, we use the following defaults for model parameters (except `granite-20b-code-instruct-r1.1`):
475
+
469
476
- `decoding_method`: `greedy`, (`temperature`: 0)
470
477
- `max_new_tokens`: 1024
471
478
- `min_new_tokens`: 1
472
479
- `repetition_penalty`: 1.05
473
-
480
+
474
481
Also if the `decoding_method` is `sample`, then the following defaults are used:
0 commit comments