{"id":3385,"date":"2023-08-17T11:00:01","date_gmt":"2023-08-17T18:00:01","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=3385"},"modified":"2024-01-03T16:22:11","modified_gmt":"2024-01-04T00:22:11","slug":"android-openai-chatgpt-14","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-14\/","title":{"rendered":"Prompt engineering tips"},"content":{"rendered":"<p>\n  Hello prompt engineers,\n<\/p>\n<p>\n  We\u2019ve been sharing a lot of OpenAI content the last few months, and because each blog post typically focuses on a specific feature or API, there\u2019s often smaller learnings or discoveries that don\u2019t get mentioned or highlighted. \n<\/p>\n<p>\n  In this blog we\u2019re sharing a few little tweaks that we discovered when creating LLM prompts for the samples we\u2019ve shared. \n<\/p>\n<h2>\n  Set the system prompt \n<\/h2>\n<p>\n  The <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-7\/\">droidcon SF sessions demo<\/a> has a few different instructions in its system prompt, each for a specific purpose (explained below):\n<\/p>\n<h3>\n  Keep the chat focused\n<\/h3>\n<p>The first part of the system prompt was intended to prevent the chat from going off-topic:<\/p>\n<pre>\"You will answer questions about the speakers and sessions at the droidcon SF conference.\"<\/pre>\n<p>\n  Unfortunately, in <code>gpt-3.5<\/code> the system prompt isn\u2019t given much weight. With <code>gpt-3.5<\/code> this instruction helps the model to answer with the name of the conference but doesn\u2019t really restrict the types of queries it will respond to. With <code>gpt-4<\/code>, however, the model follows this instruction more closely, with responses like this:\n<\/p>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-19.png\" class=\"wp-image-3402\" alt=\"Model refuses to write a poem\" width=\"450\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-19.png 1768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-19-300x158.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-19-1024x541.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-19-768x406.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-19-1536x811.png 1536w\" sizes=\"(max-width: 1768px) 100vw, 1768px\" \/>\n<\/p>\n<h3>\n  Provide grounding data\n<\/h3>\n<p>The next part of the system prompt helps the model to answer some basic questions:<\/p>\n<pre>\"The conference is on June 8th and 9th, 2023 on the UCSF campus in Mission Bay. \r\nIt starts at 8am and finishes by 6pm.\"<\/pre>\n<p>\n  The conference date, times, and location were originally added to the system prompt to help it answer questions about those facts. However, once we added the <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-10\/\"><code>sessionsByTime<\/code> function<\/a> call the model can also use this information to determine appropriate parameters for the function.\n<\/p>\n<h3>\n  Instructions on how to respond\n<\/h3>\n<p>Another part of the system prompt helps the model to respond with useful information:<\/p>\n<pre>\"When showing session information, always include the subject, speaker, location, and time. \r\nONLY show the description when responding about a single session.\"<\/pre>\n<p>\n  This addition to the system prompt makes the model\u2019s responses more useful. Without it, the model won\u2019t always return all the information about the session (in this case it\u2019s missing the times and locations):\n<\/p>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-20.png\" class=\"wp-image-3403\" alt=\"Chat response about sessions doesn't include time or location\" width=\"450\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-20.png 1768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-20-300x136.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-20-1024x463.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-20-768x347.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-20-1536x694.png 1536w\" sizes=\"(max-width: 1768px) 100vw, 1768px\" \/>\n<\/p>\n<p>\n  But <em>with<\/em> the instructions to always include the metadata, it\u2019s much more verbose:\n<\/p>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-4.png\" class=\"wp-image-3404\" alt=\"Chat response to same prompt includes more useful information with system prompt change\" width=\"450\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-4.png 1768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-4-300x201.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-4-1024x687.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-4-768x515.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-4-1536x1030.png 1536w\" sizes=\"(max-width: 1768px) 100vw, 1768px\" \/>\n<\/p>\n<p>\n  Note that the completion request was always including <em>all<\/em> the metadata; the change to the system prompt is the only difference between these two different outcomes.\n<\/p>\n<h2>\n  Even error messages can be better engineered\n<\/h2>\n<p>\n  In the <a href=\"#post-3385-TK\">post about adding a function<\/a> to query droidcon sessions by time, an error message is returned when no sessions are found \u2013 a scenario that would typically happen before or after the event.\n<\/p>\n<p>\n  The first iteration of the &#8220;no sessions found\u201d error was this text:\n<\/p>\n<pre>\"There are no sessions available\"<\/pre>\n<p>\n  The model interpreted this into responses like this:\n<\/p>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-21.png\" class=\"wp-image-3406\" alt=\"Error message isn't useful when no sessions are found\" width=\"450\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-21.png 1768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-21-300x135.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-21-1024x460.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-21-768x345.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-21-1536x690.png 1536w\" sizes=\"(max-width: 1768px) 100vw, 1768px\" \/>\n<\/p>\n<p>\n  By changing the function\u2019s response to include a reference to the conference:\n<\/p>\n<pre>\"There are no sessions available.\r\nRemind the user about the dates and times the conference is open.\"<\/pre>\n<p>\n  the model gives a much friendlier response:\n<\/p>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-22.png\" class=\"wp-image-3407\" alt=\"Error message includes useful information such as when the conference dates and times are.\" width=\"450\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-22.png 1768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-22-300x146.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-22-1024x500.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-22-768x375.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-chat-description-automatically-22-1536x750.png 1536w\" sizes=\"(max-width: 1768px) 100vw, 1768px\" \/>\n<\/p>\n<p>\n  Note that the error message doesn\u2019t need to specifically reference the conference dates, the model will understand that from previous context (in this case the system prompt, as explained above). The model will also use the current date and time to craft the response and refer to whether the conference hasn\u2019t started yet or is already over.\n<\/p>\n<h2>Read The Fancy Manual<\/h2>\n<p>\n  The first time we discussed OpenAI chat function calling \u2013 to support the <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-9-functions\/\">current weather query<\/a> \u2013 we also updated the <a href=\"https:\/\/github.com\/conceptdev\/droidcon-sf-23\/blob\/942abb8512a04d90661fa796668f1e7062ea5a42\/Jetchat\/app\/src\/main\/java\/com\/example\/compose\/jetchat\/OpenAIWrapper.kt#L30\">system prompt<\/a> to contain:\n<\/p>\n<pre>\"Only use the functions you have been provided with.\"<\/pre>\n<p>\n  This was added at the suggestion of the OpenAI <a href=\"https:\/\/platform.openai.com\/docs\/guides\/gpt\/function-calling\">documentation for function calling<\/a>, which states:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1695\" height=\"302\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-white-background-with-black-text-description-au-2.png\" class=\"wp-image-3405\" alt=\"Screenshot of OpenAI documentation explaining the need for the function-restricting system prompt\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-white-background-with-black-text-description-au-2.png 1695w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-white-background-with-black-text-description-au-2-300x53.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-white-background-with-black-text-description-au-2-1024x182.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-white-background-with-black-text-description-au-2-768x137.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-white-background-with-black-text-description-au-2-1536x274.png 1536w\" sizes=\"(max-width: 1695px) 100vw, 1695px\" \/>\n<\/p>\n<p>\n  Sometimes prompt tweaks don\u2019t have to come by trial-and-error, they can come straight from the documentation \ud83d\ude09 Of course the function calling API is fairly new, so the possibility of hallucinated function names might be fixed in a future version.\n<\/p>\n<h2>Summarize but not what you think<\/h2>\n<p>\n  The first OpenAI-related post this year was about implementing a <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-2\/\">summarization feature in an HTML editor<\/a>. The prompt suggested was:\n<\/p>\n<pre>\"Strip away extra words in the below html content and provide a clear message as html content\"<\/pre>\n<p>\n  which you can test out in <a href=\"https:\/\/chat.openai.com\/\">ChatGPT<\/a> \u2013 it works great and returns shorter, summarized HTML as shown:\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"2500\" height=\"1190\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/screenshot-of-a-chatgpt-interaction-testing-a-spel-2.png\" class=\"wp-image-3408\" alt=\"Screenshot of a ChatGPT interaction testing a spell checking prompt with HTML content\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/screenshot-of-a-chatgpt-interaction-testing-a-spel-2.png 2500w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/screenshot-of-a-chatgpt-interaction-testing-a-spel-2-300x143.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/screenshot-of-a-chatgpt-interaction-testing-a-spel-2-1024x487.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/screenshot-of-a-chatgpt-interaction-testing-a-spel-2-768x366.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/screenshot-of-a-chatgpt-interaction-testing-a-spel-2-1536x731.png 1536w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/screenshot-of-a-chatgpt-interaction-testing-a-spel-2-2048x975.png 2048w\" sizes=\"(max-width: 2500px) 100vw, 2500px\" \/>\n<\/p>\n<p>\n  It wasn\u2019t explained in that post, but there is a reason why the prompt isn\u2019t just <code>\"summarize the below HTML\"<\/code>, and that\u2019s because when the prompt is that simple, the model interprets it \u201cliterally\u201d, with the following result (you can try it yourself with <a href=\"https:\/\/github.com\/conceptdev\/surface-duo-window-manager-samples\/blob\/main\/SourceEditor\/app\/src\/main\/assets\/source.html\">this source<\/a>):\n<\/p>\n<p>\n  <img decoding=\"async\" width=\"1298\" height=\"1313\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-5.png\" class=\"wp-image-3409\" alt=\"Screenshot of a prompt doing unexpected things - the 'summarize' request instead summarizes the structure of the document rather than the content\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-5.png 1298w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-5-297x300.png 297w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-5-1012x1024.png 1012w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-5-768x777.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-5-24x24.png 24w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-5-48x48.png 48w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/07\/a-screenshot-of-a-computer-description-automatica-5-96x96.png 96w\" sizes=\"(max-width: 1298px) 100vw, 1298px\" \/>\n<\/p>\n<p>\n  As you can see, the model summarizes the HTML document, literally explaining the <em>structure<\/em> as well as the content. This was run using GPT-3.5, but GPT-4 returns a similar style of response. A simple \u201csummarize the below\u201d works fine on plaintext though, so the more literal interpretation only applies when there is more potential for different interpretations (i.e., when there is a format or structure present in addition to the content). \n<\/p>\n<h2>Resources and feedback<\/h2>\n<p>\n  We\u2019d love your feedback on this post, including any tips or tricks you\u2019ve learning from playing around with ChatGPT prompts.\n<\/p>\n<p>\n  If you have any thoughts or questions, use the\u00a0<a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\" target=\"_blank\" rel=\"noopener\">feedback forum<\/a>\u00a0or message us on\u00a0<a href=\"https:\/\/twitter.com\/surfaceduodev\" target=\"_blank\" rel=\"noopener\">Twitter @surfaceduodev<\/a>.\n<\/p>\n<p>\n  There will be no livestream this week, but you can check out the\u00a0<a href=\"https:\/\/youtube.com\/c\/surfaceduodev\" target=\"_blank\" rel=\"noopener\">archives on YouTube<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello prompt engineers, We\u2019ve been sharing a lot of OpenAI content the last few months, and because each blog post typically focuses on a specific feature or API, there\u2019s often smaller learnings or discoveries that don\u2019t get mentioned or highlighted. In this blog we\u2019re sharing a few little tweaks that we discovered when creating LLM [&hellip;]<\/p>\n","protected":false},"author":570,"featured_media":3407,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[741],"tags":[734,733],"class_list":["post-3385","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","tag-chatgpt","tag-openai"],"acf":[],"blog_post_summary":"<p>Hello prompt engineers, We\u2019ve been sharing a lot of OpenAI content the last few months, and because each blog post typically focuses on a specific feature or API, there\u2019s often smaller learnings or discoveries that don\u2019t get mentioned or highlighted. In this blog we\u2019re sharing a few little tweaks that we discovered when creating LLM [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/3385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/users\/570"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=3385"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/3385\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/3407"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=3385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=3385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=3385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}