<?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>Forem: Kirk Crenshaw</title>
    <description>The latest articles on Forem by Kirk Crenshaw (@kirkcren).</description>
    <link>https://forem.com/kirkcren</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%2Fuser%2Fprofile_image%2F1593392%2F9581dd67-cc36-4b5c-bf5a-083cf8acd0da.jpg</url>
      <title>Forem: Kirk Crenshaw</title>
      <link>https://forem.com/kirkcren</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kirkcren"/>
    <language>en</language>
    <item>
      <title>What the Heck Are Hybrid Knowledge Bases? (And Why They Matter for LLM Apps)</title>
      <dc:creator>Kirk Crenshaw</dc:creator>
      <pubDate>Fri, 25 Apr 2025 17:51:56 +0000</pubDate>
      <link>https://forem.com/griptape/what-the-heck-are-hybrid-knowledge-bases-and-why-they-matter-for-llm-apps-im</link>
      <guid>https://forem.com/griptape/what-the-heck-are-hybrid-knowledge-bases-and-why-they-matter-for-llm-apps-im</guid>
      <description>&lt;p&gt;If you're building with LLMs and trying to give your agents or copilots real context, you've probably used a &lt;strong&gt;vector database&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They're great for unstructured data — PDFs, HTML, markdown, text blobs. But what happens when your data &lt;em&gt;isn't&lt;/em&gt; just text?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enter Hybrid Knowledge Bases.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Now available in &lt;a href="https://www.griptape.ai/cloud" rel="noopener noreferrer"&gt;Griptape Cloud&lt;/a&gt;, they let you store and retrieve &lt;strong&gt;structured and unstructured data&lt;/strong&gt; — together — and query them intelligently in your apps.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 So... What &lt;em&gt;Is&lt;/em&gt; a Hybrid Knowledge Base?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Hybrid Knowledge Base&lt;/strong&gt; compliments a vector store by combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔢 &lt;strong&gt;Structured data&lt;/strong&gt;: things like location, job titles, timestamps, metadata fields
&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Unstructured data&lt;/strong&gt;: resumé text, emails, notes, paragraphs, docs
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use &lt;strong&gt;natural language queries&lt;/strong&gt; or programmatic ones — and get results that combine &lt;strong&gt;exact-match filters&lt;/strong&gt; with &lt;strong&gt;vector similarity searches&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠️ Example Use Case: Candidate Search
&lt;/h3&gt;

&lt;p&gt;You're building a recruiter assistant. You have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structured data: candidate name, location, years of experience
&lt;/li&gt;
&lt;li&gt;Unstructured data: resumes, LinkedIn profiles, cover letters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a hybrid knowledge base, your app can answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Which candidates are in New York and have experience in data analysis with Python?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filter by &lt;code&gt;location == New York&lt;/code&gt; (structured)&lt;/li&gt;
&lt;li&gt;Perform semantic search across profiles and resumes for &lt;code&gt;"data analysis with Python"&lt;/code&gt; (unstructured)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📊✅ Combined results. No hacky joins. No second queries. Just clean, LLM-ready responses.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Why It Matters
&lt;/h2&gt;

&lt;p&gt;Most LLM apps fail when the data isn’t flat text.&lt;br&gt;&lt;br&gt;
Real-world knowledge is messy. It’s structured &lt;em&gt;and&lt;/em&gt; unstructured.&lt;br&gt;&lt;br&gt;
And most stacks treat those as separate systems.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;Griptape Hybrid Knowledge Bases&lt;/strong&gt;, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A unified query layer&lt;/li&gt;
&lt;li&gt;Tight integration with agents, workflows, and pipelines&lt;/li&gt;
&lt;li&gt;Real-time, semantic + structured retrieval&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Read more
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.griptape.ai/blog/introducing-griptape-cloud-hybrid-knowledge-bases" rel="noopener noreferrer"&gt;Hybrid Knowledge Bases are now available in Griptape Cloud&lt;/a&gt;.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🙋‍♂️ What Would You Build?
&lt;/h2&gt;

&lt;p&gt;Got a use case that blends structured and unstructured data?&lt;br&gt;&lt;br&gt;
Want to give your agents actual intelligence without cobbling multiple tools together?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>devtools</category>
      <category>rag</category>
    </item>
    <item>
      <title>Improving the dev experience for building apps that integrate up-to-date and private data with large language models</title>
      <dc:creator>Kirk Crenshaw</dc:creator>
      <pubDate>Mon, 31 Mar 2025 20:25:51 +0000</pubDate>
      <link>https://forem.com/griptape/improving-the-dev-experience-for-building-apps-that-integrate-up-to-date-and-private-data-with-gpj</link>
      <guid>https://forem.com/griptape/improving-the-dev-experience-for-building-apps-that-integrate-up-to-date-and-private-data-with-gpj</guid>
      <description>&lt;p&gt;We’re delighted to announce a new feature in Griptape Cloud that will improve the experience for developers building applications that integrate up-to-date and private data with large language models.  Griptape Cloud has supported retrieval augmented generation applications through similarity search for some time. Check out this post for more details on existing Retrieval Augmented Generation features in Griptape Cloud &amp;gt; &lt;a href="https://www.griptape.ai/blog/retrieval-augmented-generation-with-griptape-cloud" rel="noopener noreferrer"&gt;https://www.griptape.ai/blog/retrieval-augmented-generation-with-griptape-cloud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrievers&lt;/strong&gt;&lt;br&gt;
Today, we are adding to that capability with Griptape Cloud Retrievers. Retrievers are a fully-managed implementation of the RAG Engine within Griptape Framework, and add query modification, reranking capabilities, and the ability to apply rules to query responses. These features enable you to generate more accurate and tailored results in your RAG applications built with Griptape Cloud.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query Modification&lt;/strong&gt;&lt;br&gt;
Query modification in RAG allows you to improve matching by transforming queries before embeddings are generated for the query and used for similarity search against the data stored in a vector store. They use techniques such as query expansion, where an LLM is used to add additional context or terms to improve each query; or Hypothetical Document Embedding (HyDE), which is the generation of hypothetical answers to a query, which are then embedded and used  with the original query to enhance the query that is made against the vector store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Reranking?&lt;/strong&gt;&lt;br&gt;
Reranking works by comparing the relatedness of search results returned from a vector search query to the original query and reordering the results in descending order of their relatedness. This gives a ‘reranked’ list of results that you can use in your application.  Let’s explore an example of reranking with Griptape Framework to illustrate why reranking is valuable, and then we’ll move on to explain how to get started with Retrievers in Griptape Cloud. Let’s assume we asked the question “What is the capital of France?” and the results that came back from a vector search operation across our data sources were as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;results = [ “Hotdog", "San Francisco", "Lille", "Paris", "Rome", "Baguette", "Eiffel Tower", "French Hotdog" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To rerank these results, we compare the embedding for each result to the embedding for the original question “What is the capital of France?” and then order the results in descending order of relatedness. In this use-case, answering a question, we would likely use the top result, but there are other use-cases, a research agent might be one example, where we might want to take the top n results from the reranking operation to perform a secondary operation on those results.&lt;/p&gt;

&lt;p&gt;Implementing reranking is simple with Griptape Framework. Griptape Framework supports reranking with a local rerank driver using a simple relatedness calculation, and also has the capabilities to use Cohere’s reranking model through the &lt;code&gt;CohereRerankDriver&lt;/code&gt;. The sample code below uses the local rerank driver to rerank these results from the example query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from griptape.artifacts import TextArtifact
from griptape.drivers.rerank.local import LocalRerankDriver

list = ["Hotdog","San Francisco","Lille","Paris","Rome","Baguette","Eiffel Tower","French Hotdog"]

artifact_list = []

for i in list:
   artifact_list.append(TextArtifact(i))

rerank_driver = LocalRerankDriver()

artifacts = rerank_driver.run("What is the capital of France?", artifact_list)

print("Reranked list:")

for artifact in artifacts:
    print("\t", artifact.value)
Reranked list:
         Paris
         Eiffel Tower
         Lille
         San Francisco
         Rome
         Baguette
         French Hotdog
         Hotdog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that the reranking operation correctly identifies Paris as the best answer to the question that we posed.&lt;/p&gt;

&lt;p&gt;The example above shows the &lt;code&gt;LocalRerankDriver&lt;/code&gt; being used as a standalone module, but it is more commonly used within a Griptape Framework &lt;code&gt;RagEngine&lt;/code&gt;. The code sample below shows how we might create a tool for an Agent to use where we define a &lt;code&gt;RetrievalRagStage&lt;/code&gt; that includes a &lt;code&gt;VectorStoreRetrievalRagModule&lt;/code&gt; and a &lt;code&gt;TextChunksRerankRagModule&lt;/code&gt;, where we use the &lt;code&gt;LocalRerankDriver&lt;/code&gt;as the rerank_driver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rag_tool = RagTool(
   description="Contains information about the judgements and applications relating to legal cases",
   off_prompt=False,
   rag_engine=RagEngine(
       retrieval_stage=RetrievalRagStage(
           retrieval_modules=[
               VectorStoreRetrievalRagModule(
                   vector_store_driver=vector_store_driver,
                   query_params={"namespace": "legal documents", "top_n": 20},
               )
           ],
           rerank_module=TextChunksRerankRagModule(rerank_driver=LocalRerankDriver()),
       ),
       response_stage=ResponseRagStage(
           response_modules=[
               PromptResponseRagModule(
                   prompt_driver=OpenAiChatPromptDriver(model="gpt-4o")
               )
           ]
       ),
   ),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we mentioned earlier, Retrievers are a fully-managed implementation of the RAG Engine within the Griptape Framework. So you don’t need to worry about this complexity if you’re using Griptape Cloud.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query Response Types&lt;/strong&gt;&lt;br&gt;
Retrievers support two different response types, text chunk responses and prompts with rulesets. The Text Chunk response type is intended for use in conjunction with an LLM for Retrieval Augmented Generation use-case. &lt;/p&gt;

&lt;p&gt;The Prompt with Rulesets response type is used to generate natural language responses to your queries directly from the Retriever without the need to pass text chunks to an LLM for response generation. As you might expect from the name of this response type, you can control the behaviour of the Retrieverer in generating natural language responses by attaching a Ruleset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Retrievers in Griptape Cloud&lt;/strong&gt;&lt;br&gt;
Retrievers bring the benefits of query modification, reranking, and control over query responses to Griptape Cloud. Retrievers can rerank the results returned from multiple Knowledge Bases. This means that they are particularly valuable when combining the results from multiple different data sources where they can help ensure that your applications get the results that are most relevant to the search queries they are making. &lt;/p&gt;

&lt;p&gt;Let’s walk through the process of setting up a Retriever on Griptape Cloud. In this example, we’re going to create a Retriever that uses the Knowledge Base that we configured when we set up the Assistant in the 'Brush Up on NVIDIA's Q4 Earnings’ sample on the Griptape Cloud console home page. If you want to learn more about that sample application, &lt;a href="https://www.griptape.ai/blog/retrieval-augmented-generation-with-griptape-cloud" rel="noopener noreferrer"&gt;it’s covered in this blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Retrievers can be found under the Libraries Navigation header in the left navigation menu in the Griptape Cloud Console. To create a Retriever, select the yellow highlighted option in the  left navigation menu and then select Create Retriever on the Retrievers page.&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%2Fr20jnrc3bra56gtlyfb3.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%2Fr20jnrc3bra56gtlyfb3.png" alt="Retrievers can be found under the Libraries Navigation header" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will then be prompted to provide the details for your new Retriever. We are going to create a Retriever for the RAG use-case that I will connect to an Assistant, so I completed the Retriever details as shown below. Once the details have been entered, click the Create button to create the Retriever. &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%2Ft76r2l6eoydvx30gbbnd.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%2Ft76r2l6eoydvx30gbbnd.png" alt="completed the Retriever details" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can then connect the new Retriever to my Assistant and use it to retrieve answers to my questions from the NVIDIA Q4 Earnings Knowledge Base.&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%2Fvjfms34vq4ynbjm1w37f.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%2Fvjfms34vq4ynbjm1w37f.png" alt="connect the new Retriever to my Assistant" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, I am using a Ruleset to guide the Assistants behavior. If you want to experiment with this, you can use my rules as inspiration for your own, or just copy them for yourself. The rules I used are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only provide answers that you can verify using the Knowledge Base or Retriever. Check all answers against either the Knowledge Base or Retriever. If you cannot verify an answer from the Knowledge Base or Retriever, say so and decline to answer. Do not make things up that cannot be verified.&lt;/li&gt;
&lt;li&gt;Only answer questions related to NVIDIA's Q4 2025 earnings. Decline to answer all other questions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We hope you find the Griptape Cloud Retrievers a valuable addition to your RAG toolkit. As usual, we’re excited to hear how you put this new capability to work. Please join us in the &lt;a href="https://discord.gg/griptape" rel="noopener noreferrer"&gt;Griptape Discord&lt;/a&gt; if you have any questions, or use-cases that you would like to share.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>rag</category>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Announcing Griptape AI Framework 1.5</title>
      <dc:creator>Kirk Crenshaw</dc:creator>
      <pubDate>Thu, 20 Mar 2025 19:37:37 +0000</pubDate>
      <link>https://forem.com/griptape/announcing-griptape-framework-15-2m65</link>
      <guid>https://forem.com/griptape/announcing-griptape-framework-15-2m65</guid>
      <description>&lt;p&gt;We’re pleased to announce that Griptape Framework 1.5 is now available. The 1.5 release brings enhancements to embeddings to add support for generating image embeddings and the addition of image search via the framework’s vector store drivers. We also have updates to the default models in several drivers, support for Perplexity with a new prompt driver and web search driver, and more. Let’s head down to the skatepark and explore some of the new features added in this release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated Getting Started Guide &amp;amp; Improved Samples&lt;/strong&gt;&lt;br&gt;
First up, we have improved the &lt;a href="https://docs.griptape.ai/stable/griptape-framework/" rel="noopener noreferrer"&gt;Griptape Framework getting started guide&lt;/a&gt; on the Framework Overview documentation page. The new guide uses the &lt;code&gt;uv&lt;/code&gt; python dependency manager, though of course we also provide instructions for &lt;code&gt;pip&lt;/code&gt; users, and provides a tour of the key features in the framework. We recommend that you check this out, even if you're already familiar with Griptape Framework, as it covers new features added over the last few releases. We have also updated all the code samples in the documentation to include a tab showing the output logs from running the sample, so you can see the results from each sample without having to run them yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Support for Image Embeddings&lt;/strong&gt;&lt;br&gt;
Griptape Framework 1.5 includes support for generating embeddings from &lt;code&gt;ImageArtifact&lt;/code&gt; objects, together with new embedding drivers for Amazon Bedrock with Amazon’s Titan Multimodal Embeddings G1 model, and for Voyage AI’s &lt;code&gt;voyage-multimodal-3&lt;/code&gt; model. &lt;/p&gt;

&lt;p&gt;In the example below, I generate embeddings for 4 images that I generated using FLUX.2 with the &lt;a href="https://github.com/griptape-ai/griptape-black-forest" rel="noopener noreferrer"&gt;Black Forest Labs extension for Griptape&lt;/a&gt;. After generating and saving two snowboarding images and two skateboarding images, in the code sample I use Amazon’s amazon.titan-embed-image-v1 model to calculate embeddings for these images and a simple relatedness calculation to compare the vectors that the embedding model generated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from griptape.drivers.embedding.amazon_bedrock import AmazonBedrockTitanEmbeddingDriver
from griptape.loaders import ImageLoader
import numpy as np

def calc_relatedness(
   x, y
):  # using the same relatedness function as the localrerankdriver
   return np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))

# create a driver for multi-modal embedding with Amazon Bedrock and Amazon Titan
multi_modal_embedding_driver = AmazonBedrockTitanEmbeddingDriver(
   model="amazon.titan-embed-image-v1"
)

# calculate embeddings for our four sample images
blue_snowboarder_embeddings = multi_modal_embedding_driver.embed(
   ImageLoader().load("images/blue_snowboarder.jpeg")
)
orange_snowboarder_embeddings = multi_modal_embedding_driver.embed(
   ImageLoader().load("images/orange_snowboarder.jpeg")
)
beach_skater_embeddings = multi_modal_embedding_driver.embed(
   ImageLoader().load("images/beach_skater.jpeg")
)
paris_skater_embeddings = multi_modal_embedding_driver.embed(
   ImageLoader().load("images/paris_skater.jpeg")
)

print(  # compare the two snowboarding images
   "blue_snowboarder vs orange_snowboarder: ",
   calc_relatedness(blue_snowboarder_embeddings, orange_snowboarder_embeddings),
)

print(  # compare a snowboarding image with a skateboarding image
   "blue_snowboarder vs beach_skater: ",
   calc_relatedness(blue_snowboarder_embeddings, beach_skater_embeddings),
)

print(  # compare the two skateboarding images
   "beach_skater vs paris_skater: ",
   calc_relatedness(beach_skater_embeddings, paris_skater_embeddings),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The results are that the two snowboarding images are very related with a score of greater than 0.9 (scores closer to 1 indicate higher levels of relatedness), while the comparison of the snowboarding and skateboarding images gives a score just over 0.55. Comparing the two skateboarding images generates a relatedness score of greater than 0.75, despite one being on Santa Monica beach and the other in the skatepark at the Paris Olympics.&lt;/p&gt;

&lt;p&gt;Here are the images, together with the results for you to take a look at. I really like the results that I got with Black Forest Labs, and the results from the relatedness calculations.&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%2Fc3997b5rcpfy8vfshp7n.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%2Fc3997b5rcpfy8vfshp7n.png" alt="Image description" width="800" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to the changes to embedding drivers, vector store drivers have been updated to support upserting and querying with &lt;code&gt;ImageArtifact&lt;/code&gt; objects, and the framework’s local vector store has been updated to support persisting multi-modal entries. These changes mean that you can store the embeddings generated for the images into a vector store and then you can query this to find the top x images nearest to the embeddings for a query image. These changes enable Griptape Framework to support image-based use cases such as image similarity search. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Support for Perplexity&lt;/strong&gt;&lt;br&gt;
In this release we’ve added support for the popular AI-powered search and research engine, Perplexity, with the addition of &lt;code&gt;PerplexityPromptDriver&lt;/code&gt; and &lt;code&gt;PerplexityWebSearchDriver&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os

from griptape.drivers.prompt.perplexity import PerplexityPromptDriver
from griptape.rules import Rule
from griptape.structures import Agent
from griptape.tasks import PromptTask

agent = Agent(
   tasks=[
       PromptTask(
           prompt_driver=PerplexityPromptDriver(
               model="sonar-pro", api_key=os.environ["PERPLEXITY_API_KEY"]
           ),
           rules=[
               Rule("Be precise and concise"),
           ],
       )
   ],
)

agent.run("tell me about the griptape framework 1.4 release")

print(agent.output.value)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you experiment with the &lt;code&gt;PerplexityPromptDriver&lt;/code&gt; using the code sample above, you will notice that the responses are generated using search as well as an LLM, meaning that you get up-to-date answers from the web. In this case, the model does a great job finding some of the highlights from the last release of the framework, using the blog post about that release as a source. This makes the &lt;code&gt;PerplexityPromptDriver&lt;/code&gt; a little different to the other prompt drivers in Griptape Framework. We are excited to see what you build with this exciting new capability. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updates to Default Models&lt;/strong&gt;&lt;br&gt;
The default model in the &lt;code&gt;AnthropicPromptDriver&lt;/code&gt; has been updated to &lt;code&gt;claude-3-7-sonnet-latest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you're using Google models, the default model for the &lt;code&gt;GooglePromptDriver&lt;/code&gt; has been updated to &lt;code&gt;gemini-2.0-flash&lt;/code&gt; and the default model for the &lt;code&gt;GoogleEmbeddingDriver&lt;/code&gt; has been updated to &lt;code&gt;embedding-004&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For developers using Amazon Bedrock to access Anthropic’s model, the default model in the &lt;code&gt;AmazonBedrockPromptDriver&lt;/code&gt; has been updated to &lt;code&gt;anthropic.claude-3-7-sonnet-20250219-v1:0&lt;/code&gt;. In addition, the Amazon Titan model used for text embeddings has been updated to &lt;code&gt;amazon.titan-embed-text-v2:0&lt;/code&gt; and the default Amazon Titan model used in the &lt;code&gt;AmazonBedrockImageGenerationDriver&lt;/code&gt; has been updated to &lt;code&gt;amazon.titan-image-generator-v2:0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As usual, you can continue to use previous generation models by setting the model keyword argument to the model that you wish to use when creating an instance of each driver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improved Control over Tool Use&lt;/strong&gt;&lt;br&gt;
If you’ve having trouble getting less powerful LLMs to function correctly when calling tools, the 1.5 release allows you to set &lt;code&gt;reflect_on_tool_use&lt;/code&gt; to &lt;code&gt;False&lt;/code&gt; and have the LLM return tool outputs directly. If you're using a less powerful LLM, you should consider using this setting so that you can make tool calls yourself rather than having the LLM coordinate them. In the very simple code sample below I run three tasks where I provide a DateTimeTool. The code is commented to provide details on the behavior that you should expect, and you can see the results from running this sample below the sample.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from griptape.tasks import PromptTask
from griptape.tools import DateTimeTool
from griptape.artifacts.list_artifact import ListArtifact

# When disabling `reflect_on_tool_use`, Task results will be returned as a ListArtifact.
# Each item in the ListArtifact will be the result of a single tool execution.

date_task = PromptTask(
    tools=[DateTimeTool()],
    reflect_on_tool_use=False,
)
results = date_task.run("How many days until it's 2026?")
# This will fail as the model will not reflect and figure out that an additional tool run is needed to calculate the date delta

if isinstance(results, ListArtifact):
    for result in results:
        print("Simple prompt output without reflection:", result)

date_task = PromptTask(
    tools=[DateTimeTool()],
    reflect_on_tool_use=False,
)
results = date_task.run("How many days from 12:44 on March 19th 2025 to Jan 1st 2026?")
# This will succeed as the prompt is more specific and the model can calculate the date delta using a single tool invocation
# Note that the output is the raw output from the tool

if isinstance(results, ListArtifact):
    for result in results:
        print("Detailed prompt output without reflection:", result)

date_task = PromptTask(
    tools=[DateTimeTool()],
    reflect_on_tool_use=True,
)
results = date_task.run("How many days until it's 2026?")
# This will succeed as the model will invoke the tool multiple times to get the current date &amp;amp; calculate the date delta
# Note that the output is more descriptive as the model has reflected on the final tool inovcation to generate the response

print("Simple prompt output with reflection:", results)
Simple prompt output without reflection: 2025-03-19 12:47:10.882934

Detailed prompt output without reflection: 287 days, 11:16:00

Simple prompt output with reflection: There are 287 days until it's 2026.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;‍&lt;strong&gt;How to get started&lt;/strong&gt;&lt;br&gt;
Griptape Framework 1.5 is available now and you can download it with uv, poetry, pip or another Python package manager of your choice. As usual, we would love to hear your feedback on these changes, together with ideas and suggestions for future imrpovements to the framework. If you want to ask any questions about the other features in this release or discuss your image embedding use-cases, please head over to the &lt;a href="https://discord.com/invite/griptape" rel="noopener noreferrer"&gt;Griptape Discord&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>griptape</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
