{"id":3537,"date":"2023-10-12T10:39:33","date_gmt":"2023-10-12T17:39:33","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=3537"},"modified":"2024-01-03T16:06:07","modified_gmt":"2024-01-04T00:06:07","slug":"android-openai-chatgpt-22","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-22\/","title":{"rendered":"&#8220;Search the web&#8221; for up-to-date OpenAI chat responses"},"content":{"rendered":"<p>\n  Hello prompt engineers,\n<\/p>\n<p>\n  Over the course of this blog series, we have investigated different ways of augmenting the information available to an LLM when answering user queries, such as:\n<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-7\/\">Embeddings generated against static data<\/a>\n  <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-9-functions\/\">Function calls that use an external web service (eg. to get a weather report)<\/a>\n  <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-11\/\">Function calls against a local database, both to retrieve data and to store context<\/a>\n  <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-19\/\">Embeddings from conversation history to remember earlier interactions<\/a>\n  <\/li>\n<\/ul>\n<p>\n  However, there is still a challenge getting the model to answer with up-to-date \u201cgeneral information\u201d (for example, if the question relates to events that have occurred after the model\u2019s training). You can see a \u201creal life\u201d example of this when you use <em>Bing Chat<\/em> versus <em>ChatGPT<\/em> to search for a new TV show called \u201cPoker Face\u201d which first appeared in 2023:\n<\/p>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-computer-description-automatica-1.png\" class=\"wp-image-3538\" alt=\"\" width=\"500\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-computer-description-automatica-1.png 931w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-computer-description-automatica-1-300x137.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-computer-description-automatica-1-768x350.png 768w\" sizes=\"(max-width: 931px) 100vw, 931px\" \/><br\/><em>Figure 1: ChatGPT 3.5 training ended in September 2021. It does not know about the latest shows.<\/em>\n<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-phone-description-automatically.png\" class=\"wp-image-3539\" alt=\"\" width=\"500\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-phone-description-automatically.png 910w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-phone-description-automatically-300x129.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-phone-description-automatically-768x330.png 768w\" sizes=\"(max-width: 910px) 100vw, 910px\" \/><br\/><em>Figure 2: ChatGPT 4 training ended in January 2022. It doesn\u2019t know about the TV show we are asking about either.<\/em>\n<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-television-show-description-aut.png\" class=\"wp-image-3540\" alt=\"\" width=\"500\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-television-show-description-aut.png 1616w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-television-show-description-aut-300x156.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-television-show-description-aut-1024x531.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-television-show-description-aut-768x398.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-television-show-description-aut-1536x797.png 1536w\" sizes=\"(max-width: 1616px) 100vw, 1616px\" \/><br\/><em>Figure 3: Bing Chat extracts the intent of the question, performs an internet search, and summarizes the results with up-to-date knowledge <\/em>\n<\/p>\n<p>\n  You can see from the Bing Chat screenshot in Figure 3 that it takes an intermediate step before answering the question, which is to extract the intent of my question and perform an internet search. The Bing Chat answer specifically references Wikipedia.org as its primary source (as shown by the footnote indicator on the results) that helped it to answer this question.\n<\/p>\n<p>\n  To illustrate how to build an internet search that will let <strong><em>JetchatAI<\/em><\/strong> answer questions about recent topics, we\u2019ll create a new function (similar to the <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-9-functions\/\">weather function<\/a>) that searches <a href=\"https:\/\/www.wikipedia.org\/\">Wikipedia<\/a> and uses the results to augment our OpenAI chat requests.\n<\/p>\n<blockquote><p>NOTE: this post is <em>not<\/em> intended to be a production-quality implementation of a Bing Chat-like feature. Rather, it walks through the <em>principles<\/em> whereby the <a href=\"https:\/\/openai.com\/blog\/function-calling-and-other-api-updates\">chat function API<\/a> can extract meaning from the user\u2019s query and execute a search on their behalf, and then summarize the results and thereby answer questions on topics that did not exist in the training data.<\/p><\/blockquote>\n<p>\n  Figure 4 shows how JetchatAI would answer this query <em>before<\/em> adding the ability to search more current data. The app is configured with the <code>gpt-3.5-turbo-16k<\/code> model, which returns details of an old TV show&#8230;\n<\/p>\n<p>\n  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-1.png\" class=\"wp-image-3541\" alt=\"\" width=\"500\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-1.png 1895w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-1-300x171.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-1-1024x584.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-1-768x438.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-1-1536x876.png 1536w\" sizes=\"(max-width: 1895px) 100vw, 1895px\" \/><br\/><em>Figure 4: Without up-to-date context, the app answers with details which I suspect are a hallucination<\/em>\n<\/p>\n<p>\n  I\u2019m reasonably sure the model is hallucinating the answer because the ChatGPT website did not respond with an answer, and every time I restart JetchatAI, it produces a different answer. This is probably due to configuration differences (e.g., temperature) between the model being used in JetchatAI and the ChatGPT website examples in Figures 1 and 2.\n<\/p>\n<h2>HttpClient as a chat function<\/h2>\n<p>\n  In order to access more accurate, up-to-date information, we\u2019ll need to implement a way for the app to query an internet search index. For this demo, we\u2019ll just use Wikipedia\u2019s <a href=\"https:\/\/en.wikipedia.org\/w\/api.php\">MediaWiki API<\/a> \u2013 it\u2019s not as comprehensive as an internet search engine like Bing, but it will provide enough data to build a working prototype.\n<\/p>\n<p>\n  The existing <code>currentWeather<\/code> function performs two HTTP requests (to locate the user and then to retrieve the weather for that location). The <a href=\"https:\/\/github.com\/conceptdev\/droidcon-sf-23\/pull\/18\/files\">pull-request<\/a> for this blogpost shows that we can copy-paste that exact code to perform a \u2018search\u2019 on Wikipedia and then retrieve the content for the first matching result:\n<\/p>\n<pre>  val wikiSearchUrl = \"https:\/\/en.wikipedia.org\/w\/api.php?action=opensearch&amp;search=$query&amp;limit=1&amp;namespace=0&amp;format=json\"\r\n  val wikiSearchResponse = httpClient.get(wikiSearchUrl) {contentType(ContentType.Application.Json)}\r\n  if (wikiSearchResponse.status == HttpStatusCode.OK) {\r\n      \/\/ CODE OMITTED to parse the Wikipedia search response\r\n      wikipediaTitle = responseJsonElement[1].jsonArray[0].jsonPrimitive.content\r\n  }\r\n  val wikiTitleUrl = \"https:\/\/en.wikipedia.org\/w\/api.php?action=query&amp;prop=extracts&amp;exsentences=10&amp;exlimit=1&amp;titles=$wikipediaTitle&amp;explaintext=1&amp;format=json\"\r\n  val wikiTitleResponse = httpClient.get(wikiTitleUrl) {contentType(ContentType.Application.Json)}\r\n  if (wikiTitleResponse.status == HttpStatusCode.OK) {\r\n     \/\/ CODE OMITTED to parse the Wikipedia content response\r\n      wikipediaText = itemPageElement?.get(\"extract\")?.jsonPrimitive?.content\r\n  }<\/pre>\n<p><em>Figure 5: HTTP requests to Wikipedia to implement the \u2018search\u2019<\/em>\n<\/p>\n<p>\n  With these two HTTP requests we can now create a chat function <code>askWikipedia<\/code>, which will attempt to use the Wikipedia search engine to identify a top result, and then visit that entry and use the page summary as context for our chat request. The query is hardcoded to only return a single result \u2013 in a production application, we might choose to return a number of top results (possibly using embeddings to evaluate how likely they are to be useful)\u2026\n<\/p>\n<h2>Prompt engineering challenges<\/h2>\n<p>\n  There are four different spots in the function declaration that act like a \u201cprompt\u201d that affects how the model interacts with the function. I tested two different styles of \u201cprompt\u201d, one that was very broad and another that was designed to limit answers to TV\/Movie topics only. These values are all set in the <a href=\"Jetchat\/app\/src\/main\/java\/com\/example\/compose\/jetchat\/functions\/AskWikipediaFunction.kt\"><strong>AskWikipedia.kt<\/strong><\/a> file.\n<\/p>\n<table>\n<tr>\n<td>\n<p><strong>Chat Function attributes<\/strong>\n<\/p>\n<\/td>\n<td>\n<p><strong>Broad implementation<\/strong>\n<\/p>\n<\/td>\n<td>\n<p><strong>Subject-specific implementation<\/strong>\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong>Function name<\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  <code>askWikipedia<\/code>\n<\/p>\n<\/td>\n<td>\n<p>\n  <code>askMediaQuery<\/code>\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong>Function description<\/strong>\n<\/p>\n<\/td>\n<td>\n<p><code>Answer user questions by querying the Wikipedia website.<\/code>\n<\/p>\n<\/td>\n<td>\n<p>\n  <code>Answer questions about tv shows and movies<\/code>\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong>Parameter name<\/strong>\n<\/p>\n<\/td>\n<td>\n<p>\n  <code>query<\/code>\n<\/p>\n<\/td>\n<td>\n<p>\n  <code>query<\/code>\n<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p><strong>Parameter description<\/strong>\n<\/p>\n<\/td>\n<td>\n<p><code>The search term to query on the Wikipedia website. Extract the subject from the sentence or phrase to use as the search term.<\/code>\n<\/p>\n<\/td>\n<td>\n<p>\n  Tested both <code>Movie or TV show name<\/code> and <code>Search query<\/code> \n<\/p>\n<\/td>\n<\/tr>\n<\/table>\n<p>\n  Notes on testing these two different implementations:\n<\/p>\n<ol>\n<li>\n  The <strong>function name<\/strong> can have a huge impact on when the model chooses to call it. When it\u2019s set to <code>askWikipedia<\/code>, the function is called for lots of different types of query, including single word queries like \u201cplatypus\u201d. When testing with the function name <code>askMediaQuestion<\/code>, it was much less likely to be called for questions about geography or animals, for example. I suspect that the model actually understands what \u201cWikipedia\u201d is and this causes it to favor calling this function when \u201cWikipedia\u201d is part of the function name.\n  \n<\/li>\n<li>\n  The <strong>function description<\/strong> can further guide the model to use the function only for certain types of queries. When the name is <code>askWikipedia<\/code>, changing the description doesn\u2019t seem to have much effect, but when the name is more generic, the function description has more impact on guiding the model on what sorts of queries it is intended to handle.\n  \n<\/li>\n<li>\n  The <strong>parameter name<\/strong> can provide a hint to the model as to what sorts of data should be sent. Whether the parameter is required or not can also have an impact.\n<\/li>\n<li>\n  The <strong>parameter description<\/strong> can have a material impact on the function working. For example, using the phrase \u201cExtract the subject from the sentence or phrase\u201d can ensure that the model attempts to interpret the user intent rather than just sending the entire query string.\n  <br \/>\n  Also, when testing as <code>askMediaQuery<\/code>, if the parameter description was \u201cSearch query\u201d, then the model would send \u201cPoker Face TV series\u201d as the parameter; but if the description was \u201cMovie or TV show name\u201d then it would only send \u201cPoker Face\u201d (omitting the \u201cTV series\u201d qualifying string). This seemingly minor change resulted in different search results from Wikipedia which did not return the correct results!\n<\/li>\n<\/ol>\n<p>\n  Tweaking each of these values can cause the model responses to change dramatically. It may take some trial-and-error to set the function attributes correctly for your use-case. Ultimately, I chose the broader implementation, as it succeeded more frequently than when I was trying to create restrictions on the types of data that could be acted on.\n<\/p>\n<p>\n  The final \u201cprompt\u201d challenge for this feature was ensuring that the model attributes its answers to Wikipedia. When the function retrieves data from Wikipedia, the following text is added to the return string: <code>If this information is used in the response, add [sourced from Wikipedia] to the end of the response<\/code>. Figure 6 shows how this looks in the app.\n<\/p>\n<h2>How it works<\/h2>\n<p>\n  Here\u2019s a step-by-step walkthrough of how the query is processed:\n<\/p>\n<h3>Step 1: Model determines that a function call is needed<\/h3>\n<p>\n  User query: \u201c<strong>tell me about the poker face tv series\u201d<\/strong>\n<\/p>\n<p>\n  Function parameter: <strong>Poker Face TV series<\/strong>\n<\/p>\n<p>\n  The model extracts the intent of the query and removes unnecessary words (\u201ctell me about\u201d) and uses the result as the function parameter. \n<\/p>\n<h3>Step 2: Function call visits Wikipedia<\/h3>\n<p>\n  The first HTTPS request calls the Wikipedia <em>search<\/em> API and returns JSON that includes a valid page \u201c<a href=\"https:\/\/en.wikipedia.org\/wiki\/Poker_Face_(TV_series)\">Poker Face (TV Series)<\/a>\u201d.\n<\/p>\n<p>\n  The second HTTPS request calls the Wikipedia <em>query<\/em> API and returns JSON that includes a <a href=\"https:\/\/en.wikipedia.org\/w\/api.php?action=query&amp;prop=extracts&amp;exsentences=10&amp;exlimit=1&amp;titles=Poker%20Face%20(TV%20series)&amp;explaintext=1&amp;format=json\">summary of the content on that page<\/a>.\n<\/p>\n<p>\n  The Wikipedia page summary is then returned to the model as context for the query \u201c<strong>tell me about the poker face tv series<\/strong>\u201d\n<\/p>\n<h3>Step 3: Wikipedia content sent back to model for answer<\/h3>\n<p>\n  The final response from the model returns a lightly summarized version of the Wikipedia content, and the model has effectively answered a question from data that did not exist when it was trained! The function appends the note \u201c[sourced from Wikipedia]\u201d as instructed in our prompt.\n<\/p>\n<h2>And it works!<\/h2>\n<p>\n  The screenshot below shows the output of the query to Wikipedia:\n<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-2.png\" class=\"wp-image-3542\" alt=\"\" width=\"500\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-2.png 1895w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-2-243x300.png 243w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-2-831x1024.png 831w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-2-768x946.png 768w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-2-1247x1536.png 1247w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-chat-description-automatically-2-1662x2048.png 1662w\" sizes=\"(max-width: 1895px) 100vw, 1895px\" \/><br\/><em>Figure 6: JetchatAI will now extract search terms from the user query, and use Wikipedia\u2019s results to answer with up-to-date information<\/em>\n<\/p>\n<h2>Side effects of a broadly applicable chat function<\/h2>\n<p>\n  The downside of a function that can be applied to most or almost all user queries is that the model falls into a pattern of calling it for every user query, even queries that the model could adequately answer from its training. The model may or may not use the function when answering queries like:\n<\/p>\n<ul>\n<li>\n    What is a platypus?\n  <\/li>\n<li>\n    What\u2019s the top tourist attraction in Paris?\n  <\/li>\n<li>\n    Where is the city of Cairns?\n  <\/li>\n<\/ul>\n<p>\n  In my testing, I found that for some of these (e.g., the platypus), Wikipedia returns content, and the model summarizes that in preference to its training data. In others, like the question about Paris attractions, Wikipedia\u2019s search does not find a result and the model answers from its training data. For the question about Cairns, the model answers immediately and does not call the <code>askWikipedia<\/code> function.\n<\/p>\n<p>\n  It\u2019s interesting to note that the model can switch modes: the answer to \u201cwhat is a platypus?\u201d is retrieved and summarized from the Wikipedia response, but a follow-up question \u201ctell me more detail about the platypus\u201d might result in the model returning a much longer response from its training data (containing details that were not in the Wikipedia content). \n<\/p>\n<h2>Prompt jailbreaking<\/h2>\n<p>\n  The user-query can also be structured to <em>bypass<\/em> the function, simply by saying \u201cwithout using any functions\u201d, e.g.:\n<\/p>\n<ul>\n<li>\n    Tell me about monotremes without using any functions\n  <\/li>\n<li>\n    Tell me about the poker face tv series without using any functions\n  <\/li>\n<\/ul>\n<p>\n  In both these cases, the <code>askWikipedia<\/code> function is not called and the model answers from its training data \u2013 which still results in the correct answer for factual queries (eg. \u201cdefinition of a monotreme\u201d), but returns a hallucinated reference for the tv show question. When the user\u2019s input affects how the model responds in this way, it could be considered a kind of \u2018jailbreak\u2019 that you would want to avoid with more specific prompts in the system prompt and the function attributes.\n<\/p>\n<p>\n  Hilariously, the <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/android-openai-chatgpt-19\/\">infinite chat embeddings history<\/a> remembers the incorrect answer, and subsequent queries for \u201cTell me about the poker face tv series\u201d <em>always<\/em> repeat the hallucinated response that was first generated. However, we can <em>specifically ask it to refer to Wikipedia<\/em>, and it will call the function and tell us the right answer (click on Figure 7 to see the full discussion):\n<\/p>\n<p>\n  <a href=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-phone-description-automatically-1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2023\/10\/a-screenshot-of-a-phone-description-automatically-1.png\" class=\"wp-image-3543\" alt=\"\" width=\"500\" \/><\/a><br\/><em>Figure 7: Arguing with a model confused by jailbreaking to get the right answer<\/em>\n<\/p>\n<p>\n  Notice that the hallucinated answer in Figure 7 describes a different \u201cPoker Face\u201d than the hallucinated answer in Figure 4, because this was after a fresh restart of the application (embeddings history was blank).\n<\/p>\n<p>\n  Ultimately, a lot of testing is required to observe how the model behaves in response to the various types of questions you expect from your users.\n<\/p>\n<blockquote><p>NOTE: the fact that the chat embeddings history remembers and recalls hallucinated facts exposes a weakness in the design. One idea to address this could be to add another layer of processing to the history data store, so that if a new fact (especially from a function call) is learned for a given user-query, the earlier saved response is deleted. More embeddings comparisons would be required to decide what user-queries were equivalent, along with more code to manage the history database and decide which responses to save and which to delete.<\/p><\/blockquote>\n<h2>Feedback and resources<\/h2>\n<p>\n  We\u2019d love your feedback on this post, including any tips or tricks you\u2019ve learned from playing around with ChatGPT prompts.\n<\/p>\n<p>\n  If you have any thoughts or questions, use the <a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a> or message us on <a href=\"https:\/\/twitter.com\/surfaceduodev\">Twitter @surfaceduodev<\/a>.\n<\/p>\n<p>\n  There will be no livestream this week, but you can check out the <a href=\"https:\/\/youtube.com\/c\/surfaceduodev\">archives on YouTube<\/a>.\n<\/p>\n<p>\n  Text from Wikipedia is shared under the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Wikipedia:Text_of_the_Creative_Commons_Attribution-ShareAlike_4.0_International_License\">Creative Commons Attribution-ShareAlike license 4.0<\/a>. The text may be summarized and adapted from the source. Refer to the <a href=\"https:\/\/www.mediawiki.org\/wiki\/API:Etiquette\">API etiquette<\/a> page for advice on how to be a responsible client of Wikipedia APIs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello prompt engineers, Over the course of this blog series, we have investigated different ways of augmenting the information available to an LLM when answering user queries, such as: Embeddings generated against static data Function calls that use an external web service (eg. to get a weather report) Function calls against a local database, both [&hellip;]<\/p>\n","protected":false},"author":570,"featured_media":3544,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[741],"tags":[734,733],"class_list":["post-3537","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, Over the course of this blog series, we have investigated different ways of augmenting the information available to an LLM when answering user queries, such as: Embeddings generated against static data Function calls that use an external web service (eg. to get a weather report) Function calls against a local database, both [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/3537","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=3537"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/3537\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/3544"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=3537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=3537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=3537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}