A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the `title` element
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>Poking around OpenAI. (archive) — David Larlet</title>
  13. <meta name="description" content="Publication mise en cache pour en conserver une trace.">
  14. <!-- That good ol' feed, subscribe :). -->
  15. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  16. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  17. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  18. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  19. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  20. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  21. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  22. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  23. <meta name="msapplication-TileColor" content="#f7f7f7">
  24. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  25. <meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)">
  26. <meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)">
  27. <!-- Documented, feel free to shoot an email. -->
  28. <link rel="stylesheet" href="/static/david/css/style_2021-01-20.css">
  29. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  35. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  36. <script>
  37. function toggleTheme(themeName) {
  38. document.documentElement.classList.toggle(
  39. 'forced-dark',
  40. themeName === 'dark'
  41. )
  42. document.documentElement.classList.toggle(
  43. 'forced-light',
  44. themeName === 'light'
  45. )
  46. }
  47. const selectedTheme = localStorage.getItem('theme')
  48. if (selectedTheme !== 'undefined') {
  49. toggleTheme(selectedTheme)
  50. }
  51. </script>
  52. <meta name="robots" content="noindex, nofollow">
  53. <meta content="origin-when-cross-origin" name="referrer">
  54. <!-- Canonical URL for SEO purposes -->
  55. <link rel="canonical" href="https://lethain.com/openai-exploration/">
  56. <body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all">
  57. <article>
  58. <header>
  59. <h1>Poking around OpenAI.</h1>
  60. </header>
  61. <nav>
  62. <p class="center">
  63. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  64. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  65. </svg> Accueil</a> •
  66. <a href="https://lethain.com/openai-exploration/" title="Lien vers le contenu original">Source originale</a>
  67. </p>
  68. </nav>
  69. <hr>
  70. <p>I haven’t spent much time playing around with the latest LLMs,
  71. and decided to spend some time doing so. I was particularly curious
  72. about the usecase of using embeddings to supplement user prompts
  73. with additional, relevant data (e.g. supply the current status of their
  74. recent tickets into the prompt where they might inquire about progress on
  75. said tickets). This usecase is interesting because it’s very attainable
  76. for existing companies and products to take advantage of, and I imagine it’s
  77. roughly how e.g. Stripe’s GPT4 integration with their documentation works.</p>
  78. <p>To play around with that, I created a script that converts all of my writing
  79. into embeddings, tokenizes the user-supplied prompt to identify relevant sections
  80. of my content to inject into an expanded prompt, and sent that expanded prompt
  81. to OpenAI AI’s API.</p>
  82. <p>You can <a href="https://github.com/lethain/openai-experiments/blob/main/corpus.py">see the code on Github</a>,
  83. and read my notes on this project below.</p>
  84. <h2 id="references">References</h2>
  85. <p>This exploration is inspired by the recent work
  86. by <a href="https://eugeneyan.com/writing/llm-experiments/#llm-tools-to-summarize-query-and-advise">Eugene Yan</a>
  87. and <a href="https://simonwillison.net/2023/Apr/4/llm/">Simon Willison</a>.
  88. I owe particular thanks to <a href="https://twitter.com/eugeneyan/status/1646336530695467010">Eugene Yan</a>
  89. for his suggestions to improve the quality of the responses.</p>
  90. <p>The code I’m sharing below is scrapped together from a number of sources:</p>
  91. <p>I found none of the examples quite worked as documented, but ultimately I was able to get them working
  92. with some poking around, relearning Pandas, and so on.</p>
  93. <h2 id="project">Project</h2>
  94. <p>My project was to make the OpenAI API answer questions with awareness of all of my personal writing from this blog,
  95. <a href="https://staffeng.com">StaffEng</a> and <a href="https://infraeng.dev/">Infrastructure Engineering</a>.
  96. Specifically this means creating embeddings from Hugo blog posts in Markdown to use with OpenAI.</p>
  97. <p>You can <a href="https://github.com/lethain/openai-experiments/blob/main/corpus.py">read the code on Github</a>.
  98. I’ve done absolutely nothing to make it easy to read, but it is a complete example, and you could use
  99. it with your own writing by changing <a href="https://github.com/lethain/openai-experiments/blob/main/corpus.py#L112">Line 112</a>
  100. to point at your blog’s content directories. (Oh, and changing the prompts on <a href="https://github.com/lethain/openai-experiments/blob/main/corpus.py#L260">Line 260</a>.</p>
  101. <p>You can see a screenshot of what this looks like below.</p>
  102. <p><img src="/static/blog/2023/openai-experiment.png" alt="Screenshot of terminal program running Github lethain/openai-experiment"></p>
  103. <p>This project is pretty neat, in the sense that it works. It did take me a bit longer than expected, probably about three hours
  104. to get it working given some interruptions, mostly because the documentation’s examples were all subtly broken or didn’t actually connect
  105. together into working code. After it was working, I inevitably spent a few more hours fiddling around as well.
  106. My repo is terrible code, but is a full working code if anyone
  107. else had similar issues getting the question answering using embeddings stuff working!</p>
  108. <p>The other comment on this project is that I don’t really view this as a particularly effective solution to the problem I wanted to solve,
  109. as it’s performing a fairly basic k-means algorithm to match tokenized versions of my blog posts against the query,
  110. and then injecting the best matches into the GPT query as context. Going into this, I expected, I dunno, something more
  111. sophisticated than this. It’s a very reasonable solution, and a cost efficient solution because it avoids any model (re)training,
  112. but feels a bit more basic than I imagined.</p>
  113. <p>Also worth noting, the total cost to developing this app and running it a few dozen times: $0.50.</p>
  114. <h2 id="thoughts">Thoughts</h2>
  115. <p>This was a fun project, in part because it was a detour away from what I’ve spent most of my time on the last few months,
  116. which is writing my next book. Writing and editing a book is very valuable work, but it lacks the freeform joy of
  117. hacking around a small project with zero users. Without overthinking or overstructuring things too much,
  118. here are some bullet points thoughts about this project and expansion of AI in the industry at large:</p>
  119. <ul><li>As someone who’s been working in the industry for a while now, it’s easy to get jaded about new things.
  120. My first reaction to the recent AI hype is very similar to my first reaction to the crypto hype:
  121. we’ve seen hype before, and initial hype is rarely correlated with long-term impact on the industry
  122. or on society. In other words, I wasn’t convinced.</li><li>Conversely, I think part of long-term engineering leadership is remaining open to new things.
  123. The industry has radically changed from twenty years ago, with mobile development as the most obvious proof point.
  124. Most things won’t change the industry much, but some things will completely transform it,
  125. and we owe cautious interest to these potentially transformational projects.</li><li>My personal bet is that the new AI wave is moderately transformative but not massively so.
  126. Expanding on my thinking a bit, LLMs are showing significant promise at mediocre solutions to very general problems.
  127. A very common, often unstated, Silicon Valley model is to hire engineers, pretend the engineers are
  128. solving a problem, hire a huge number of non-engineers to actually solve the problem “until the technology automates it”,
  129. grow the business rapidly, and hope automation solves the margins in some later year.
  130. LLM adoption should be a valuable tool in improving margins in this kind of business,
  131. which in theory should enable new businesses to be created by improving the potential margin.
  132. However, we’ve been in a decade of <a href="https://www.readmargins.com/p/zirp-explains-the-world">zero-interest-rate policy</a>
  133. which has meant that current-year margins haven’t mattered much to folks,
  134. which implies that most of these ideas that should be enabled by improved margins should
  135. have already been attempted in the preceeding margin-agnostic decade.
  136. This means that LLMs will make those businesses better, but the businesses themselves should
  137. have already been tried, and many of them have failed ultimately due to market size preventing
  138. required returns moreso than margin of operating their large internal teams to mask over missing margin-enhancing technology.</li><li>If you ignore the margin-enhancement opporunties represented by LLMs,
  139. which I’ve argued shouldn’t generate new business ideas but improve existing business ideas already
  140. tried over the last decade, then it’s interesting to ponder what the sweet spot is for these tools.
  141. My take is that they’re very good at supporting domain experts, where the potential damaged caused by
  142. inaccuracies is constrained, e.g. Github Copilot is a very plausible way to empower a proficient programmer,
  143. and a very risky way to train a novice in a setting where the code has access to sensitive resources or data.
  144. However, to the extent that we’re pushing experts from authors to editors, I’m not sure that’s an actual speed
  145. improvement for our current generation of experts, who already have mastery in authorship and (often) a lesser
  146. skill in editing. Maybe there is a new generation of experts who are exceptional editors first, and authors second,
  147. which these tools will foster. If that’s true, then likely the current generation of leaders is unable to
  148. assess these tools appropriately, but&amp;mldr; I think that most folks make this argument about most new technologies,
  149. and it’s only true sometimes. (Again, crypto is a clear example of something that has not overtaken existing
  150. technologies in the real world with significant regulatory overhead.)</li></ul>
  151. <p>Anyway, it was a fun project, and I have a much better intuitive sense of what’s possible
  152. in this space after spending some time here, which was my goal. I’ll remain very curious to
  153. see what comes together here as the timeline progresses.</p>
  154. <p class="mt6 instapaper_ignoref"></p>
  155. </article>
  156. <hr>
  157. <footer>
  158. <p>
  159. <a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home">
  160. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use>
  161. </svg> Accueil</a> •
  162. <a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2">
  163. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use>
  164. </svg> Suivre</a> •
  165. <a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie">
  166. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use>
  167. </svg> Pro</a> •
  168. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail">
  169. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use>
  170. </svg> Email</a> •
  171. <abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2">
  172. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use>
  173. </svg> Légal</abbr>
  174. </p>
  175. <template id="theme-selector">
  176. <form>
  177. <fieldset>
  178. <legend><svg class="icon icon-brightness-contrast">
  179. <use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use>
  180. </svg> Thème</legend>
  181. <label>
  182. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  183. </label>
  184. <label>
  185. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  186. </label>
  187. <label>
  188. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  189. </label>
  190. </fieldset>
  191. </form>
  192. </template>
  193. </footer>
  194. <script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script>
  195. <script>
  196. function loadThemeForm(templateName) {
  197. const themeSelectorTemplate = document.querySelector(templateName)
  198. const form = themeSelectorTemplate.content.firstElementChild
  199. themeSelectorTemplate.replaceWith(form)
  200. form.addEventListener('change', (e) => {
  201. const chosenColorScheme = e.target.value
  202. localStorage.setItem('theme', chosenColorScheme)
  203. toggleTheme(chosenColorScheme)
  204. })
  205. const selectedTheme = localStorage.getItem('theme')
  206. if (selectedTheme && selectedTheme !== 'undefined') {
  207. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  208. }
  209. }
  210. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  211. window.addEventListener('load', () => {
  212. let hasDarkRules = false
  213. for (const styleSheet of Array.from(document.styleSheets)) {
  214. let mediaRules = []
  215. for (const cssRule of styleSheet.cssRules) {
  216. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  217. continue
  218. }
  219. // WARNING: Safari does not have/supports `conditionText`.
  220. if (cssRule.conditionText) {
  221. if (cssRule.conditionText !== prefersColorSchemeDark) {
  222. continue
  223. }
  224. } else {
  225. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  226. continue
  227. }
  228. }
  229. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  230. }
  231. // WARNING: do not try to insert a Rule to a styleSheet you are
  232. // currently iterating on, otherwise the browser will be stuck
  233. // in a infinite loop…
  234. for (const mediaRule of mediaRules) {
  235. styleSheet.insertRule(mediaRule.cssText)
  236. hasDarkRules = true
  237. }
  238. }
  239. if (hasDarkRules) {
  240. loadThemeForm('#theme-selector')
  241. }
  242. })
  243. </script>
  244. </body>
  245. </html>