Prompt engineering should be about building (engineering) a program within a string (the string is a necessary evil because of llms nature not an asset). It should not be about finding the secret incantation that only works when the planets are aligned. The most maintainable and efficient way to do this is by following these rules:
1. Separate instructions, input fields, and output fields.
Clearly name your input and output fields. You may also describe them and specify their types if necessary.
Example:
Program name: rag
Instruction: Given a context and a question, provide an answer.
Inputs: context, question
Output: answer
2. Do not hard-code formatting or parsing logic into your prompt.
Use tools to extract or enhance the program for the particular LLM and formatting you need.
3. Avoid manually iterating on the exact prompt wording unless it’s a specification you’d share with humans.
Instead, use coding tools, LLMs, and benchmarks to automatically optimize prompt wording. Different models may require different phrasing—this approach ensures your LLM program remains maintainable.
If you follow these rules, you should use DSPy: it provides a class for step 1, code for step 2, and optimizers for step 3. In fact, these rules covers over 90% of what DSPy offers. The truth is, this post is not about prompt engineering, it about prompt programming and its a paraphrasing of the dspy paradigm as described by
@lateinteraction yesterday. See below for the original post.