<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: TimeSurge Labs</title>
    <description>The latest articles on DEV Community by TimeSurge Labs (@timesurgelabs).</description>
    <link>https://dev.to/timesurgelabs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F7143%2Fe7c9d9c4-af8c-4e7c-b9e6-8e87fd478ce2.png</url>
      <title>DEV Community: TimeSurge Labs</title>
      <link>https://dev.to/timesurgelabs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/timesurgelabs"/>
    <language>en</language>
    <item>
      <title>Using LLMs in 3 lines of Python</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Mon, 30 Jun 2025 19:26:33 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/using-llms-in-3-lines-of-python-gm1</link>
      <guid>https://dev.to/timesurgelabs/using-llms-in-3-lines-of-python-gm1</guid>
      <description>&lt;p&gt;When working with LLMs, the first thing people generally install is the &lt;code&gt;openai&lt;/code&gt; or &lt;code&gt;anthropic&lt;/code&gt; packages, if you’re a little more adventurous with your LLM choice it may be &lt;code&gt;litellm&lt;/code&gt; or &lt;code&gt;ollama&lt;/code&gt;. The issue is that all of these require a bit of code to get your started. For example, assuming you have an API key in your environment like I do, you’ll need at least this code to make an LLM call with OpenAI (also assuming you’re using the older Chat Completions endpoint).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="c1"&gt;# retrieve API key from environment
&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# initialize client
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# send a chat request
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a helpful assistant.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Say something concise.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# print assistant's answer
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you want to wrap your API call with a function so you can call it repeatedly, that’s even more lines!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chat_with_openai&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a helpful assistant.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;chat_with_openai&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Say something concise.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that is simply unacceptable!&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you really care?
&lt;/h2&gt;

&lt;p&gt;No, I’m being facetious. For most LLM projects, consistency of output trumps anything else, however sometimes its nice to have a super simple way to add LLMs to my one-off python scripts and tools without all the boilerplate. &lt;/p&gt;

&lt;h2&gt;
  
  
  Magentic
&lt;/h2&gt;

&lt;p&gt;Magentic is a Python package that lets you create functions that call LLMs in 3 lines of code. No, really! Here’s an example ripped straight from &lt;a href="https://magentic.dev/#usage" rel="noopener noreferrer"&gt;their docs&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Add more &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ness to: {phrase}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;  &lt;span class="c1"&gt;# No function body as this is never executed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thanks to some black box dark magic that I don’t feel like learning about, this is a completely valid Python function that’s callable anywhere in the script, assuming you have an OpenAI API Key in your environment variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, how are you?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;# "Hey, dude! What's up? How's it going, my man?"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Note On Package Management
&lt;/h2&gt;

&lt;p&gt;I’m going to be using the &lt;a href="https://peps.python.org/pep-0723/" rel="noopener noreferrer"&gt;PEP 723&lt;/a&gt; standard at the top of all my scripts for the rest of this post. This allows you to use &lt;a href="https://docs.astral.sh/uv/" rel="noopener noreferrer"&gt;uv&lt;/a&gt;, the best package manager for Python, to run the scripts without you having to make a virtual environment, then install packages, then run the script. This automates all three of those tasks into a single command. Here’s an example.&lt;/p&gt;

&lt;p&gt;Here’s the above script with the added metadata and some slight modifications. This assumes you have &lt;a href="https://docs.astral.sh/uv/#installation" rel="noopener noreferrer"&gt;uv installed&lt;/a&gt; and the &lt;code&gt;OPENAI_API_KEY&lt;/code&gt; env var set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic"
# ]
# ///
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Add more &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ness to: {phrase}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;  &lt;span class="c1"&gt;# No function body as this is never executed
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script can now be downloaded and ran like an executable. I’ve uploaded to &lt;a href="https://gist.github.com/chand1012/218372f3e1101dfa7f915dc35c0e66d8" rel="noopener noreferrer"&gt;a gist&lt;/a&gt; for easy download.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; dudeify https://gist.githubusercontent.com/chand1012/218372f3e1101dfa7f915dc35c0e66d8/raw/363f720d21fa8ebe2e6a484f6b389496c3452064/dudeify.py
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x dudeify
./dudeify &lt;span class="s2"&gt;"Hello how are you"&lt;/span&gt;
&lt;span class="c"&gt;# Installed 23 packages in 45ms&lt;/span&gt;
&lt;span class="c"&gt;# Yo dude, how's it hangin'?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first time you run the script it’ll handle making a cached virtual environment for the next time you run it! For more information on how this works, you can check out the &lt;a href="https://docs.astral.sh/uv/guides/scripts/#using-a-shebang-to-create-an-executable-file" rel="noopener noreferrer"&gt;uv docs&lt;/a&gt;, and the &lt;a href="https://www.cottongeeks.com/articles/2025-06-24-fun-with-uv-and-pep-723" rel="noopener noreferrer"&gt;blog post&lt;/a&gt; that inspired my constant use of this feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured Outputs
&lt;/h2&gt;

&lt;p&gt;If you want to have structured outputs, like for example for an API response or just to make it easier to parse and use the data with your scripts, you can use a &lt;a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" rel="noopener noreferrer"&gt;Pydantic Dataclass&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic",
#     "pydantic",
# ]
# ///
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;species&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;legs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;latin_species&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;predators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;prey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Give me information on the animal {animal_name}.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;animal_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s an example of that method being ran.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6fsnfs8f52p75cm1mtg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6fsnfs8f52p75cm1mtg.png" alt="Example output" width="800" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompting and Function Calls
&lt;/h2&gt;

&lt;p&gt;There’s two ways you can prompt the LLM with Magentic. You can either use the &lt;code&gt;@prompt&lt;/code&gt; decorator, as I’ve been using, which is the simplest and fastest way to create LLM methods. There’s also &lt;code&gt;@chatprompt&lt;/code&gt;, which allows you to pass a list of chat messages to the LLM. This is especially useful for few-shot prompting, where you give the LLM some examples of what output you want. After all, LLMs &lt;em&gt;are&lt;/em&gt; just fancy pattern matching black boxes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic",
#     "pydantic",
# ]
# ///
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;chatprompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AssistantMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserMessage&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="c1"&gt;# this is a modified version of magentic's example chatprompt code
# https://magentic.dev/#chatprompt
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="nd"&gt;@chatprompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a movie buff.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;UserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is your favorite quote from Harry Potter?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;AssistantMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;Quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;It does not do to dwell on dreams and forget to live.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;character&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Albus Dumbledore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;UserMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is your favorite quote from {movie}?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_movie_quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Quote&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_movie_quote&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also pass &lt;a href="https://magentic.dev/#functioncall" rel="noopener noreferrer"&gt;function calls to LLMs&lt;/a&gt; to allow them to return a python callable that you can call later. Another use of this is the decorator &lt;code&gt;@prompt_chain&lt;/code&gt; which allows you to have an LLM call a function and use the returned results to generate its response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic",
#     "duckduckgo_search",
# ]
# ///
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt_chain&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;duckduckgo_search&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DDGS&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;web_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Searches the web for a given query&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;DDGS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ddgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ddgs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;

&lt;span class="nd"&gt;@prompt_chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a helpful assistant that can search the web for information. Use your tools to answer the user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s question: {query}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;functions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;web_search&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using Other LLMs
&lt;/h2&gt;

&lt;p&gt;If you’re a data conscious person, or just want your options to be open, Magentic can be configured to work with nearly all other LLMs as long as they are supported by &lt;a href="https://github.com/BerriAI/litellm" rel="noopener noreferrer"&gt;LiteLLM&lt;/a&gt; or offer an OpenAI compatible API. Here’s an example of a script that runs entirely locally using &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; and &lt;a href="https://ollama.com/library/gemma3" rel="noopener noreferrer"&gt;Google’s Gemma 3&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic"
# ]
# ///
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OpenaiChatModel&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenaiChatModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemma3:27b-it-qat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:11434/v1/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Add more &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ness to: {phrase}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;  &lt;span class="c1"&gt;# No function body as this is never executed
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your chosen LLM is one of the &lt;a href="https://docs.litellm.ai/docs/providers" rel="noopener noreferrer"&gt;many supported by LiteLLM&lt;/a&gt;, you can use the LiteLLM extra feature of Magentic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic[litellm]"
# ]
# ///
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic.chat_model.litellm_chat_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LitellmChatModel&lt;/span&gt;

&lt;span class="c1"&gt;# this specific example requires GEMINI_API_KEY env var to be set
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LitellmChatModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini/gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Add more &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ness to: {phrase}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;  &lt;span class="c1"&gt;# No function body as this is never executed
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use the LiteLLM method to use Anthropic’s Claude series of models, or you can use Magentic’s official Anthropic extension.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic[anthropic]"
# ]
# ///
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic.chat_model.anthropic_chat_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AnthropicChatModel&lt;/span&gt;

&lt;span class="c1"&gt;# this specific example requires GEMINI_API_KEY env var to be set
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AnthropicChatModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;claude-4-sonnet-latest&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Add more &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dude&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ness to: {phrase}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;  &lt;span class="c1"&gt;# No function body as this is never executed
&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dudeify&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No LLM left behind!&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Usage
&lt;/h2&gt;

&lt;p&gt;Need an async function? Just prefix with &lt;code&gt;async def&lt;/code&gt; instead of &lt;code&gt;def&lt;/code&gt; !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# incomplete snippet
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tell me more about {topic}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tell_me_more_about&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use Python’s &lt;code&gt;AsyncIterable&lt;/code&gt; to make multiple simultaneous calls to the LLM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# incomplete snippet
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AsyncIterable&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;List ten presidents of the United States&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;iter_presidents&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AsyncIterable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;president&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;iter_presidents&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Use asyncio.create_task to schedule the coroutine for execution before awaiting it
&lt;/span&gt;    &lt;span class="c1"&gt;# This way descriptions will start being generated while the list of presidents is still being generated
&lt;/span&gt;    &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;tell_me_more_about&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;president&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;descriptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need to stream the response back to the user? Use Magentic’s &lt;code&gt;StreamedStr&lt;/code&gt; to loop through the response chunks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic"
# ]
# ///
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StreamedStr&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tell me about {country}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;describe_country&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;StreamedStr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;describe_country&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also works for multiple objects, simply wrap your objects in the &lt;code&gt;Iterable&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env -S uv run --script
# /// script
# requires-python = "&amp;gt;=3.10"
# dependencies = [
#     "fire",
#     "magentic",
#     "pydantic",
# ]
# ///
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;collections.abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Iterable&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fire&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Fire&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;magentic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;species&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;legs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;latin_species&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;predators&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;prey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nd"&gt;@prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Give me information on the animals in the family {family}.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;animal_family_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Iterable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;animal&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;animal_family_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;family&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nc"&gt;Fire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Working with LLMs is now easier than ever, and Magnetic makes it even easier than the standard methods to quick add LLMs to any Python script, regardless of the scale of complexity. Using this in tandem with something like uv and the new scripting metadata allows you to quickly make command line tools that can utilize AI quickly and effectively. I won’t always use Magentic for every project I need an LLM for, but I’ll definitely use it all the time with my small one-offs and utilities.&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Agentic Coding (Vibe Coding) Best Practices</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Fri, 28 Mar 2025 21:49:53 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/agentic-coding-vibe-coding-best-practices-b4b</link>
      <guid>https://dev.to/timesurgelabs/agentic-coding-vibe-coding-best-practices-b4b</guid>
      <description>&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwolb0rz23myp0eub2led.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwolb0rz23myp0eub2led.png" alt="Comic" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've been living under a rock, you may not be aware of the "vibe coding" phenomenon.&lt;br&gt;
If you want a good explanation of what "vibe coding", or to use a more technical term, Agentic Coding, is, check out &lt;a href="https://youtu.be/Tw18-4U7mts?si=wmgKylbi-gEEmXzU" rel="noopener noreferrer"&gt;Fireship's video&lt;/a&gt; on the subject. He does a great job of explaining the concept in a way that's both easy to understand and objective about the pros and cons.&lt;/p&gt;
&lt;h2&gt;
  
  
  Tooling
&lt;/h2&gt;

&lt;p&gt;If you're going to ignore all the cons and go ahead with agentic coding, there are some best practices I use to make sure my code doesn't turn into a complete mess of AI generated garbage. I personally use Cursor, so this guide is going to use their &lt;a href="https://docs.cursor.com/context/rules-for-ai" rel="noopener noreferrer"&gt;Rules feature&lt;/a&gt; to organize and apply rules to the LLM for code generation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rules
&lt;/h2&gt;

&lt;p&gt;Cursor has a concept of a rule file. This file is a markdown file found in the &lt;code&gt;.cursor/rules&lt;/code&gt; directory with some extra front matter that specifies when and how the rule is applied to the LLM, and ending in &lt;code&gt;.mdc&lt;/code&gt; rather than &lt;code&gt;.md&lt;/code&gt;. These can be broken down into 4 categories.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Language Rules

&lt;ul&gt;
&lt;li&gt;Applies to specific languages.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Framework Rules

&lt;ul&gt;
&lt;li&gt;Applies to specific frameworks.&lt;/li&gt;
&lt;li&gt;Can also apply to libraries that have special rules, like shadcn/ui.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Practice Rules

&lt;ul&gt;
&lt;li&gt;For coding practice guidelines.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Project Rules

&lt;ul&gt;
&lt;li&gt;Should be used to describe project specific guidelines like file structure, dependencies used, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rules can be applied with 4 different methods.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always Apply&lt;/li&gt;
&lt;li&gt;Auto Apply

&lt;ul&gt;
&lt;li&gt;Uses a glob pattern to apply the rule to all files that match the pattern.&lt;/li&gt;
&lt;li&gt;Especially useful for language and framework rules where specific file extensions are used.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Agent Requested

&lt;ul&gt;
&lt;li&gt;Uses a description of the rule to allow the agent to decide when to apply the rule.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Manual Apply

&lt;ul&gt;
&lt;li&gt;Only applied when you directly ask the agent to apply the rule.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rules can also have other files from within your project linked to them and will also be loaded into context. This is especially useful for the project rules where you can link the README as well as any other documentation that the LLM should know about, like an Architecture or Contributing Guide.&lt;/p&gt;
&lt;h2&gt;
  
  
  Writing Rules
&lt;/h2&gt;

&lt;p&gt;The actual contents of the rules are written in markdown, and should be concise and clear guidelines for the LLM rules. They should be written to be both human and LLM readable, and should include very minimal code and command examples. Here's some examples of rules from my &lt;a href="https://github.com/chand1012/cursorrules" rel="noopener noreferrer"&gt;personal collection&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example Rules
&lt;/h2&gt;

&lt;p&gt;Here's an example I made for best practices when using Go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Go&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;coding&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;standards&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;best&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;practices&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;modern&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;development"&lt;/span&gt;
&lt;span class="na"&gt;globs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="err"&gt;**&lt;/span&gt;&lt;span class="s"&gt;/*.go&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Go Best Practices&lt;/span&gt;

&lt;span class="gu"&gt;## Package and Import Statements&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use meaningful package names that reflect their purpose (e.g., &lt;span class="sb"&gt;`auth`&lt;/span&gt;, &lt;span class="sb"&gt;`config`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Group imports in this order: standard library, third-party, then local packages, separated by blank lines.
&lt;span class="p"&gt;-&lt;/span&gt; Avoid import cycles to maintain clean dependency graphs.

&lt;span class="gu"&gt;## Type System&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`struct`&lt;/span&gt; types to define complex data structures.
&lt;span class="p"&gt;-&lt;/span&gt; Define &lt;span class="sb"&gt;`interface`&lt;/span&gt; types to specify behavior and enable polymorphism.
&lt;span class="p"&gt;-&lt;/span&gt; Use type aliases sparingly for clarity (e.g., &lt;span class="sb"&gt;`type ID string`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Leverage Go’s built-in types (e.g., &lt;span class="sb"&gt;`map`&lt;/span&gt;, &lt;span class="sb"&gt;`slice`&lt;/span&gt;) and composite types effectively.
&lt;span class="p"&gt;-&lt;/span&gt; Avoid unnecessary type conversions to maintain type safety.
&lt;span class="p"&gt;-&lt;/span&gt; Use struct embedding for composition instead of inheritance.

&lt;span class="gu"&gt;## Naming Conventions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`camelCase`&lt;/span&gt; for variable and function names (e.g., &lt;span class="sb"&gt;`getUser`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`PascalCase`&lt;/span&gt; for type names and exported identifiers (e.g., &lt;span class="sb"&gt;`UserService`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`ALL_CAPS`&lt;/span&gt; for constants (e.g., &lt;span class="sb"&gt;`MAX_RETRIES`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Be descriptive yet concise in naming (e.g., &lt;span class="sb"&gt;`userCount`&lt;/span&gt; over &lt;span class="sb"&gt;`cnt`&lt;/span&gt;).

&lt;span class="gu"&gt;## Code Organization&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Follow the standard Go project layout (e.g., &lt;span class="sb"&gt;`cmd/`&lt;/span&gt;, &lt;span class="sb"&gt;`pkg/`&lt;/span&gt;, &lt;span class="sb"&gt;`internal/`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Keep related code within the same package for cohesion.
&lt;span class="p"&gt;-&lt;/span&gt; Use subdirectories for larger packages to organize functionality (e.g., &lt;span class="sb"&gt;`api/handlers`&lt;/span&gt;).

&lt;span class="gu"&gt;## Functions and Methods&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Keep functions short and focused on a single responsibility.
&lt;span class="p"&gt;-&lt;/span&gt; Use named return values for clarity in complex functions (e.g., &lt;span class="sb"&gt;`func getData() (data string, err error)`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Avoid side effects in functions to improve predictability.

&lt;span class="gu"&gt;## Best Practices&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Follow the Go proverb: "A little copying is better than a little dependency."
&lt;span class="p"&gt;-&lt;/span&gt; Use interfaces to define behavior and decouple components.
&lt;span class="p"&gt;-&lt;/span&gt; Prefer composition over inheritance using embedding.
&lt;span class="p"&gt;-&lt;/span&gt; Avoid unnecessary abstractions; prioritize simplicity.
&lt;span class="p"&gt;-&lt;/span&gt; Use the &lt;span class="sb"&gt;`init`&lt;/span&gt; function sparingly for package initialization.
&lt;span class="p"&gt;-&lt;/span&gt; Avoid global variables; if unavoidable, ensure they are thread-safe (e.g., with &lt;span class="sb"&gt;`sync.Mutex`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Be mindful of memory allocations; use profiling tools (e.g., &lt;span class="sb"&gt;`pprof`&lt;/span&gt;) to optimize performance.
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`gofmt`&lt;/span&gt; for consistent formatting and &lt;span class="sb"&gt;`go vet`&lt;/span&gt; for static analysis.

&lt;span class="gu"&gt;## Error Handling&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Always check errors explicitly (e.g., &lt;span class="sb"&gt;`if err != nil`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Use descriptive error messages for debugging (e.g., &lt;span class="sb"&gt;`errors.New("failed to open file")`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Consider error wrapping with &lt;span class="sb"&gt;`fmt.Errorf`&lt;/span&gt; and &lt;span class="sb"&gt;`%w`&lt;/span&gt; for context (e.g., &lt;span class="sb"&gt;`fmt.Errorf("query failed: %w", err)`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Use &lt;span class="sb"&gt;`defer`&lt;/span&gt; with &lt;span class="sb"&gt;`recover`&lt;/span&gt; to handle panics in critical sections (e.g., HTTP handlers).

&lt;span class="gu"&gt;## Concurrency&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use goroutines for concurrent tasks (e.g., &lt;span class="sb"&gt;`go processData()`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Use channels for safe communication between goroutines (e.g., &lt;span class="sb"&gt;`ch := make(chan int)`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Avoid shared state when possible; prefer message passing via channels.

&lt;span class="gu"&gt;## Testing&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Write tests for all public functions using the &lt;span class="sb"&gt;`testing`&lt;/span&gt; package.
&lt;span class="p"&gt;-&lt;/span&gt; Use table-driven tests for multiple test cases (e.g., &lt;span class="sb"&gt;`tests := []struct{...}`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Aim for high test coverage with &lt;span class="sb"&gt;`go test -cover`&lt;/span&gt;.

&lt;span class="gu"&gt;## Documentation&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Write doc comments for all exported identifiers (e.g., &lt;span class="sb"&gt;`// UserService handles user operations`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Follow the standard Go doc format, starting with the identifier name (e.g., &lt;span class="sb"&gt;`// Package auth provides...`&lt;/span&gt;).
&lt;span class="p"&gt;-&lt;/span&gt; Include examples in doc comments when possible (e.g., &lt;span class="sb"&gt;`// Example: ...`&lt;/span&gt;).

&lt;span class="gu"&gt;## Patterns&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use interfaces for dependency injection to improve testability.
&lt;span class="p"&gt;-&lt;/span&gt; Implement the Repository pattern for data access (e.g., &lt;span class="sb"&gt;`UserRepository`&lt;/span&gt; interface).
&lt;span class="p"&gt;-&lt;/span&gt; Use the Factory pattern for object creation (e.g., &lt;span class="sb"&gt;`NewUserService()`&lt;/span&gt;).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the LLM to properly structure Go code, and its output is great! &lt;a href="https://gist.github.com/chand1012/05bbe89f2d41c2cc335f684f7281a2fa" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is some code generated using the rule.&lt;/p&gt;

&lt;p&gt;Here's another example of a project-level rule that I use for a Supabase backend project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
&lt;span class="na"&gt;globs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
&lt;span class="na"&gt;alwaysApply&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="gh"&gt;# Lancer DB&lt;/span&gt;

This is our monorepo for our Supabase Database migrations as well as our Supabase Edge Functions written in Deno.

&lt;span class="gu"&gt;## Directory Structure&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; docs/: Markdown documentation relevant to the repo and development.
&lt;span class="p"&gt;-&lt;/span&gt; supabase/: Contains all the Supabase related configurations, migrations, and edge functions.
&lt;span class="p"&gt;  -&lt;/span&gt; supabase/migrations/: Contains the migrations. All migrations names should be formatted like so: &lt;span class="sb"&gt;`20240821194157_subnets.sql`&lt;/span&gt;. That is a raw date with no spaces or formatting + &lt;span class="sb"&gt;`_`&lt;/span&gt; + followed by a snake case description of the migration.
&lt;span class="p"&gt;  -&lt;/span&gt; supabase/functions/: Contains Deno edge functions.
&lt;span class="p"&gt;    -&lt;/span&gt; supabase/functions/&lt;span class="ge"&gt;**&lt;/span&gt;/index.ts: Each of the main entrypoints for each edge function. Edge functions have folders which are their name, and any related files that the edge function uses that are not shared between functions should be included in the same directory as &lt;span class="sb"&gt;`index.ts`&lt;/span&gt;.
&lt;span class="p"&gt;    -&lt;/span&gt; supabase/functions/_shared/: Directory of all shared code that gets reused between multiple functions.
&lt;span class="p"&gt;  -&lt;/span&gt; supabase/seed.sql: Seed data for local development and testing only. If dummy data is needed for local testing, it should be added here.
&lt;span class="p"&gt;  -&lt;/span&gt; supabase/config.toml: Configuration data for the local Supabase instance for local dev and testing.
&lt;span class="p"&gt;-&lt;/span&gt; scripts/: Deno scripts for development and testing.
&lt;span class="p"&gt;-&lt;/span&gt; Justfile: Command runner script. Holds commands and bash scripts we use frequently as we work on the project. Automatically loads a &lt;span class="sb"&gt;`.env`&lt;/span&gt; if present. Commands can be run with &lt;span class="sb"&gt;`just &amp;lt;command name&amp;gt;`&lt;/span&gt;

&lt;span class="gu"&gt;## Code Style&lt;/span&gt;

&lt;span class="gu"&gt;### General Guidelines&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Follow DRY (DO NOT REPEAT YOURSELF)
&lt;span class="p"&gt;-&lt;/span&gt; Code should be well-named while following the case practices defined below for the language.
&lt;span class="p"&gt;-&lt;/span&gt; Code should be readable by human devs as well as LLMs alike.
&lt;span class="p"&gt;-&lt;/span&gt; Use meaningful variable and function names.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This basically just tells the LLM to follow the project's overall coding standards and file structure. In other repos, I've also linked other documentation that the LLM should know about via an &lt;code&gt;@&lt;/code&gt; symbol.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Rules
&lt;/h2&gt;

&lt;p&gt;Create a new file in the &lt;code&gt;.cursor/rules&lt;/code&gt; directory followed by &lt;code&gt;.mdc&lt;/code&gt; as the extension.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .cursor/rules
&lt;span class="nb"&gt;touch&lt;/span&gt; .cursor/rules/go.mdc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cursor will by default open the rule file using a special editor that allows you to set the rule type and globs without having to manually edit the front matter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjaub6s8lir0yee1s2p9e.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjaub6s8lir0yee1s2p9e.gif" alt="Cursor Rule Editor" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For manual and always apply rules, you can simply write the rule contents and save the file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw04eaprjibls6fa3j40m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw04eaprjibls6fa3j40m.png" alt=" " width="580" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For auto apply rules, you can use a glob pattern to apply the rule to all files that match the pattern.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4btn9dtbfk9ei6067av1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4btn9dtbfk9ei6067av1.png" alt=" " width="561" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For agent requested rules, you should write a good description of the rule and the conditions that should trigger the rule.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4c8440xkv1rkyeg7bdo3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4c8440xkv1rkyeg7bdo3.png" alt=" " width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that's done your rules are finished and will be loaded into context when you open Cursor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;Sometimes you'll need to link both internal and external documentation to the LLM. For internal documentation, such as a project's README, you can use the &lt;code&gt;@&lt;/code&gt; which will bring up a menu of files you can select from. You can start typing the name of the file you want to link to and it will filter down the list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwqkokhrslezk9r3h4sas.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwqkokhrslezk9r3h4sas.gif" alt=" " width="560" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For external documentation, you should link it via a markdown link.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuqc1eqm2ch3aragavwh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuqc1eqm2ch3aragavwh.gif" alt=" " width="562" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I've been using these rules for a while now and they've helped me write better code. I've also found that the LLM is able to follow the rules more often than not, and when it doesn't, it's usually because I need to update the rule to be more specific.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Command Line Power-Ups: Boost Your Workflow with Mods and Freeze</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Thu, 27 Jun 2024 23:05:53 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/command-line-power-ups-boost-your-workflow-with-mods-and-freeze-407j</link>
      <guid>https://dev.to/timesurgelabs/command-line-power-ups-boost-your-workflow-with-mods-and-freeze-407j</guid>
      <description>&lt;p&gt;For developers and tech enthusiasts, the command line is a powerful tool. But did you know there are ways to make it even more efficient and visually appealing? Two of my favorite tools I’ve been using lately are &lt;strong&gt;Mods&lt;/strong&gt; and &lt;strong&gt;Freeze&lt;/strong&gt;. These tools, brought to you by the innovative team at Charm Bracelet (charm.sh), will revolutionize how you interact with your terminal, automating tasks and creating beautiful code snippets. &lt;/p&gt;

&lt;h3&gt;
  
  
  Mods
&lt;/h3&gt;

&lt;p&gt;Imagine having the capabilities of ChatGPT directly in your command line. That's the power of Mods. This AI-driven tool excels at scripting and automation, allowing you to generate code snippets and streamline repetitive tasks with ease.&lt;/p&gt;

&lt;p&gt;Let's say you need a basic Python script to print "Hello World" with user input. With Mods, it's as simple as typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mods -f "Generate a python hello world app with user input. Only output the code and no other text" -r &amp;gt; test.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command instructs Mods to generate the code, output it in raw format (without Markdown), and save it to a file named &lt;code&gt;test.py&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Mods is still under development, so you might need to make minor adjustments to the output format. However, its ability to understand natural language commands and generate code is truly impressive. Plus, Mods remembers your conversation history, allowing you to reference previous commands and build upon your work seamlessly. &lt;/p&gt;

&lt;h3&gt;
  
  
  Freeze
&lt;/h3&gt;

&lt;p&gt;Sharing code snippets for documentation, presentations, or blog posts can be cumbersome. Freeze comes to the rescue, enabling you to generate visually stunning code screenshots with just a single command.&lt;/p&gt;

&lt;p&gt;To create a beautiful image of your Python script (&lt;code&gt;test.py&lt;/code&gt;), simply type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;freeze test.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a PNG image file showcasing your code with elegant syntax highlighting. Freeze also offers a range of customization options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--window&lt;/code&gt;&lt;/strong&gt;: Adds macOS-style window controls for a realistic look. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--theme&lt;/code&gt;&lt;/strong&gt;: Allows you to apply various themes like the popular GitHub dark mode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--execute&lt;/code&gt;&lt;/strong&gt;: Captures the output of terminal commands within the screenshot. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Freeze, you can effortlessly create professional-looking code visuals, enhancing your projects and communication.&lt;/p&gt;

&lt;p&gt;Mods and Freeze offer developers and tech enthusiasts powerful tools to enhance their productivity and creativity. Whether you're automating tasks, generating scripts, or creating eye-catching code visuals, these tools will streamline your workflow and elevate your projects. Explore these and other innovative command line tools to unlock the full potential of your terminal!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mods:&lt;/strong&gt; &lt;a href="https://github.com/charmbracelet/mods" rel="noopener noreferrer"&gt;https://github.com/charmbracelet/mods&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freeze:&lt;/strong&gt; &lt;a href="https://github.com/charmbracelet/freeze" rel="noopener noreferrer"&gt;https://github.com/charmbracelet/freeze&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What are your favorite command line tools? Share them in the comments below!&lt;/strong&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Video Tutorial - How To Run Llama 3 locally with Ollama and OpenWebUI!</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Thu, 16 May 2024 16:52:07 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/video-tutorial-how-to-run-llama-3-locally-with-ollama-and-openwebui-1dn1</link>
      <guid>https://dev.to/timesurgelabs/video-tutorial-how-to-run-llama-3-locally-with-ollama-and-openwebui-1dn1</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/GT-Fwg124-I"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Learn how to run LLaMA 3 locally on your computer using Ollama and Open WebUI! In this tutorial, we'll take you through a step-by-step guide on how to install and set up Ollama, and demonstrate the power of LLaMA 3 in action. Whether you're a developer, AI enthusiast, or just curious about the possibilities of local AI, this video is for you. So sit back, relax, and let's dive into the world of LLaMA 3, Ollama, and OpenWeb UI!&lt;/p&gt;

&lt;h3&gt;
  
  
  Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Recommended &lt;a href="https://youtu.be/eGz9DS-aIeY?feature=shared" rel="noopener noreferrer"&gt;Docker Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.openwebui.com" rel="noopener noreferrer"&gt;Open WebUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openwebui.com" rel="noopener noreferrer"&gt;Open WebUI Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Follow TimeSurge Labs!
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/TimeSurgeLabs" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/company/timesurge-labs" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/timesurgelabs"&gt;Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI Disclosure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Thumbnail Background by &lt;a href="https://openai.com/index/dall-e-3/" rel="noopener noreferrer"&gt;OpenAI Dalle 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Title and Description partially AI generated by Llama 3 on &lt;a href="https://console.groq.com/" rel="noopener noreferrer"&gt;GroqCloud&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;All music generated by &lt;a href="https://suno.com" rel="noopener noreferrer"&gt;Suno&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Video filmed and edited by &lt;a href="https://twitter.com/Chand1012Dev" rel="noopener noreferrer"&gt;Chandler&lt;/a&gt; (NOT AI).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Music Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://suno.com/song/73419c49-e237-47eb-8b11-c644e0384e8c" rel="noopener noreferrer"&gt;Putting In The Hours&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://suno.com/song/4fd4615d-43e1-45e8-bb7a-32cb10848cab" rel="noopener noreferrer"&gt;The Chase Scene&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://suno.com/song/e213b6a8-6785-409d-a869-cdd60f66d72e" rel="noopener noreferrer"&gt;TimeSurge Labs Outro&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>ai</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Said Goodbye to ChatGPT and Hello to Llama 3 on Open WebUI - You Should Too</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Wed, 24 Apr 2024 18:29:03 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/i-said-goodbye-to-chatgpt-and-hello-to-llama-3-on-open-webui-you-should-too-4g6k</link>
      <guid>https://dev.to/timesurgelabs/i-said-goodbye-to-chatgpt-and-hello-to-llama-3-on-open-webui-you-should-too-4g6k</guid>
      <description>&lt;p&gt;I’m a huge fan of open source models, especially the newly release &lt;a href="https://llama.meta.com/llama3/" rel="noopener noreferrer"&gt;Llama 3&lt;/a&gt;. Because of the performance of both the large 70B Llama 3 model as well as the smaller and self-host-able 8B Llama 3, I’ve actually cancelled my ChatGPT subscription in favor of &lt;a href="https://docs.openwebui.com/" rel="noopener noreferrer"&gt;Open WebUI&lt;/a&gt;, a self-hostable ChatGPT-like UI that allows you to use &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; and other AI providers while keeping your chat history, prompts, and other data locally on any computer you control.&lt;/p&gt;

&lt;p&gt;My &lt;a href="https://dev.to/timesurgelabs/how-to-run-llama-3-locally-with-ollama-and-open-webui-297d"&gt;previous article&lt;/a&gt; went over how to get Open WebUI set up with &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; and Llama 3, however this isn’t the only way I take advantage of Open WebUI. The other way I use it is with external API providers, of which I use three. I’ll go over each of them with you and given you the pros and cons of each, then I’ll show you how I set up all 3 of them in my Open WebUI instance!&lt;/p&gt;

&lt;h2&gt;
  
  
  External AIs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  OpenAI
&lt;/h3&gt;

&lt;p&gt;OpenAI can either be considered the classic or the monopoly. Their AI tech is the most mature, and trades blows with the likes of Anthropic and Google. Even though Llama 3 70B (and even the smaller 8B model) is good enough for 99% of people and tasks, sometimes you just need the best, so I like having the option either to just quickly answer my question or even use it along side other LLMs to quickly get options for an answer. &lt;/p&gt;

&lt;p&gt;OpenAI is the example that is most often used throughout the Open WebUI docs, however they can support any number of OpenAI-compatible APIs. Here’s another favorite of mine that I now use even more than OpenAI!&lt;/p&gt;

&lt;h3&gt;
  
  
  Groq Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://wow.groq.com/why-groq/" rel="noopener noreferrer"&gt;Groq&lt;/a&gt; is an AI hardware and infrastructure company that’s developing their own hardware LLM chip (which they call &lt;a href="https://wow.groq.com/groq-lpu-inference-engine-crushes-first-public-llm-benchmark/" rel="noopener noreferrer"&gt;an LPU&lt;/a&gt;). They offer an API to use their new LPUs with a number of open source LLMs (including Llama 3 8B and 70B) on their &lt;a href="https://console.groq.com" rel="noopener noreferrer"&gt;GroqCloud platform&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Their claim to fame is their insanely fast inference times - sequential token generation in the hundreds per second for 70B models and thousands for smaller models. Here’s Llama 3 70B running in real time on Open WebUI.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1782783466406322202-998" src="https://platform.twitter.com/embed/Tweet.html?id=1782783466406322202"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1782783466406322202-998');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1782783466406322202&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Here’s the best part - GroqCloud is &lt;strong&gt;free&lt;/strong&gt; for most users. With no credit card input, they’ll grant you some pretty high rate limits, significantly higher than most AI API companies allow. Here’s the limits for my newly created account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff628pyddn7ssjp8ay4kk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff628pyddn7ssjp8ay4kk.png" alt="API Example" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;14k requests per day is a lot, and 12k tokens per minute is significantly higher than the average person can use on an interface like Open WebUI. &lt;/p&gt;

&lt;p&gt;Using GroqCloud with Open WebUI is possible thanks to an &lt;a href="https://console.groq.com/docs/openai" rel="noopener noreferrer"&gt;OpenAI-compatible API&lt;/a&gt; that Groq provides. All you have to do is generate an API Key &lt;a href="https://console.groq.com/keys" rel="noopener noreferrer"&gt;via the dashboard&lt;/a&gt;, change the URL in the dashboard to &lt;code&gt;https://api.groq.com/openai/v1&lt;/code&gt;, and it’ll work just like OpenAI’s API!&lt;/p&gt;

&lt;p&gt;This is how I was able to use and evaluate Llama 3 as my replacement for ChatGPT!&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloudflare Workers AI
&lt;/h3&gt;

&lt;p&gt;This is the part where I toot my own horn a little. Using Open WebUI via Cloudflare Workers is not natively possible, however I developed my own &lt;a href="https://github.com/chand1012/openai-cf-workers-ai" rel="noopener noreferrer"&gt;OpenAI-compatible API for Cloudflare Workers&lt;/a&gt; a few months ago. I recently &lt;a href="https://github.com/chand1012/openai-cf-workers-ai/pull/8" rel="noopener noreferrer"&gt;added the &lt;code&gt;/models&lt;/code&gt; endpoint&lt;/a&gt; to it to make it compable with Open WebUI, and its been working great ever since. The main advantage of using Cloudflare Workers over something like GroqCloud is their &lt;a href="https://developers.cloudflare.com/workers-ai/models/#text-generation" rel="noopener noreferrer"&gt;massive variety of models&lt;/a&gt;. This allows you to test out many models quickly and effectively for many use cases, such as &lt;a href="https://developers.cloudflare.com/workers-ai/models/deepseek-math-7b-instruct/" rel="noopener noreferrer"&gt;DeepSeek Math&lt;/a&gt; (&lt;a href="https://huggingface.co/deepseek-ai/deepseek-math-7b-instruct" rel="noopener noreferrer"&gt;model card&lt;/a&gt;) for math-heavy tasks and &lt;a href="https://developers.cloudflare.com/workers-ai/models/llamaguard-7b-awq/" rel="noopener noreferrer"&gt;Llama Guard&lt;/a&gt; (&lt;a href="https://huggingface.co/meta-llama/LlamaGuard-7b" rel="noopener noreferrer"&gt;model card&lt;/a&gt;) for moderation tasks. They even support &lt;a href="https://developers.cloudflare.com/workers-ai/models/llama-3-8b-instruct/" rel="noopener noreferrer"&gt;Llama 3 8B&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;The main con of Workers AI is token limits and model size. Currently Llama 3 8B is the largest model supported, and they have &lt;a href="https://developers.cloudflare.com/workers-ai/models/llama-2-7b-chat-int8/#properties" rel="noopener noreferrer"&gt;token generation limits&lt;/a&gt; much smaller than some of the models available. I still think they’re worth having in this list due to the sheer variety of models they have available with no setup on your end other than of the API. If you want to set up OpenAI for Workers AI yourself, check out &lt;a href="https://github.com/chand1012/openai-cf-workers-ai?tab=readme-ov-file#deploying" rel="noopener noreferrer"&gt;the guide in the README&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding External AIs to Open WebUI
&lt;/h2&gt;

&lt;p&gt;Now, how do you add all these to your Open WebUI instance? Assuming you’ve installed Open WebUI (&lt;a href="https://docs.openwebui.com/getting-started/" rel="noopener noreferrer"&gt;Installation Guide&lt;/a&gt;), the best way is via environment variables.&lt;/p&gt;

&lt;p&gt;When running Open WebUI using Docker, you can set the &lt;code&gt;OPENAI_API_BASE_URLS&lt;/code&gt; and &lt;code&gt;OPENAI_API_KEYS&lt;/code&gt; environment variables to configure the API endpoints.&lt;/p&gt;

&lt;p&gt;For example, to integrate OpenAI, GroqCloud, and Cloudflare Workers AI, you would set the environment variables as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; open-webui:/app/backend/data &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;OPENAI_API_BASE_URLS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://api.openai.com/v1;https://api.groq.com/openai/v1;https://openai-cf.yourusername.workers.dev/v1"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;OPENAI_API_KEYS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"sk-proj-ABCDEFGHIJK1234567890abcdef;gsk_1234567890abcdefabcdefghij;0123456789abcdef0123456789abcdef"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; open-webui &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt; always &lt;span class="se"&gt;\&lt;/span&gt;
  ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;sk-proj-ABCDEFGHIJK1234567890abcdef&lt;/code&gt;, &lt;code&gt;gsk_1234567890abcdefabcdefghij&lt;/code&gt;, and &lt;code&gt;0123456789abcdef0123456789abcdef&lt;/code&gt; with your actual API keys. Make sure to put the keys for each API in the same order as their respective API. If you don’t, you’ll get errors saying that the APIs could not authenticate.&lt;/p&gt;

&lt;p&gt;When using Docker Compose, you can define the environment variables in your &lt;code&gt;docker-compose.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;open-webui&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_BASE_URLS=${OPENAI_API_BASE_URLS}'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEYS=${OPENAI_API_KEYS}'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, you can define the values of these variables in an &lt;code&gt;.env&lt;/code&gt; file, placed in the same directory as the &lt;code&gt;docker-compose.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;OPENAI_API_BASE_URLS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://api.openai.com/v1;https://api.groq.com/openai/v1;https://openai-cf.yourusername.workers.dev/v1"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;OPENAI_API_KEYS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"sk-proj-ABCDEFGHIJK1234567890abcdef;gsk_1234567890abcdefabcdefghij;0123456789abcdef0123456789abcdef"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By following these steps, you can easily integrate multiple OpenAI-compatible APIs with your Open WebUI instance, unlocking the full potential of these powerful AI models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Open WebUI has opened up a whole new world of possibilities for me, allowing me to take control of my AI experiences and explore the vast array of OpenAI-compatible APIs out there. With the ability to seamlessly integrate multiple APIs, including OpenAI, Groq Cloud, and Cloudflare Workers AI, I've been able to unlock the full potential of these powerful AI models. By leveraging the flexibility of Open WebUI, I've been able to break free from the shackles of proprietary chat platforms and take my AI experiences to the next level. If you're tired of being limited by traditional chat platforms, I highly recommend giving Open WebUI a try and discovering the vast possibilities that await you.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ai</category>
      <category>productivity</category>
      <category>api</category>
    </item>
    <item>
      <title>How to Run Llama 3 Locally with Ollama and Open WebUI</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Sun, 21 Apr 2024 14:26:46 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/how-to-run-llama-3-locally-with-ollama-and-open-webui-297d</link>
      <guid>https://dev.to/timesurgelabs/how-to-run-llama-3-locally-with-ollama-and-open-webui-297d</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/GT-Fwg124-I"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I’m a big fan of Llama. Meta releasing their LLM open source is a net benefit for the tech community at large, and their permissive license allows most medium and small businesses to use their LLMs with little to no restrictions (within the bounds of the law, of course). Their latest release is Llama 3, which has been highly anticipated.&lt;/p&gt;

&lt;p&gt;Llama 3 comes in two sizes: 8 billion and 70 billion parameters. This kind of model is trained on a massive amount of text data and can be used for a variety of tasks, including generating text, translating languages, writing different kinds of creative content, and answering your questions in an informative way. Meta touts Llama 3 as one of the best open models available, but it is still under development. Here’s the 8B model benchmarks when compared to Mistral and Gemma (according to Meta).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fax9r9z2w2zghv81grbh7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fax9r9z2w2zghv81grbh7.png" alt="Benchmarks" width="800" height="899"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This begs the question: how can I, the regular individual, run these models locally on my computer?&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with Ollama
&lt;/h2&gt;

&lt;p&gt;That’s where &lt;a href="https://ollama.com/" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; comes in! Ollama is a free and open-source application that allows you to run various large language models, including Llama 3, on your own computer, even with limited resources. Ollama takes advantage of the performance gains of llama.cpp, an open source library designed to allow you to run LLMs locally with relatively low hardware requirements. It also includes a sort of package manager, allowing you to download and use LLMs quickly and effectively with just a single command. &lt;/p&gt;

&lt;p&gt;The first step is &lt;a href="https://ollama.com/download" rel="noopener noreferrer"&gt;installing Ollama&lt;/a&gt;. It supports all 3 of the major OSes, with &lt;a href="https://ollama.com/blog/windows-preview" rel="noopener noreferrer"&gt;Windows being a “preview”&lt;/a&gt; (nicer word for beta).&lt;/p&gt;

&lt;p&gt;Once this is installed, open up your terminal. On all platforms, the command is the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run llama3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait a few minutes while it downloads and loads the model, and then start chatting! It should bring you to a chat prompt similar to this one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama run llama3
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; Who was the second president of the united states?
The second President of the United States was John Adams. He served from 1797 to 1801, succeeding
George Washington and being succeeded by Thomas Jefferson.

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; Who was the 30th?
The 30th President of the United States was Calvin Coolidge! He served from August 2, 1923, to March 4,
1929.

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; /bye
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can chat all day within this terminal chat, but what if you want something more ChatGPT-like?  &lt;/p&gt;

&lt;h2&gt;
  
  
  Open WebUI
&lt;/h2&gt;

&lt;p&gt;Open WebUI is an extensible, self-hosted UI that runs entirely inside of &lt;a href="https://docs.docker.com/desktop/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;. It can be used either with Ollama or other OpenAI compatible LLMs, like LiteLLM or my own &lt;a href="https://github.com/chand1012/openai-cf-workers-ai" rel="noopener noreferrer"&gt;OpenAI API for Cloudflare Workers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Assuming you already have &lt;a href="https://docs.docker.com/desktop/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; and Ollama running on your computer, &lt;a href="https://docs.openwebui.com/getting-started/#quick-start-with-docker-" rel="noopener noreferrer"&gt;installation&lt;/a&gt; is super simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:8080 &lt;span class="nt"&gt;--add-host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host.docker.internal:host-gateway &lt;span class="nt"&gt;-v&lt;/span&gt; open-webui:/app/backend/data &lt;span class="nt"&gt;--name&lt;/span&gt; open-webui &lt;span class="nt"&gt;--restart&lt;/span&gt; always ghcr.io/open-webui/open-webui:main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The simply go to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;, make an account, and start chatting away!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdi1d35zh09s78o8vqvb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdi1d35zh09s78o8vqvb.png" alt="OpenWebUI Example" width="800" height="1169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you didn’t run Llama 3 earlier, you’ll have to pull some models down before you can start chatting. Easiest way to do this is to click the settings icon after clicking your name in the bottom left.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqyetksyn0y4a0p12ylu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftqyetksyn0y4a0p12ylu.png" alt="Settings" width="634" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then clicking on “models” on the left side of the modal, then pasting in a name of a model from the &lt;a href="https://ollama.com/models" rel="noopener noreferrer"&gt;Ollama registry&lt;/a&gt;. Here are some models that I’ve used that I recommend for general purposes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;llama3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mistral&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;llama2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxc581jf4w3xszymjfbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxc581jf4w3xszymjfbg.png" alt="Models Setting Page" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Ollama API
&lt;/h2&gt;

&lt;p&gt;If you want to integrate Ollama into your own projects, Ollama offers both its own API as well as an OpenAI Compatible API. The APIs automatically load a locally held LLM into memory, run the inference, then unload after a certain timeout. You do have to pull whatever models you want to use before you can run the model via the API, which can easily be done via the command line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ollama pull mistral
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ollama API
&lt;/h3&gt;

&lt;p&gt;Ollama has their own API available, which also has a &lt;a href="https://github.com/ollama/ollama?tab=readme-ov-file#libraries" rel="noopener noreferrer"&gt;couple of SDKs&lt;/a&gt; for Javascript and Python.&lt;/p&gt;

&lt;p&gt;Here is how you can do a simple text generation inference with the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:11434/api/generate &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
  "model": "mistral",
  "prompt":"Why is the sky blue?"
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here’s how you can do a Chat generation inference with the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:11434/api/chat &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
  "model": "mistral",
  "messages": [
    { "role": "user", "content": "why is the sky blue?" }
  ]
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the &lt;code&gt;model&lt;/code&gt; parameter with whatever model you want to use. See the &lt;a href="https://github.com/ollama/ollama/blob/main/docs/api.md" rel="noopener noreferrer"&gt;official API docs&lt;/a&gt; for more information.&lt;/p&gt;

&lt;h3&gt;
  
  
  OpenAI Compatible API
&lt;/h3&gt;

&lt;p&gt;You can also use Ollama as a drop in replacement (depending on use case) with the OpenAI libraries. Here’s an example from &lt;a href="https://github.com/ollama/ollama/blob/main/docs/openai.md" rel="noopener noreferrer"&gt;their documentation&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Python
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http://localhost:11434/v1/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;# required but ignored
&lt;/span&gt;    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ollama&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;chat_completion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Say this is a test&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mistral&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This also works for Javascript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Javascript&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OpenAI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:11434/v1/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="c1"&gt;// required but ignored&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ollama&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chatCompletion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Say this is a test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;llama2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The release of Meta's Llama 3 and the open-sourcing of its Large Language Model (LLM) technology mark a major milestone for the tech community. With these advanced models now accessible through local tools like Ollama and Open WebUI, ordinary individuals can tap into their immense potential to generate text, translate languages, craft creative writing, and more. Furthermore, the availability of APIs enables developers to seamlessly integrate LLMs into new projects or enhance existing ones. Ultimately, the democratization of LLM technology through open-source initiatives like Llama 3 unlocks a vast realm of innovative possibilities and fuels creativity in the tech industry.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ai</category>
      <category>productivity</category>
      <category>api</category>
    </item>
    <item>
      <title>Building a Fast, Efficient Web App: The Technology Stack of PromptSmithy Explained</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Tue, 26 Mar 2024 17:08:07 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/building-a-fast-efficient-web-app-the-technology-stack-of-promptsmithy-explained-184f</link>
      <guid>https://dev.to/timesurgelabs/building-a-fast-efficient-web-app-the-technology-stack-of-promptsmithy-explained-184f</guid>
      <description>&lt;p&gt;I’ve written a lot of one-off project, internal scripts for my own use, B2C apps, B2B apps, and everything in between. Every time I start a new project I like to use a new stack to try and diversify my own skillset, and so that if I’m ever tasked with doing another similar project in the future, my knowledge can accelerate my workflow. &lt;a href="https://promptsmithy.com/" rel="noopener noreferrer"&gt;PromptSmithy&lt;/a&gt; was slightly different though, as the stack hadn’t changed from other recent projects of mine, however the frontend tooling did greatly. In this article I’m going to break down the stack we used and talk about the new development flow we used for rapid development.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  React + Vite + React Router
&lt;/h3&gt;

&lt;p&gt;We all know what &lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt; is at this point, but why use it with &lt;a href="https://vitejs.dev/" rel="noopener noreferrer"&gt;Vite&lt;/a&gt; and &lt;a href="https://reactrouter.com/en/main" rel="noopener noreferrer"&gt;React Router DOM&lt;/a&gt; over something like &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NextJS&lt;/a&gt;? &lt;/p&gt;

&lt;p&gt;The reasons are twofold: We didn’t need any of the backend functionality of NextJS, and I wanted something that wouldn’t get in the way of our development with SSR or any other special cases that are only found on NextJS.&lt;/p&gt;

&lt;p&gt;On top of that, Vite’s compiler is super fast, supports &lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;Typescript&lt;/a&gt; (which we of course used), and built just fine on our host, which was &lt;a href="https://pages.cloudflare.com/" rel="noopener noreferrer"&gt;Cloudflare Pages. Cloudflare Pages&lt;/a&gt; is a super fast static website hosting service by Cloudflare, which allows your site to take advantage of their global CDN to make sure your site is as close to your users as possible. It supports nearly any JS framework you could want to use for your site, and can even host plan old HTML if you’re of that persuasion.&lt;/p&gt;

&lt;p&gt;React Router is also super minimal and doesn’t get in the way, and provides all the same functionality of NextJS’s static output router without making your compile sizes massive. Our entire built site (before we added all the fancy physics animations) was just a bit over 135KB. &lt;/p&gt;

&lt;h3&gt;
  
  
  Tailwind + shadcn/ui + v0.dev
&lt;/h3&gt;

&lt;p&gt;For development of the UI components, we tried something new. Vercel has this new AI tool called &lt;a href="http://v0.dev" rel="noopener noreferrer"&gt;v0.dev&lt;/a&gt; that allows developers to take advantage of &lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;shadcn/ui&lt;/a&gt; and &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt; using nothing but words, which can then be easily downloaded to your local project using nothing but a simple &lt;code&gt;npx&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxoy51g12efo45ozzr77.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxoy51g12efo45ozzr77.png" alt="Here is the original example code for a 404 page that I ended up using in the final app!" width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://v0.dev/t/RB8eJs2Kd6R" rel="noopener noreferrer"&gt;original example code&lt;/a&gt; for a 404 page that I ended up using in the final app! &lt;code&gt;npx v0 add RB8eJs2Kd6R&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;While I have experience with Tailwind and frontend development, I don’t really have the patience to use it. I usually end up using something like &lt;a href="https://mantine.dev/" rel="noopener noreferrer"&gt;Mantine&lt;/a&gt;, which is a complete component library UI kit, or &lt;a href="https://daisyui.com/" rel="noopener noreferrer"&gt;Daisy UI&lt;/a&gt;, which is a component library built on top of Tailwind. Shadcn/ui is quite similar to Daisy in this sense, but being able to customize the individual components, since they get installed to your components folder, made development more streamlined and more customizable. On top of that being able to change my components style with natural language thanks to v0 made development super easy and fast. Shadcn may be too minimalist of a style for some, but thanks to all the components being local, you can customize them quickly and easily!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsijgkghiwn9ibl4bru0x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsijgkghiwn9ibl4bru0x.png" alt="This is the structure of the project’s components directory" width="746" height="740"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the structure of the project’s components directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supabase
&lt;/h3&gt;

&lt;p&gt;Here the thing that accelerated my development the most: &lt;a href="https://supabase.com/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;. Thanks to its Database, Authentication, and Edge Functions, we were able to rapidly develop the app. Their JS library made development super seamless, and their local development stack made testing a breeze. &lt;/p&gt;

&lt;p&gt;The development process is simple: install their &lt;a href="https://supabase.com/docs/guides/cli" rel="noopener noreferrer"&gt;CLI&lt;/a&gt;,  run &lt;code&gt;supabase init&lt;/code&gt;, run &lt;code&gt;supabase start&lt;/code&gt;. That’s it. (Assuming you have Docker installed that is.)&lt;/p&gt;

&lt;p&gt;The database service is pretty self explanatory. Rather than having to write SQL queries in a remote API, hosting that API as well as the database to go with it, you simply create tables with migrations (created using &lt;code&gt;supabase migrations new name_here&lt;/code&gt;), then you can query the migrations using the frontend API. From there you can configure row level security, which restricts access to specific rows on a per user basis, using either the migrations themselves or using the local UI. I opted for the former so that I could easily apply the migrations. Here is one I wrote for the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;bigint&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="k"&gt;generated&lt;/span&gt; &lt;span class="n"&gt;always&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;metaprompt_id&lt;/span&gt; &lt;span class="nb"&gt;bigint&lt;/span&gt; &lt;span class="k"&gt;references&lt;/span&gt; &lt;span class="n"&gt;metaprompts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;variables&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt; &lt;span class="k"&gt;zone&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt; &lt;span class="k"&gt;zone&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nb"&gt;boolean&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;alter&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt;
  &lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt; &lt;span class="k"&gt;level&lt;/span&gt; &lt;span class="k"&gt;security&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="nv"&gt;"Users can insert their own prompts"&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="k"&gt;check&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="nv"&gt;"Users can read their own prompts that are private"&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="nv"&gt;"Users can read all prompts that are public"&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This then got applied locally by running &lt;code&gt;supabase db reset&lt;/code&gt;, and deployed remotely with &lt;code&gt;supabase db push&lt;/code&gt;. We could then query on the frontend using the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prompts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;created_at&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;ascending&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see &lt;a href="https://supabase.com/docs/guides/getting-started/quickstarts/reactjs" rel="noopener noreferrer"&gt;Supabase’s excellent guides&lt;/a&gt; on how to do this for more information.&lt;/p&gt;

&lt;p&gt;We also took advantage of Supabase’s Authentication service that allows us to quickly and effectively log in a user so we can handle authenticated requests (which once Row Level Security is set up is automatic) quickly. Since this was a weekend project sort of app, we went with Supabase Magic Links, which allows our users to log in by simply entering their email and clicking a link that gets sent. Here’s all the code to do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;me@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signInWithOtp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! Then all we had to do is have the user click the link (assuming your website URL is configured properly in the Supabase settings) and they were logged in!&lt;/p&gt;

&lt;p&gt;Finally we used Supabase Edge Functions to handle payments with Stripe, as well as hold the business logic of PromptSmithy, which primarily just calling Anthropic AI. Edge Functions are written in Deno, which is a NodeJS alternative that I like very much. You create a new edge function by running &lt;code&gt;supabase functions new name_here&lt;/code&gt; and then deploying with &lt;code&gt;supabase functions deploy&lt;/code&gt; . You can also run these functions locally for testing (which is what we did along with the Stripe CLI’s webhook feature) with &lt;code&gt;supabase functions serve&lt;/code&gt; . &lt;/p&gt;

&lt;p&gt;Calling your functions on the frontend is super simple too. Whenever we wanted to call the AI, this is the code we run on the frontend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Write me an email response to my boss asking for a raise&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;create-task-prompt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;public&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;metapromptID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The value of &lt;code&gt;resp&lt;/code&gt; would be whatever we responded with, which is always JSON for our application. &lt;/p&gt;

&lt;p&gt;Functions can also be invoked by remote applications, for example Stripe webhooks. If you want this, you’ll need to make sure that JWT verification is disabled for that function, which can be done simply in the &lt;code&gt;config.toml&lt;/code&gt; in the &lt;code&gt;supabase&lt;/code&gt;  directory of your project. Here’s an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[functions.stripe-webhook]&lt;/span&gt;
&lt;span class="py"&gt;verify_jwt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now whenever this function is deployed you can check your Edge Functions page for a URL to give to Stripe!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, our choice of stack for PromptSmithy’s project was primarily based on the speed of development and the performance of the end product. Using tools like Vite, React, Supabase, and the innovative v0.dev, we were able to develop rapidly and effectively, resulting in a highly functional and efficient application.&lt;/p&gt;

&lt;p&gt;Want to give &lt;a href="https://promptsmithy.com/" rel="noopener noreferrer"&gt;PromptSmithy&lt;/a&gt; a try? All new users get &lt;strong&gt;$5 in free credits!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>productivity</category>
    </item>
    <item>
      <title>🦉 AthenaDB: Distributed Vector Database Powered by Cloudflare 🌩️</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Mon, 19 Feb 2024 18:47:15 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/athenadb-distributed-vector-database-powered-by-cloudflare-4p59</link>
      <guid>https://dev.to/timesurgelabs/athenadb-distributed-vector-database-powered-by-cloudflare-4p59</guid>
      <description>&lt;h2&gt;
  
  
  What is AthenaDB?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/TimeSurgeLabs/athenadb" rel="noopener noreferrer"&gt;AthenaDB&lt;/a&gt; is a serverless vector database designed to be highly distributed and easily accessible as an API. It leverages &lt;a href="https://developers.cloudflare.com/workers-ai/" rel="noopener noreferrer"&gt;Cloudflare’s Workers AI&lt;/a&gt; platform to create the vectors, &lt;a href="https://developers.cloudflare.com/vectorize/" rel="noopener noreferrer"&gt;Cloudflare Vectorize&lt;/a&gt; for handling vector querying, and &lt;a href="https://developers.cloudflare.com/d1/" rel="noopener noreferrer"&gt;Cloudflare D1&lt;/a&gt; as its database for storing text. This combination allows AthenaDB to offer a simple yet powerful set of API endpoints for inserting, querying, retrieving, and deleting vector text data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features of AthenaDB
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple API Endpoints&lt;/strong&gt;: AthenaDB provides straightforward endpoints for various database operations, making it accessible for developers of all skill levels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distributed Nature&lt;/strong&gt;: With data replication across multiple data centers, AthenaDB ensures high availability and resilience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-In Data Replication&lt;/strong&gt;: Due to Cloudflare Workers’ underlying architecture, data is replicated across data centers automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: AthenaDB is designed to handle large amounts of vector text data, making it suitable for projects with high data volumes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless Architecture&lt;/strong&gt;: With AthenaDB being serverless, you don't have to worry about managing infrastructure, allowing for more focus on development.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Are Vector Databases?
&lt;/h2&gt;

&lt;p&gt;Vector databases are a special kind of computer storage that helps artificial intelligence (AI) programs quickly understand and use information. They work by turning data into numbers (called vectors) that the AI can easily compare to find similarities. This is really useful for things like online searches, suggesting products you might like, or creating smart chatbots. &lt;/p&gt;

&lt;p&gt;For example, if a vector database has the following three items: “Python is cool”, “Java is cool”, and “C is statically typed”, and the user uses a search query “coffee”, it would return “Java is cool”. Why? Because while the user may not have been talking about the programming language Java, the words “java” and “coffee” have similar root meaning, which the neural network that created the vectors relates using complex math. &lt;/p&gt;

&lt;p&gt;You can learn more about them &lt;a href="https://www.cloudflare.com/learning/ai/what-is-vector-database/" rel="noopener noreferrer"&gt;in this article&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Cloudflare?
&lt;/h2&gt;

&lt;p&gt;Cloudflare has a serverless compute platform called &lt;a href="https://workers.cloudflare.com/" rel="noopener noreferrer"&gt;Workers&lt;/a&gt;. Workers are automatically replicated across all Cloudflare data centers, meaning that the developer can make an API or other application that automatically scales with zero infrastructure! Workers also automatically routes user requests to their nearest data center, meaning that latency is reduced significantly!&lt;/p&gt;

&lt;p&gt;By using this, it means AthenaDB gets many of the features of Cloudflare’s Platform - Data replication, distribution across data centers, and an infinitely scalable serverless architecture - with no complicated code base or management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with AthenaDB
&lt;/h2&gt;

&lt;p&gt;Deploying and using AthenaDB involves a few steps, starting from setting up your environment to deploying your instance of AthenaDB.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before you begin, make sure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloudflare account&lt;/li&gt;
&lt;li&gt;Node.js and npm installed&lt;/li&gt;
&lt;li&gt;Wrangler CLI installed (&lt;code&gt;npm install -g @cloudflare/wrangler&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Clone the Repository&lt;/strong&gt;: Start by cloning the AthenaDB repository to your local machine, installing dependencies, and logging in to Wrangler.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/TimeSurgeLabs/athenadb.git
&lt;span class="nb"&gt;cd &lt;/span&gt;athenadb
npm i
npx wrangler login
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a Vector and Database&lt;/strong&gt;: Use the provided npm scripts to create a vector and database for your AthenaDB instance.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run create-vector
npm run create-db
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;After running these commands, copy the output Database ID and update the &lt;code&gt;wrangler.toml&lt;/code&gt; file under &lt;code&gt;database_id&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize the Database&lt;/strong&gt;: Run the initialization script to set up the database schema.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run init-db
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deploy AthenaDB&lt;/strong&gt;: Finally, deploy your instance of AthenaDB using Wrangler.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run deploy
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Upon successful deployment, you will receive an output with your API URL, which indicates that AthenaDB is now ready for use.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Using AthenaDB
&lt;/h3&gt;

&lt;p&gt;With AthenaDB deployed, you can start interacting with the database through its API endpoints. Here are some examples of how you can use AthenaDB:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inserting Text Data&lt;/strong&gt;: Use the &lt;code&gt;/insert&lt;/code&gt; endpoint to add text data into the database.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://athenadb.yourusername.workers.dev/your-namespace/insert&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your text here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Querying the Database&lt;/strong&gt;: To find similar text embeddings, use the &lt;code&gt;/query&lt;/code&gt; endpoint.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://athenadb.yourusername.workers.dev/your-namespace/query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Query text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Retrieving an Entry&lt;/strong&gt;: Retrieve specific entries using their UUID with the &lt;code&gt;GET&lt;/code&gt; endpoint.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://athenadb.yourusername.workers.dev/your-namespace/your-uuid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deleting Data&lt;/strong&gt;: Use the &lt;code&gt;/delete&lt;/code&gt; endpoint to remove data from the database.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://athenadb.yourusername.workers.dev/your-namespace/your-uuid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DELETE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AthenaDB stands out as a powerful tool for developers needing a scalable, serverless database solution for managing vector text data. By following the steps outlined in this blog post, you can deploy your own instance of AthenaDB and begin leveraging its capabilities for your projects. Whether you're building search engines, recommendation systems, or any application that requires efficient handling of vector data, AthenaDB provides a robust, easy-to-use solution.&lt;/p&gt;

&lt;p&gt;If you’re looking to integrate AI into your existing workflow or products, &lt;a href="https://timesurgelabs.com/" rel="noopener noreferrer"&gt;TimeSurge Labs&lt;/a&gt; is here to help. Specializing in AI consulting, development, internal tooling, and LLM hosting, our team of passionate AI experts is dedicated to building the future of AI and helping your business thrive in this rapidly changing industry. &lt;a href="https://timesurgelabs.com/#contact" rel="noopener noreferrer"&gt;Contact us&lt;/a&gt; today!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>database</category>
      <category>cloud</category>
      <category>serverless</category>
    </item>
    <item>
      <title>How I Use Google's Gemini Pro with LangChain</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Thu, 04 Jan 2024 17:00:26 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/how-to-use-googles-gemini-pro-with-langchain-1eje</link>
      <guid>https://dev.to/timesurgelabs/how-to-use-googles-gemini-pro-with-langchain-1eje</guid>
      <description>&lt;p&gt;Google's Gemini Pro is one of the newest LLMs publicly available, and to the surprise of some its relatively price competitive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvin3nlq60w8hd6m2wc99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvin3nlq60w8hd6m2wc99.png" alt="Gemini Pro Pricing" width="800" height="816"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Its effectively free while you're developing, and after you development is complete its relatively cheap, costing around $0.00025 per 1K characters (&lt;strong&gt;characters&lt;/strong&gt;, not &lt;strong&gt;tokens&lt;/strong&gt; like OpenAI), which is slightly more expensive than GPT-3.5-Turbo, and $0.0025 per image, which is effectively the same as OpenAI's GPT-4).&lt;/p&gt;

&lt;h2&gt;
  
  
  Okay, I get it, how do I use it?
&lt;/h2&gt;

&lt;p&gt;Let's start fresh with a new project. Assuming you're using Python &amp;gt;= 3.10, let's initialize a new virtual environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="nb"&gt;env
source env&lt;/span&gt;/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And let's install LangChain and our dotenv file loader first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install langchain python-dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that's done, we can install Gemini Pro's libraries and its LangChain adapter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install google-generativeai langchain-google-genai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next you need to acquire an API key, which can be done on the &lt;a href="https://makersuite.google.com" rel="noopener noreferrer"&gt;Google MakerSuite&lt;/a&gt;. In the top left of the page you should see a "Get API Key" button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9icwjzh0oco2n5d0zgl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9icwjzh0oco2n5d0zgl.png" alt="API Key Button" width="620" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click that button, then click "Create API Key in new project". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiw4uv7wwo2baq2ge5rim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiw4uv7wwo2baq2ge5rim.png" alt="New Key Button" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the new API Key and save it to a .env file in your project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GOOGLE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;new_api_key_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can create a script that calls Gemini Pro via LangChain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_google_genai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatGoogleGenerativeAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;GOOGLE_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOGLE_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatGoogleGenerativeAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-pro&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;google_api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;GOOGLE_API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tweet_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a content creator. Write me a tweet about {topic}.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tweet_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tweet_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;how ai is really cool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tweet_chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! You've now integrated Gemini Pro with LangChain! If you're interested in learning more about LangChain and AI, follow us here on Dev.to as well as on &lt;a href="https://twitter.com/TimeSurgeLabs" rel="noopener noreferrer"&gt;X&lt;/a&gt;! I also post a lot of AI and developer stuff on my &lt;a href="https://twitter.com/Chand1012Dev" rel="noopener noreferrer"&gt;personal X account&lt;/a&gt;! We also have more articles on LangChain an AI on &lt;a href="https://dev.to/timesurgelabs"&gt;our Dev Page&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Happy coding! &lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Llamafile: AI Integration &amp; Deployment Made Easy</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Wed, 13 Dec 2023 18:45:47 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/llamafile-ai-integration-deployment-made-easy-44cg</link>
      <guid>https://dev.to/timesurgelabs/llamafile-ai-integration-deployment-made-easy-44cg</guid>
      <description>&lt;p&gt;Its no secret that I think Llama 2 and its derivatives are the future of AI and ML. Rather than getting bigger and smarter, I think GPT-4 is enough for 99.5% of applications, AI should instead strive to get smaller, cheaper, and faster. If you want to run Llama 2 via llama.cpp, you can check out my &lt;a href="https://blog.chand1012.dev/posts/howtorunllama2onanything/" rel="noopener noreferrer"&gt;guide on how to do that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, the problem with llama.cpp is that to get it working you have to have all the dependencies, either download a binary or clone and build the repo, make sure your drivers are working, and then you can finally run it. What if you just want to download the model and run it? Well, that's where Llamafiles comes in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Mozilla-Ocho/llamafile" rel="noopener noreferrer"&gt;Llamafile&lt;/a&gt; is a project by a team over at Mozilla. It allows users to distribute and run LLMs using a single, platform-independent file. It accomplishes this by building all required code into a binary called &lt;code&gt;llamafile&lt;/code&gt; , then by using a zipping tool, you can combine the binary with the model and any other files you need. This allows you to run Llama 2, Mistral 7B, on anything, without having to have &lt;small&gt;most&lt;/small&gt; dependencies.&lt;/p&gt;

&lt;p&gt;Llamafiles come in two flavors: Main and Server. Main replicates the command-line interface of &lt;a href="https://github.com/ggerganov/llama.cpp" rel="noopener noreferrer"&gt;llama.cpp&lt;/a&gt;, while Server is a server that can be used to run Llama 2 and other models over HTTP with a basic but functional web interface. I'll be focusing on the Servers, as that's what I prefer to use, but the process is the same for both.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use Llamafiles
&lt;/h2&gt;

&lt;p&gt;There are &lt;em&gt;some&lt;/em&gt; dependencies you'll need depending on your platform. You can see &lt;a href="https://github.com/Mozilla-Ocho/llamafile#gotchas" rel="noopener noreferrer"&gt;here&lt;/a&gt; for the most up-to-date information on that, but here is the TLDR as of 13/12/2023:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On macOS, you need &lt;a href="https://developer.apple.com/xcode/" rel="noopener noreferrer"&gt;Xcode&lt;/a&gt; installed.&lt;/li&gt;
&lt;li&gt;For GPU support on Linux and Windows, you need &lt;a href="https://developer.nvidia.com/cuda-toolkit" rel="noopener noreferrer"&gt;CUDA&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For GPU support on Linux, you need to have the &lt;code&gt;cc&lt;/code&gt; compiler installed.&lt;/li&gt;
&lt;li&gt;On Linux and Windows you have to pass &lt;code&gt;--n-gpu-layers 35&lt;/code&gt; for the GPU to work properly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One other thing of note, due to a limitation imposed by Microsoft, you cannot run Llamafiles larger than 4GB on any version of Windows. This can be bypassed by enabling &lt;a href="https://learn.microsoft.com/en-us/windows/ai/directml/gpu-cuda-in-wsl" rel="noopener noreferrer"&gt;Nvidia CUDA on WSL&lt;/a&gt; and running it inside of Linux. Otherwise you'll just be limited to models smaller than 4GB.&lt;/p&gt;

&lt;p&gt;Once that is all complete, you can simply find a llamafile, and try to run it! Platform doesn't matter, except if you are on Windows you have to add .exe to the end of the file in order to execute it. On *nix systems, here's all you have to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# replace with the url and name of the llamafile you want to run!&lt;/span&gt;
wget https://huggingface.co/jartine/mistral-7b.llamafile/resolve/main/mistral-7b-instruct-v0.1-Q4_K_M-server.llamafile
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x mistral-7b-instruct-v0.1-Q4_K_M-server.llamafile
./mistral-7b-instruct-v0.1-Q4_K_M-server.llamafile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! You can now run Llama 2 on anything, without having to worry about dependencies. I have compiled a list of available Llamafiles on HuggingFace, you can find the collection &lt;a href="https://huggingface.co/collections/TimeSurgeLabs/llamafiles-65749149983403462a2980b9" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making your own Llamafile
&lt;/h2&gt;

&lt;p&gt;If your favorite Llama-based model isn't available yet, or you want to run a newer version of the Llama code that an older Llamafile may not be running, you may want to make your own Llamafile. Luckily, this is pretty easy to do!&lt;/p&gt;

&lt;p&gt;First step is to obtain either binaries or source code for Llamafile. I opted to compile from source, but they do have precompiled binaries on their &lt;a href="https://github.com/Mozilla-Ocho/llamafile/releases" rel="noopener noreferrer"&gt;releases page&lt;/a&gt;. Here's how you can compile from source.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Mozilla-Ocho/llamafile.git
&lt;span class="nb"&gt;cd &lt;/span&gt;llamafile
&lt;span class="c"&gt;# optional. I compiled the latest tagged version. You can also just build from main.&lt;/span&gt;
git checkout 0.4 &lt;span class="c"&gt;# there may be a newer version by the time you read this&lt;/span&gt;
make &lt;span class="nt"&gt;-j&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;make &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;PREFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you have Llamafile, you need to download your model. The models &lt;strong&gt;have&lt;/strong&gt; to be in the GGUF format for &lt;a href="https://ggml.ai" rel="noopener noreferrer"&gt;ggml&lt;/a&gt;, as Llamafile is based on llama.cpp. If you don't know how to convert models to GGUF, or just don't want to put in the effort, &lt;a href="https://huggingface.co/TheBloke" rel="noopener noreferrer"&gt;TheBloke&lt;/a&gt; has uploaded &lt;em&gt;thousands&lt;/em&gt; of GGUF conversions to HuggingFace. I'd check his collection before you try to convert anything yourself. If the model happens to be unavailable as GGUF, here's a &lt;a href="https://www.substratus.ai/blog/converting-hf-model-gguf-model/" rel="noopener noreferrer"&gt;guide by Substratus.ai&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For this example, we're going to package Intel's &lt;a href="https://huggingface.co/Intel/neural-chat-7b-v3-3" rel="noopener noreferrer"&gt;Neural Chat v3.3&lt;/a&gt; into a Llamafile. First, we need to download the model. Luckily for us, TheBloke has already converted it to &lt;a href="https://huggingface.co/TheBloke/neural-chat-7B-v3-3-GGUF" rel="noopener noreferrer"&gt;GGUF&lt;/a&gt;, so we can just download it from HuggingFace. Once that's done, we should test it out before we package it. Luckily, when you install llamafile it includes the ability to execute models in a quick and easy manner from the command line, even before you package it into a llamafile!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# The Q4_K_M model is a good balance between compression and performance.&lt;/span&gt;
wget https://huggingface.co/TheBloke/neural-chat-7B-v3-3-GGUF/resolve/main/neural-chat-7b-v3-3.Q4_K_M.gguf
llamafile-server &lt;span class="nt"&gt;-m&lt;/span&gt; neural-chat-7b-v3-3.Q4_K_M.gguf &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there is a browser available on the machine you are running this on, it will automatically open a browser window to the server. If not, you can just go to &lt;code&gt;http://localhost:8080&lt;/code&gt; (or the IP of the server) to access the web interface. Once you are there, you can test out the model. If you are happy with the results, you can now package it into a Llamafile.&lt;/p&gt;

&lt;p&gt;First, we have to create an arguments file. This file is named &lt;code&gt;.args.&lt;/code&gt; and gets appended to the end of the file to act as the arguments for the executable. Here is the contents we are going to be putting on our file, use whichever text editor you prefer. The file is newline delimited, so make sure to add a newline where you would normally add a space.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-m
neural-chat-7b-v3-3.Q4_K_M.gguf
--host
0.0.0.0
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;...&lt;/code&gt; at the end means to accept any other commands that are passed to the executable. Now that we have our arguments file, we can package it into a Llamafile. First, copy the llamafile from &lt;code&gt;/usr/local/bin/llamafile-server&lt;/code&gt; (or wherever you installed it) to the same directory as the model. Then, rename the executable to what you want to call your Llamafile plus &lt;code&gt;.llamafile&lt;/code&gt; . In this case, we'll call it &lt;code&gt;neural-chat-7b-v3-3.Q4_K_M.llamafile&lt;/code&gt; .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; /usr/local/bin/llamafile-server neural-chat-7b-v3-3.Q4_K_M.llamafile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can package it all together into a Llamafile. Llamafile include a command called &lt;code&gt;zipalign&lt;/code&gt; that will package everything together for you. Here's how you can use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zipalign &lt;span class="nt"&gt;-j0&lt;/span&gt; neural-chat-7b-v3-3.Q4_K_M.llamafile neural-chat-7b-v3-3.Q4_K_M.gguf .args
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this is complete, you can test your llamafile out with &lt;code&gt;./neural-chat-7b-v3-3.Q4_K_M.llamafile&lt;/code&gt; . If it works, you can now distribute it to your friends, or &lt;a href="https://huggingface.co/TimeSurgeLabs/intel-neural-chat-v3.3-llamafile" rel="noopener noreferrer"&gt;upload it to HuggingFace&lt;/a&gt; for others to use!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Llamafiles are a great way to distribute Llama 2 and other LLMs. They allow you to run Llama 2 on anything, without having to worry about dependencies. They also allow you to distribute LLMs without having to worry about the user having the right version of Llama 2 installed. I hope this guide was helpful, and I hope to see more Llamafiles in the future!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>llama</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I Made an AI Agent in 10 Minutes with LangChain</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Tue, 15 Aug 2023 16:49:12 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/how-to-make-an-ai-agent-in-10-minutes-with-langchain-3i2n</link>
      <guid>https://dev.to/timesurgelabs/how-to-make-an-ai-agent-in-10-minutes-with-langchain-3i2n</guid>
      <description>&lt;p&gt;&lt;a href="https://www.langchain.com/" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt; is a powerful library for Python and Javascript/Typescript that allows you to quickly prototype large language model applications. It allows you to chain together LLM tasks (hence the name) and even allows you to run autonomous agents quickly and easily. In this blog post, we'll explore how to create agents and define custom tools that those agents can use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.9

&lt;ul&gt;
&lt;li&gt;3.10 and up have some issues with some of LangChain’s modules.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;An OpenAI API Key&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;We’re going to create a Python virtual environment and install the dependencies that way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;myproject
&lt;span class="nb"&gt;cd &lt;/span&gt;myproject
&lt;span class="c"&gt;# or python3, python3.9, etc depending on your setup&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="nb"&gt;env
source env&lt;/span&gt;/bin/activate &lt;span class="c"&gt;# this will need run every time before using your agent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is done we can install dependencies. The only ones we need for this tutorial are LangChain and OpenAI. Finally, &lt;code&gt;python-dotenv&lt;/code&gt; will be used to load the OpenAI API keys into the environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain openai python-dotenv requests duckduckgo-search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LangChain is a very large library so that may take a few minutes. While this is downloading, create a new file called &lt;code&gt;.env&lt;/code&gt; and paste your API key in. Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is complete we can make our first chain!&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Concepts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://python.langchain.com/docs/modules/agents" rel="noopener noreferrer"&gt;Agents&lt;/a&gt;&lt;/strong&gt; are a way to run an LLM in a loop in order to complete a task. Agents are defined with the following:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://python.langchain.com/docs/modules/agents/agent_types/" rel="noopener noreferrer"&gt;Agent Type&lt;/a&gt;&lt;/strong&gt; - This defines how the Agent acts and reacts to certain events and inputs. For this tutorial we will focus on the &lt;a href="https://python.langchain.com/docs/modules/agents/agent_types/react.html" rel="noopener noreferrer"&gt;ReAct&lt;/a&gt; Agent Type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://python.langchain.com/docs/modules/chains/foundational/llm_chain" rel="noopener noreferrer"&gt;LLM&lt;/a&gt;&lt;/strong&gt; - The AI that actually runs your prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://python.langchain.com/docs/modules/agents/tools/" rel="noopener noreferrer"&gt;Tools&lt;/a&gt;&lt;/strong&gt; - These are Python (or JS/TS) functions that your Agent can call to interact with the world outside of itself. These can be as simple or as complex as you want them to be!

&lt;ul&gt;
&lt;li&gt;Many tools make a &lt;a href="https://python.langchain.com/docs/modules/agents/toolkits/" rel="noopener noreferrer"&gt;Toolkit&lt;/a&gt;. There are many &lt;a href="https://python.langchain.com/docs/integrations/toolkits/" rel="noopener noreferrer"&gt;toolkits already available&lt;/a&gt; built-in to LangChain, but for this example we’ll make our own.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Agents
&lt;/h2&gt;

&lt;p&gt;Agents use a combination of an LLM (or an LLM Chain) as well as a Toolkit in order to perform a predefined series of steps to accomplish a goal. For this example, we’ll create a couple of custom tools as well as LangChain’s provided DuckDuckGo search tool to create a research agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Importing Necessary Libraries&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bs4&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DuckDuckGoSearchResults&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chat_models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;initialize_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AgentType&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's a breakdown of the imports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;requests&lt;/code&gt;: A popular Python library for making HTTP requests.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;BeautifulSoup&lt;/code&gt;: A library for web scraping purposes to pull the data out of HTML and XML files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;load_dotenv&lt;/code&gt;: A method to load environment variables from a &lt;code&gt;.env&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;LangChain specific imports: These are specific to the LangChain framework and are used to define tools, prompts, chat models, chains, and agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Loading Environment Variables&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line loads environment variables from a &lt;code&gt;.env&lt;/code&gt; file. This is useful if you have API keys or other sensitive information that you don't want to hard-code into your script.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Setting Up the DuckDuckGo Search Tool&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ddg_search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DuckDuckGoSearchResults&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This initializes the DuckDuckGo search tool provided by LangChain. It allows you to search the web using DuckDuckGo and retrieve the results.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Defining Headers for Web Requests&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:90.0) Gecko/20100101 Firefox/90.0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sets a user-agent header for our web requests. Some websites might block requests that don't have a user-agent set, thinking they're from bots.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Parsing HTML Content&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;html.parser&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;text_content_with_links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;soup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text_content_with_links&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function takes in HTML content, uses BeautifulSoup to parse it, and then extracts all the text from it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;6. Fetching Web Page Content&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_web_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HEADERS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;parse_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function fetches the content of a web page using the &lt;code&gt;requests&lt;/code&gt; library and then parses the HTML to extract the text.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;7. Creating the Web Fetcher Tool&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;web_fetch_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fetch_web_page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WebFetcher&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fetches the content of a web page&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we're creating a new tool using the &lt;code&gt;Tool.from_function&lt;/code&gt; method. This tool will use our &lt;code&gt;fetch_web_page&lt;/code&gt; function to fetch and parse web pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;8. Setting Up the Summarizer&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prompt_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize the following content: {content}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-3.5-turbo-16k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;llm_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt_template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;summarize_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm_chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarizer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarizes a web page&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This section sets up a summarizer using the ChatOpenAI model from LangChain. We define a prompt template for summarization, create a chain using the model and the prompt, and then define a tool for summarization. We use ChatGPT 3, 5 16k context as most web pages will exceed the 4k context of ChatGPT 3.5.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;9. Initializing the Agent&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ddg_search&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;web_fetch_tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;summarize_tool&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;initialize_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;agent_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AgentType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ZERO_SHOT_REACT_DESCRIPTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we're initializing an agent with the tools we've defined. This agent will be able to search the web, fetch web pages, and summarize them. Notice how we can re-use the LLM from the summarize tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;10. Running the Agent&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Research how to use the requests library in Python. Use your tools to search and summarize content into a guide on how to use the requests library.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we define a prompt for our agent and run it. The agent will search the web for information about the Python’s Requests Library, fetch the content fetch some of the content, and then summarize it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Experimentation
&lt;/h2&gt;

&lt;p&gt;In this section, we'll explore how to modify the code from the blog post draft to use the experimental Plan and Execute agent. The Plan and Execute agent accomplishes an objective by first planning what to do, then executing the sub-tasks. The planning is almost always done by an LLM, while the execution is usually done by a separate agent equipped with tools.&lt;/p&gt;

&lt;p&gt;First, install the LangChain experimental package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain_experimental
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can import the necessary modules from the &lt;code&gt;langchain_experimental.plan_and_execute&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_experimental.plan_and_execute&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PlanAndExecute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;load_agent_executor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;load_chat_planner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load the planner and executor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;planner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_chat_planner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_agent_executor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initialize the Plan and Execute agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PlanAndExecute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;planner&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;planner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the agent with a prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Research how to use the requests library in Python. Use your tools to search and summarize content into a guide on how to use the requests library.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the agent will first plan the steps needed to accomplish the objective, then execute the sub-tasks using the tools provided. The agent will search the web for information about the requests library in Python, fetch the content of the relevant results, and then summarize them into a guide.&lt;/p&gt;

&lt;p&gt;Note that the Plan and Execute agent is experimental and may not work as expected in all cases. However, it can be a powerful tool for automating complex tasks that require multiple steps and interactions with external tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;LangChain is a game-changer for anyone looking to quickly prototype large language model applications. In just a few minutes, we’ve walked through the process of creating agents, defining custom tools, and even experimenting with the experimental Plan and Execute agent to automate complex tasks.&lt;/p&gt;

&lt;p&gt;The power of LangChain lies in its simplicity and flexibility. Whether you’re a seasoned developer or just starting out, LangChain’s intuitive design allows you to harness the capabilities of large language models like never before. From generating creative content to running autonomous agents, the possibilities are endless.&lt;/p&gt;

&lt;p&gt;So why wait? Dive into LangChain today and unleash the potential of AI in your projects. If you’re looking to integrate AI into your existing workflow or products, &lt;a href="https://timesurgelabs.com/" rel="noopener noreferrer"&gt;TimeSurge Labs&lt;/a&gt; is here to help. Specializing in AI consulting, development, internal tooling, and LLM hosting, our team of passionate AI experts is dedicated to building the future of AI and helping your business thrive in this rapidly changing industry. &lt;a href="https://timesurgelabs.com/#contact" rel="noopener noreferrer"&gt;Contact us&lt;/a&gt; today!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How To Use LangChain in 10 Minutes</title>
      <dc:creator>Chandler</dc:creator>
      <pubDate>Wed, 09 Aug 2023 16:19:04 +0000</pubDate>
      <link>https://dev.to/timesurgelabs/how-to-use-langchain-in-10-minutes-56e2</link>
      <guid>https://dev.to/timesurgelabs/how-to-use-langchain-in-10-minutes-56e2</guid>
      <description>&lt;p&gt;&lt;a href="https://www.langchain.com/" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt; is a powerful library for Python and Javascript/Typescript that allows you to quickly prototype large language model applications. It allows you to chain together LLM tasks (hence the name) and even allows you to run autonomous agents quickly and easily. Today we will be going over the basics of chains, so you can hit the ground running with your newest LLM projects!&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.9

&lt;ul&gt;
&lt;li&gt;3.10 and up have some issues with some of LangChain’s modules.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;An OpenAI API Key&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;We’re going to create a Python virtual environment and install the dependencies that way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;myproject
&lt;span class="nb"&gt;cd &lt;/span&gt;myproject
&lt;span class="c"&gt;# or python3, python3.9, etc depending on your setup&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv &lt;span class="nb"&gt;env
source env&lt;/span&gt;/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is done we can install dependencies. The only ones we need for this tutorial are LangChain and OpenAI. Finally, &lt;code&gt;python-dotenv&lt;/code&gt; will be used to load the OpenAI API keys into the environment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain openai python-dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LangChain is a very large library so that may take a few minutes. While this is downloading, create a new file called &lt;code&gt;.env&lt;/code&gt; and paste your API key in. Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is complete we can make our first chain!&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Concepts
&lt;/h2&gt;

&lt;p&gt;There are a few basic concepts you’ll need to understand in order to get started.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chains&lt;/strong&gt; can be thought of as a list of actions to take with an LLM or multiple LLM calls in the list. A chain is made up of 3 simple parts.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://python.langchain.com/docs/modules/model_io/prompts/prompt_templates/" rel="noopener noreferrer"&gt;Prompt Template&lt;/a&gt;&lt;/strong&gt; - so you can quickly change inputs without changing the prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://python.langchain.com/docs/modules/chains/foundational/llm_chain" rel="noopener noreferrer"&gt;LLM&lt;/a&gt;&lt;/strong&gt; - The AI that actually runs your prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://python.langchain.com/docs/modules/model_io/output_parsers/" rel="noopener noreferrer"&gt;Output Parsers&lt;/a&gt;&lt;/strong&gt; - Converts the output into something useful, usually just another string.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Writing the Chain
&lt;/h2&gt;

&lt;p&gt;For this example, we’re going to write a chain that generates a TikTok script (I am a &lt;a href="https://www.urbandictionary.com/define.php?term=Zoomer" rel="noopener noreferrer"&gt;Zoomer&lt;/a&gt; after all) for an educational channel. First, we need to generate a description for the TikTok. We will use prompt templating so we can reuse the prompt later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# prompts.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;

&lt;span class="n"&gt;description_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write me a description for a TikTok about {topic}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can then be used in a chain. Before we can define a chain, we need to define an LLM for the chain to use. LangChain recommends that most users should use The &lt;code&gt;ChatOpenAI&lt;/code&gt; class to get the cost benefits and simplicity of the ChatGPT API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# chain.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chat_models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;description_prompt&lt;/span&gt;

&lt;span class="c1"&gt;# loads the .env file
&lt;/span&gt;&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-3.5-turbo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that is done we can create the chain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;description_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;description_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can call the new chain with &lt;code&gt;.predict&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;description_chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cats are cool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is the output:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;😻 Unleash your inner feline aficionado! From their enchanting eyes to their purrfectly mysterious ways, cats are the epitome of coolness. 🐾 Watch as they effortlessly own their spaces, teaching us the art of relaxation and play. Whether they're mastering acrobatics or curling up for a catnap, their cool vibes are undeniable. 😎 Join the cat craze and embrace the awesomeness of these four-legged trendsetters! 🐱💫 #CatsRule #CoolCats #FelineVibes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have a description, we need to have it write a script. This is where chaining comes in - we can sequentially call the LLM again using a slightly different prompt. First, let’s define a new prompt for the next chain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# add to prompts.py
&lt;/span&gt;
&lt;span class="n"&gt;script_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write me a script for a TikTok given the following description: {description}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what your &lt;code&gt;chain.py&lt;/code&gt; should look like now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# chain.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chat_models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="c1"&gt;# this line changed!!!!!
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;description_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;script_prompt&lt;/span&gt;

&lt;span class="c1"&gt;# loads the .env file
&lt;/span&gt;&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-3.5-turbo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;description_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;description_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;description_chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cats are cool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# new code below this line
&lt;/span&gt;&lt;span class="n"&gt;script_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;script_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;description_chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the new output:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[Opening shot: A close-up of a cat's mesmerizing eyes, slowly blinking.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "😻 Unleash your inner feline aficionado!"&lt;/p&gt;

&lt;p&gt;[Cut to a sleek cat walking confidently through a room, tail swaying gracefully.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "From their enchanting eyes to their purrfectly mysterious ways..."&lt;/p&gt;

&lt;p&gt;[Transition to a montage of cats lounging in different relaxed poses.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "Cats are the epitome of coolness. 🐾"&lt;/p&gt;

&lt;p&gt;[Show a cat effortlessly jumping onto a high shelf, landing with precision.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "Watch as they effortlessly own their spaces..."&lt;/p&gt;

&lt;p&gt;[Cut to a person lying on the couch while a cat playfully bats at a string toy.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "Teaching us the art of relaxation and play."&lt;/p&gt;

&lt;p&gt;[Show a cat doing a graceful mid-air flip while chasing a feather toy.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "Whether they're mastering acrobatics..."&lt;/p&gt;

&lt;p&gt;[Transition to a cozy scene of a cat curled up in a sunlit spot, eyes half-closed.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "Or curling up for a catnap..."&lt;/p&gt;

&lt;p&gt;[Cut to a group of cats with various personalities and fur patterns.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "Their cool vibes are undeniable."&lt;/p&gt;

&lt;p&gt;[Show a person petting a content cat, both sharing a moment of connection.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "😎 Join the cat craze and embrace the awesomeness..."&lt;/p&gt;

&lt;p&gt;[Cut to a playful cat chasing its tail, accompanied by a cheerful laugh.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "...of these four-legged trendsetters!"&lt;/p&gt;

&lt;p&gt;[End with a shot of a cat sitting regally, gazing confidently into the camera.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "🐱💫 #CatsRule #CoolCats #FelineVibes"&lt;/p&gt;

&lt;p&gt;[Fade out with a final glimpse of a cat's eyes.]&lt;/p&gt;

&lt;p&gt;Narrator (Voiceover): "Because when it comes to cool, cats wrote the book."&lt;/p&gt;

&lt;p&gt;[End screen: "Follow for more feline fun!"]&lt;/p&gt;

&lt;p&gt;[Background music fades out as the TikTok video concludes.]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using them like this is &lt;em&gt;fine&lt;/em&gt;, but what if we want to chain them together? That’s where &lt;a href="https://python.langchain.com/docs/modules/chains/foundational/sequential_chains" rel="noopener noreferrer"&gt;Sequential Chains&lt;/a&gt; comes in. These allow you to tie multiple chains into a single function call, with them executing in order they are defined. There are two types of sequential chains, we’re just going to focus on the simple sequential chain. Edit the Chain import line to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SimpleSequentialChain&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move the LLM chains to the top of the file and remove the print statements and the &lt;code&gt;.predict&lt;/code&gt; calls.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# chain.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chat_models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SimpleSequentialChain&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;
&lt;span class="c1"&gt;# this line changed!!!!!
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;description_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;script_prompt&lt;/span&gt;

&lt;span class="c1"&gt;# loads the .env file
&lt;/span&gt;&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-3.5-turbo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;description_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;description_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;script_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;script_prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tiktok_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SimpleSequentialChain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chains&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;description_chain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;script_chain&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tiktok_chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cats are cool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is the output:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Title: #CoolCatsRule&lt;/p&gt;

&lt;p&gt;INT. LIVING ROOM - DAY&lt;/p&gt;

&lt;p&gt;A trendy, upbeat song begins playing as the camera pans across a stylishly decorated living room. Various cat-themed decorations can be seen, setting the perfect atmosphere for showcasing the undeniable coolness of cats.&lt;/p&gt;

&lt;p&gt;CUT TO:&lt;/p&gt;

&lt;p&gt;INT. BEDROOM - DAY&lt;/p&gt;

&lt;p&gt;A YOUNG WOMAN, in her early twenties, stands in front of a full-length mirror. She wears trendy clothes and holds a CAT, who seems equally as cool, in her arms.&lt;/p&gt;

&lt;p&gt;YOUNG WOMAN&lt;br&gt;
(looking into the mirror)&lt;br&gt;
Ready to show the world why cats rule!&lt;/p&gt;

&lt;p&gt;The young woman gently places the cat on the ground as the camera zooms in on the feline.&lt;/p&gt;

&lt;p&gt;CUT TO:&lt;/p&gt;

&lt;p&gt;INT. KITCHEN - DAY&lt;/p&gt;

&lt;p&gt;A CAT sits on the kitchen counter, effortlessly balancing on one paw while wearing sunglasses. The camera pans around it, capturing its cool demeanor.&lt;/p&gt;

&lt;p&gt;CUT TO:&lt;/p&gt;

&lt;p&gt;INT. BACKYARD - DAY&lt;/p&gt;

&lt;p&gt;A CAT lounges in a hammock, wearing a tiny hat and reading a book. The camera captures its relaxed and sophisticated vibe.&lt;/p&gt;

&lt;p&gt;CUT TO:&lt;/p&gt;

&lt;p&gt;INT. LIVING ROOM - DAY&lt;/p&gt;

&lt;p&gt;The young woman sits on the couch, surrounded by a group of COOL CATS. Each cat showcases their unique coolness, like one wearing a leather jacket and another playing a tiny electric guitar.&lt;/p&gt;

&lt;p&gt;YOUNG WOMAN&lt;br&gt;
(points to the cats)&lt;br&gt;
See? Cats rule!&lt;/p&gt;

&lt;p&gt;The camera zooms in on the cats, showing their undeniable feline awesomeness.&lt;/p&gt;

&lt;p&gt;CUT TO:&lt;/p&gt;

&lt;p&gt;INT. LIVING ROOM - DAY&lt;/p&gt;

&lt;p&gt;The young woman and her cool cats gather around a table, where they enjoy a mini-cat party. There are cat-themed snacks, funky drinks, and even a DJ cat scratching vinyl records.&lt;/p&gt;

&lt;p&gt;CUT TO:&lt;/p&gt;

&lt;p&gt;INT. LIVING ROOM - DAY&lt;/p&gt;

&lt;p&gt;The young woman holds up a sign saying "#CoolCatsRule" as the cats pose beside her. The camera pans out to reveal a fun, energetic dance routine as they all groove to the beat.&lt;/p&gt;

&lt;p&gt;CUT TO:&lt;/p&gt;

&lt;p&gt;INT. LIVING ROOM - DAY&lt;/p&gt;

&lt;p&gt;The young woman and her cool cats strike a final pose, with the camera capturing their undeniable coolness.&lt;/p&gt;

&lt;p&gt;YOUNG WOMAN&lt;br&gt;
(looking at the camera)&lt;br&gt;
Remember, folks, cats rule!&lt;/p&gt;

&lt;p&gt;The screen fades out with the hashtag #CoolCatsRule displayed prominently.&lt;/p&gt;

&lt;p&gt;FADE OUT.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;LangChain is a game-changer for anyone looking to quickly prototype large language model applications. In just a few minutes, we've walked through the process of creating chains, defining prompts, and even chaining together multiple LLM calls to create a dynamic TikTok script.&lt;/p&gt;

&lt;p&gt;The power of LangChain lies in its simplicity and flexibility. Whether you're a seasoned developer or just starting out, LangChain's intuitive design allows you to harness the capabilities of large language models like never before. From generating creative content to running autonomous agents, the possibilities are endless.&lt;/p&gt;

&lt;p&gt;So why wait? Dive into LangChain today and unleash the potential of AI in your projects. If you're looking to integrate AI into your existing workflow or products, TimeSurge Labs is here to help. Specializing in AI consulting, development, internal tooling, and LLM hosting, our team of passionate AI experts is dedicated to building the future of AI and helping your business thrive in this rapidly changing industry. &lt;a href="https://timesurgelabs.com/#contact" rel="noopener noreferrer"&gt;Contact us&lt;/a&gt; today!&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Cover image generated by Stable Diffusion.&lt;/small&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>tutorial</category>
      <category>chatgpt</category>
    </item>
  </channel>
</rss>
