$git clone https://github.com/character-ai/prompt-poetPrompt Poet streamlines and simplifies prompt design for both developers and non-technical users with its low code approach. Using a mix of YAML and Jinja2, Prompt Poet allows for flexible, dynamic prompt creation, enhancing the efficiency and quality of interactions with AI mode
| 1 | [](https://pepy.tech/project/prompt-poet) |
| 2 | |
| 3 | # Prompt Poet |
| 4 | |
| 5 | Prompt Poet streamlines and simplifies prompt design for both developers and non-technical users with its low code approach. Using a mix of YAML and Jinja2, Prompt Poet allows for flexible, dynamic prompt creation, enhancing the efficiency and quality of interactions with AI models. It saves time on engineering string manipulations, enabling everyone to focus more on crafting the optimal prompts for their users. |
| 6 | |
| 7 | ### Installation |
| 8 | |
| 9 | ```shell |
| 10 | pip install prompt-poet |
| 11 | ``` |
| 12 | |
| 13 | ### Basic Usage |
| 14 | |
| 15 | ```python |
| 16 | import os |
| 17 | import getpass |
| 18 | |
| 19 | from prompt_poet import Prompt |
| 20 | from langchain import ChatOpenAI |
| 21 | |
| 22 | # Uncomment if you need to set OPENAI_API_KEY. |
| 23 | # os.environ["OPENAI_API_KEY"] = getpass.getpass() |
| 24 | |
| 25 | raw_template = """ |
| 26 | - name: system instructions |
| 27 | role: system |
| 28 | content: | |
| 29 | Your name is {{ character_name }} and you are meant to be helpful and never harmful to humans. |
| 30 | |
| 31 | - name: user query |
| 32 | role: user |
| 33 | content: | |
| 34 | {{ username}}: {{ user_query }} |
| 35 | |
| 36 | - name: response |
| 37 | role: user |
| 38 | content: | |
| 39 | {{ character_name }}: |
| 40 | """ |
| 41 | |
| 42 | template_data = { |
| 43 | "character_name": "Character Assistant", |
| 44 | "username": "Jeff", |
| 45 | "user_query": "Can you help me with my homework?" |
| 46 | } |
| 47 | |
| 48 | prompt = Prompt( |
| 49 | raw_template=raw_template, |
| 50 | template_data=template_data |
| 51 | ) |
| 52 | |
| 53 | model = ChatOpenAI(model="gpt-4o-mini") |
| 54 | response = model.invoke(prompt.messages) |
| 55 | ``` |
| 56 | |
| 57 | ### Prompt Templates |
| 58 | Prompt Poet templates use a mix of YAML and Jinja2. Template processing occurs in two primary stages: |
| 59 | |
| 60 | - Rendering: Initially, Jinja2 processes the input data. During this phase, control flow logic is executed, data is validated and appropriately bound to variables, and functions within the template are appropriately evaluated. |
| 61 | - Loading: Post-rendering, the output is a structured YAML file. This YAML structure consists of repeated blocks or parts, each encapsulated into a Python data structure. These parts are characterized by several attributes: |
| 62 | - Name: A clear, human-readable identifier for the part. |
| 63 | - Content: The actual string payload that forms part of the prompt. |
| 64 | - Role (Optional): Specifies the role of the participant, aiding in distinguishing between different users or system components. |
| 65 | - Truncation Priority (Optional): Determines the order of truncation when necessary, with parts having the same priority being truncated in the order in which they appear. |
| 66 | |
| 67 | #### Example: Basic Q&A Bot |
| 68 | ```yaml |
| 69 | - name: system instructions |
| 70 | role: system |
| 71 | content: | |
| 72 | Your name is {{ character_name }} and you are meant to be helpful and never harmful to humans. |
| 73 | |
| 74 | - name: user query |
| 75 | role: user |
| 76 | content: | |
| 77 | {{ username}}: {{ user_query }} |
| 78 | |
| 79 | - name: reply_prompt |
| 80 | role: user |
| 81 | content: | |
| 82 | {{ character_name }}: |
| 83 | ``` |
| 84 | |
| 85 | #### Interpolating Lists |
| 86 | If you have elements (e.g. messages) in a list you can parse them into your template like so. |
| 87 | ```yaml |
| 88 | {% for message in current_chat_messages %} |
| 89 | - name: chat_message |
| 90 | role: user |
| 91 | content: | |
| 92 | {{ message.author }}: {{ message.content }} |
| 93 | {% endfor %} |
| 94 | ``` |
| 95 | |
| 96 | #### Truncating Old Messages |
| 97 | Context length is limited and can’t always fit the entire chat history– so we can set a truncation priority on the message parts and Prompt Poet will truncate these parts in the order in which they appear (oldest to newest). |
| 98 | ```yaml |
| 99 | {% for message in current_chat_messages %} |
| 100 | - name: chat_message |
| 101 | role: user |
| 102 | truncation_priority: 1 |
| 103 | content: | |
| 104 | {{ message.author }}: {{ message.content }} |
| 105 | {% endfor %} |
| 106 | ``` |
| 107 | |
| 108 | #### Adapting to User Modality |
| 109 | To tailor instructions based on the user's current modality (audio or text). |
| 110 | ```yaml |
| 111 | {% if modality == "audio" %} |
| 112 | - name: special audio instruction |
| 113 | role: system |
| 114 | content: | |
| 115 | {{ username }} is currently using audio. Keep your answers succinct. |
| 116 | {% endif %} |
| 117 | ``` |
| 118 | |
| 119 | #### Targeting Specific Queries |
| 120 | To include context-specific examples like homework help when needed. |
| 121 | ```yaml |
| 122 | {% if extract_user_query_topic(user_query) == "homework_help" %} |
| 123 | { |