Class: DSPy::Prompt

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dspy/prompt.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instruction:, input_schema:, output_schema:, few_shot_examples: [], signature_class_name: nil) ⇒ Prompt

Returns a new instance of Prompt.



34
35
36
37
38
39
40
# File 'lib/dspy/prompt.rb', line 34

def initialize(instruction:, input_schema:, output_schema:, few_shot_examples: [], signature_class_name: nil)
  @instruction = instruction
  @few_shot_examples = few_shot_examples.freeze
  @input_schema = input_schema.freeze
  @output_schema = output_schema.freeze
  @signature_class_name = signature_class_name
end

Instance Attribute Details

#few_shot_examplesObject (readonly)

Returns the value of attribute few_shot_examples.



14
15
16
# File 'lib/dspy/prompt.rb', line 14

def few_shot_examples
  @few_shot_examples
end

#input_schemaObject (readonly)

Returns the value of attribute input_schema.



17
18
19
# File 'lib/dspy/prompt.rb', line 17

def input_schema
  @input_schema
end

#instructionObject (readonly)

Returns the value of attribute instruction.



11
12
13
# File 'lib/dspy/prompt.rb', line 11

def instruction
  @instruction
end

#output_schemaObject (readonly)

Returns the value of attribute output_schema.



20
21
22
# File 'lib/dspy/prompt.rb', line 20

def output_schema
  @output_schema
end

#signature_class_nameObject (readonly)

Returns the value of attribute signature_class_name.



23
24
25
# File 'lib/dspy/prompt.rb', line 23

def signature_class_name
  @signature_class_name
end

Class Method Details

.from_h(hash) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
# File 'lib/dspy/prompt.rb', line 156

def self.from_h(hash)
  examples = (hash[:few_shot_examples] || []).map { |ex| FewShotExample.from_h(ex) }
  
  new(
    instruction: hash[:instruction] || "",
    input_schema: hash[:input_schema] || {},
    output_schema: hash[:output_schema] || {},
    few_shot_examples: examples,
    signature_class_name: hash[:signature_class_name]
  )
end

.from_signature(signature_class) ⇒ Object



170
171
172
173
174
175
176
177
178
# File 'lib/dspy/prompt.rb', line 170

def self.from_signature(signature_class)
  new(
    instruction: signature_class.description || "Complete this task.",
    input_schema: signature_class.input_json_schema,
    output_schema: signature_class.output_json_schema,
    few_shot_examples: [],
    signature_class_name: signature_class.name
  )
end

Instance Method Details

#==(other) ⇒ Object



182
183
184
185
186
187
188
189
# File 'lib/dspy/prompt.rb', line 182

def ==(other)
  return false unless other.is_a?(Prompt)
  
  @instruction == other.instruction &&
    @few_shot_examples == other.few_shot_examples &&
    @input_schema == other.input_schema &&
    @output_schema == other.output_schema
end

#add_examples(new_examples) ⇒ Object



66
67
68
69
# File 'lib/dspy/prompt.rb', line 66

def add_examples(new_examples)
  combined_examples = @few_shot_examples + new_examples
  with_examples(combined_examples)
end

#diff(other) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/dspy/prompt.rb', line 192

def diff(other)
  changes = {}
  
  changes[:instruction] = {
    from: @instruction,
    to: other.instruction
  } if @instruction != other.instruction
  
  changes[:few_shot_examples] = {
    from: @few_shot_examples.length,
    to: other.few_shot_examples.length,
    added: other.few_shot_examples - @few_shot_examples,
    removed: @few_shot_examples - other.few_shot_examples
  } if @few_shot_examples != other.few_shot_examples
  
  changes
end

#render_system_promptObject



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/dspy/prompt.rb', line 73

def render_system_prompt
  sections = []
  
  sections << "Your input schema fields are:"
  sections << "```json"
  sections << JSON.pretty_generate(@input_schema)
  sections << "```"
  
  sections << "Your output schema fields are:"
  sections << "```json"
  sections << JSON.pretty_generate(@output_schema)
  sections << "```"
  
  sections << ""
  sections << "All interactions will be structured in the following way, with the appropriate values filled in."
  
  # Add few-shot examples if present
  if @few_shot_examples.any?
    sections << ""
    sections << "Here are some examples:"
    sections << ""
    @few_shot_examples.each_with_index do |example, index|
      sections << "### Example #{index + 1}"
      sections << example.to_prompt_section
      sections << ""
    end
  end

  sections << "## Input values"
  sections << "```json"
  sections << "{input_values}"
  sections << "```"
  
  sections << "## Output values"
  sections << "Respond exclusively with the output schema fields in the json block below."
  sections << "```json"
  sections << "{output_values}"
  sections << "```"
  
  sections << ""
  sections << "In adhering to this structure, your objective is: #{@instruction}"
  
  sections.join("\n")
end

#render_user_prompt(input_values) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/dspy/prompt.rb', line 119

def render_user_prompt(input_values)
  sections = []
  
  sections << "## Input Values"
  sections << "```json"
  sections << JSON.pretty_generate(serialize_for_json(input_values))
  sections << "```"
  
  sections << ""
  sections << "Respond with the corresponding output schema fields wrapped in a ```json ``` block,"
  sections << "starting with the heading `## Output values`."
  
  sections.join("\n")
end

#statsObject



212
213
214
215
216
217
218
219
220
# File 'lib/dspy/prompt.rb', line 212

def stats
  {
    character_count: @instruction.length,
    example_count: @few_shot_examples.length,
    total_example_chars: @few_shot_examples.sum { |ex| ex.to_prompt_section.length },
    input_fields: @input_schema.dig(:properties)&.keys&.length || 0,
    output_fields: @output_schema.dig(:properties)&.keys&.length || 0
  }
end

#to_hObject



145
146
147
148
149
150
151
152
153
# File 'lib/dspy/prompt.rb', line 145

def to_h
  {
    instruction: @instruction,
    few_shot_examples: @few_shot_examples.map(&:to_h),
    input_schema: @input_schema,
    output_schema: @output_schema,
    signature_class_name: @signature_class_name
  }
end

#to_messages(input_values) ⇒ Object



136
137
138
139
140
141
# File 'lib/dspy/prompt.rb', line 136

def to_messages(input_values)
  [
    { role: 'system', content: render_system_prompt },
    { role: 'user', content: render_user_prompt(input_values) }
  ]
end

#with_examples(new_examples) ⇒ Object



55
56
57
58
59
60
61
62
63
# File 'lib/dspy/prompt.rb', line 55

def with_examples(new_examples)
  self.class.new(
    instruction: @instruction,
    input_schema: @input_schema,
    output_schema: @output_schema,
    few_shot_examples: new_examples,
    signature_class_name: @signature_class_name
  )
end

#with_instruction(new_instruction) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/dspy/prompt.rb', line 44

def with_instruction(new_instruction)
  self.class.new(
    instruction: new_instruction,
    input_schema: @input_schema,
    output_schema: @output_schema,
    few_shot_examples: @few_shot_examples,
    signature_class_name: @signature_class_name
  )
end