Skip to content

Instantly share code, notes, and snippets.

@ityonemo
Created December 1, 2023 00:04
Show Gist options
  • Save ityonemo/e59df2917538b9512eeb8af37db849cd to your computer and use it in GitHub Desktop.
Save ityonemo/e59df2917538b9512eeb8af37db849cd to your computer and use it in GitHub Desktop.
Some crazy shit I wrote using EEx + GPT
defmodule RockE.DynamicImprover do
alias OpenAI
require EEx
EEx.function_from_string(:defp, :prompt, """
<% assigns = Map.from_struct(round) %>
Hi ChatGPT! I'm trying to prompt ChatGPT 3.5 to perform a function call.
However, the function call often makes mistakes in the passed argument:
The current accuracy is <%= @accuracy %> I'd love to see the accuracy go up to 90%.
Can you help me write a better prompt for the schema? Be sure to keep the prompt
as if it is a user addressing ChatGPT, and thank ChatGPT at the end.
The current prompt is as follows:
> <%= @prompt %>
The schema is as follows:
```yaml
<%= @schema %>
```
Here is an example error message:
> <%= @error %>
That resulted from the following response:
```json
<%= @response %>
```
Thanks very much for your help!
""", [:round])
@functions Yamlixir.decode!("""
name: suggest_prompt
description: Use this function to suggest a better prompt for this task.
parameters:
type: object
required: [prompt]
properties:
prompt:
description: The improved prompt
type: string
""")
defmodule Round do
@schema File.read!("lib/rock_e.yaml")
defstruct [:accuracy, :prompt, :error, :response, schema: @schema]
end
def improve_round(round) do
OpenAI.gpt([user: prompt(round)], model: "gpt-4", functions: @functions, function_call: %{name: "suggest_prompt"})
|> get_in(["function_call", "arguments"])
|> Jason.decode!
|> Map.get("prompt")
rescue
_ in MatchError ->
improve_round(round)
end
@prompt """
You are Rock-E, the AI personal trainer. Can you suggest three days of workouts for me?
Group these workouts by theme, and make sure to include the theme in the entry for the day.
"""
defp prompt_and_improve(prompt) do
RockE.profile(prompt, false)
rescue
_ in MatchError ->
prompt_and_improve(prompt)
end
def go(prompt \\ @prompt) do
profile = prompt_and_improve(prompt)
IO.puts("""
tested prompt: #{prompt}
got aaccuracy: #{profile.accuracy}
""")
unless profile.accuracy >= 90 do
example = List.first(profile.errors)
%Round{
accuracy: profile.accuracy,
prompt: @prompt,
error: example.msg,
response: example.result,
schema: @schema
}
|> improve_round
|> go()
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment