diff --git a/README.org b/README.org
index af3b63b..9eebfb8 100644
--- a/README.org
+++ b/README.org
@@ -76,9 +76,6 @@ I change models a lot, and this /just works/ for most models, even if some aren'
 (require 'gptel)
 #+end_src
 
-#+RESULTS:
-: gptel
-
 With that out of the way, let's get to the tools.
 * Usage options:
 I only use Doom Emacs, so here's how I do it.
@@ -168,7 +165,40 @@ Collects into =gptel-org-tools= list, distinct from =gptel-tools=
 #+begin_src elisp
 (defvar gptel-org-tools '())
 #+end_src
+** Helper Functions
+These abstract away some of the tool definitions.
 
+Both of these clear the org-ql-cache to work around issues where a file may be updated between tool calls.
+*** Retrieve heading and body (without subheadings)
+#+begin_src elisp
+(defun gptel-org-tools--heading-body ()
+    (concat
+     (buffer-substring-no-properties
+      (line-beginning-position)
+      (progn
+	(outline-next-heading)
+	(line-beginning-position)))
+     "---\n"))
+#+end_src
+
+*** Retrieve heading and subheadings (until next same-level heading)
+#+begin_src elisp
+(defun gptel-org-tools--heading-subtree ()
+    (concat
+     (buffer-substring-no-properties
+      (line-beginning-position)
+      (org-end-of-subtree))
+     "---\n"))
+#+end_src
+** Note on org-ql
+Given that there isn't (yet?) a built-in way of disabling caching, every (org-ql-select) call is wrapped like so.
+
+See [[https://github.com/alphapapa/org-ql/issues/437][this issue]] for details.
+
+#+begin_src elisp :tangle no
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select ...))
+#+end_src
 ** The tools
 *** Emacs
 These tools are primarily concerned with Emacs, Emacs Lisp, and files-or-buffers.
@@ -430,13 +460,7 @@ Currently *not* tangled, as I'm testing breaking out each type of query into its
     (if (stringp query)
 	(read query)
       query)
-    :action #'(lambda ()
-		(concat
-		 (buffer-substring-no-properties
-		  (line-beginning-position)
-		  (progn
-		    (outline-next-heading)
-		    (line-beginning-position)))))))
+    :action #'gptel-org-tools--heading-body
 
 (add-to-list 'gptel-org-tools
 	     (gptel-make-tool
@@ -477,10 +501,7 @@ But, any customizations to tweak this is left to the user, as everyone has their
   (org-ql-select
     (get-buffer buf)
     `(heading ,date)
-    :action #'(lambda ()
-		(buffer-substring-no-properties
-		 (line-beginning-position)
-		 (org-end-of-subtree)))))
+    :action #'gptel-org-tools--heading-subtree))
 
 
 (add-to-list 'gptel-org-tools
@@ -525,14 +546,15 @@ The following tools are still very much WIP, and I think they're self-explanator
 Retrieve the headings where the heading matches query..
 #+begin_src elisp
 (defun gptel-org-tools--org-ql-select-headings (buf query)
-  (org-ql-select
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select
     (get-buffer buf)
     `(heading ,query)
     :action #'(lambda ()
 		(concat
 		 (buffer-substring-no-properties
 		  (line-beginning-position)
-		  (line-end-position))))))
+		  (line-end-position)))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -545,7 +567,7 @@ Retrieve the headings where the heading matches query..
 			    :description "The name of the buffer. See the NAME column in ~emacs-list-buffers~.")
 			  '(:name "query"
 			    :type string
-			    :description "The string to pass into org-ql-select-headings. This is a bare string. Example: \"searchterm\""))
+			    :description "The string to match entry headings against."))
 	      :category "org-ql"))
 #+end_src
 
@@ -553,14 +575,15 @@ Retrieve the headings where the heading matches query..
 Retrieve all the headings where either heading or content matches query.
 #+begin_src elisp
 (defun gptel-org-tools--org-ql-select-headings-rifle (buf query)
-  (org-ql-select
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select
     (get-buffer buf)
     `(rifle ,query)
     :action #'(lambda ()
 			(concat
 			 (buffer-substring-no-properties
 			  (line-beginning-position)
-			  (line-end-position))))))
+			  (line-end-position)))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -573,7 +596,7 @@ Retrieve all the headings where either heading or content matches query.
 			    :description "The name of the buffer. See the NAME column in ~emacs-list-buffers~.")
 			  '(:name "query"
 			    :type string
-			    :description "The string to pass into org-ql-select-headings-rifle. This is a bare string. Example: \"searchterm\""))
+			    :description "The string to match entry headings against."))
 	      :category "org-ql"))
 #+end_src
 
@@ -581,7 +604,8 @@ Retrieve all the headings where either heading or content matches query.
 This pulls all the headings (and their contents) when they match tags (without inheritance.)
 #+begin_src elisp
 (defun gptel-org-tools--org-ql-select-tags-local (buf query)
-  (org-ql-select
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select
     (get-buffer buf)
     `(tags-local ,query)
     :action #'(lambda ()
@@ -590,7 +614,7 @@ This pulls all the headings (and their contents) when they match tags (without i
 		  (line-beginning-position)
 		  (progn
 		    (outline-next-heading)
-		    (line-beginning-position)))))))
+		    (line-beginning-position))))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -603,7 +627,7 @@ This pulls all the headings (and their contents) when they match tags (without i
 			    :description "The name of the buffer. See the NAME column in `emacs-list-buffers`. Using filename fails.")
 			  '(:name "query"
 			    :type string
-			    :description "The tags to match entry headings against. Example: \"tag1\" \"tag2\""))
+			    :description "The string match entry tags against."))
 	      :category "org-ql"))
 #+end_src
 
@@ -611,7 +635,8 @@ This pulls all the headings (and their contents) when they match tags (without i
 This pulls all the headings (and their contents) when they match tags (with inheritance; if a parent entry has the tag, descendant entries do, too.)
 #+begin_src elisp
 (defun gptel-org-tools--org-ql-select-tags (buf query)
-  (org-ql-select
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select
     (get-buffer buf)
     `(tags ,query)
     :action #'(lambda ()
@@ -620,7 +645,7 @@ This pulls all the headings (and their contents) when they match tags (with inhe
 		  (line-beginning-position)
 		  (progn
 		    (outline-next-heading)
-		    (line-beginning-position)))))))
+		    (line-beginning-position))))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -633,15 +658,16 @@ This pulls all the headings (and their contents) when they match tags (with inhe
 			    :description "The name of the buffer. See the NAME column in `emacs-list-buffers`. Using filename fails.")
 			  '(:name "query"
 			    :type string
-			    :description "The tags to match entry headings against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry headings against."))
 	      :category "org-ql"))
 #+end_src
 
 ***** org-ql-select-rifle
 And, the "grab everything that matches" tool.
 #+begin_src elisp
-(defun gptel-org-tools--org-ql-select-rifle (buf query)
-  (let ((buffer (get-buffer buf)))
+(defun hash-gptl-org-tools--org-ql-select-rifle ()
+    (let ((org-ql-cache (make-hash-table))
+	  (buffer (get-buffer buf)))
     (if buffer
         (org-ql-select
           buffer
@@ -665,15 +691,15 @@ And, the "grab everything that matches" tool.
 			    :description "The name of the buffer. See the NAME column in `emacs-list-buffers`. Using filename fails.")
 			  '(:name "query"
 			    :type string
-			    :description "The strings to match entry headings and content against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry headings and content against."))
 	      :category "org-ql"))
 #+end_src
 
-
 ***** org-ql-select-agenda-tags-local
 This pulls all the headings (and their contents) when they match tags (without inheritance.)
 #+begin_src elisp
 (defun gptel-org-tools--org-ql-select-agenda-tags (query)
+  (let ((org-ql-cache (make-hash-table)))
   (org-ql-select
     (org-agenda-files)
     `(tags-local ,query)
@@ -683,7 +709,7 @@ This pulls all the headings (and their contents) when they match tags (without i
 		  (line-beginning-position)
 		  (progn
 		    (outline-next-heading)
-		    (line-beginning-position)))))))
+		    (line-beginning-position))))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -693,7 +719,7 @@ This pulls all the headings (and their contents) when they match tags (without i
 	      :description "Run simple word query  against all files in (org-agenda-files). WITHOUT tag inheritance, only directly tagged headings."
 	      :args (list '(:name "query"
 			    :type string
-			    :description "Plain list of strings to match entry headings and content against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry tags against."))
 	      :category "org-ql"))
 #+end_src
 
@@ -701,6 +727,7 @@ This pulls all the headings (and their contents) when they match tags (without i
 This pulls all the headings (and their contents) when they match tags (with inheritance; if a parent entry has the tag, descendant entries do, too.)
 #+begin_src elisp
 (defun gptel-org-tools--org-ql-select-agenda-tags (query)
+  (let ((org-ql-cache (make-hash-table)))
   (org-ql-select
     (org-agenda-files)
     `(tags ,query)
@@ -710,7 +737,7 @@ This pulls all the headings (and their contents) when they match tags (with inhe
 		  (line-beginning-position)
 		  (progn
 		    (outline-next-heading)
-		    (line-beginning-position)))))))
+		    (line-beginning-position))))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -720,7 +747,7 @@ This pulls all the headings (and their contents) when they match tags (with inhe
 	      :description "Run simple word query  against all files in (org-agenda-files). WITH tag inheritance."
 	      :args (list '(:name "query"
 			    :type string
-			    :description "Plain list of strings to match entry headings and content against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry tags against."))
 	      :category "org-ql"))
 #+end_src
 
@@ -737,6 +764,7 @@ This means that /every org-mode file I have/ is part of this search.
 
 #+begin_src elisp
 (defun gptel-org-tools--org-ql-select-agenda-rifle (query)
+  (let ((org-ql-cache (make-hash-table)))
   (org-ql-select
     (org-agenda-files)
     `(rifle ,query)
@@ -746,7 +774,7 @@ This means that /every org-mode file I have/ is part of this search.
                   (line-beginning-position)
                   (progn
                     (outline-next-heading)
-                    (line-beginning-position)))))))
+                    (line-beginning-position))))))))
 
 (add-to-list 'gptel-org-tools
 	     (gptel-make-tool
@@ -755,7 +783,7 @@ This means that /every org-mode file I have/ is part of this search.
 	      :description "Run simple word query against all files in (org-agenda-files)"
 	      :args (list '(:name "query"
 			    :type string
-			    :description "Plain list of strings to match entry headings and content against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry headings and content against."))
 	      :category "org-ql"))
 #+end_src
 
diff --git a/gptel-org-tools.el b/gptel-org-tools.el
index 5abd253..800c57b 100644
--- a/gptel-org-tools.el
+++ b/gptel-org-tools.el
@@ -38,6 +38,22 @@
 
 (defvar gptel-org-tools '())
 
+(defun gptel-org-tools--heading-body ()
+    (concat
+     (buffer-substring-no-properties
+      (line-beginning-position)
+      (progn
+	(outline-next-heading)
+	(line-beginning-position)))
+     "---\n"))
+
+(defun gptel-org-tools--heading-subtree ()
+    (concat
+     (buffer-substring-no-properties
+      (line-beginning-position)
+      (org-end-of-subtree))
+     "---\n"))
+
 (add-to-list 'gptel-org-tools
 	     (gptel-make-tool
 	      :function (lambda (arg)
@@ -167,10 +183,7 @@
   (org-ql-select
     (get-buffer buf)
     `(heading ,date)
-    :action #'(lambda ()
-		(buffer-substring-no-properties
-		 (line-beginning-position)
-		 (org-end-of-subtree)))))
+    :action #'gptel-org-tools--heading-subtree))
 
 
 (add-to-list 'gptel-org-tools
@@ -202,14 +215,15 @@
 	      :category "org"))
 
 (defun gptel-org-tools--org-ql-select-headings (buf query)
-  (org-ql-select
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select
     (get-buffer buf)
     `(heading ,query)
     :action #'(lambda ()
 		(concat
 		 (buffer-substring-no-properties
 		  (line-beginning-position)
-		  (line-end-position))))))
+		  (line-end-position)))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -222,18 +236,19 @@
 			    :description "The name of the buffer. See the NAME column in ~emacs-list-buffers~.")
 			  '(:name "query"
 			    :type string
-			    :description "The string to pass into org-ql-select-headings. This is a bare string. Example: \"searchterm\""))
+			    :description "The string to match entry headings against."))
 	      :category "org-ql"))
 
 (defun gptel-org-tools--org-ql-select-headings-rifle (buf query)
-  (org-ql-select
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select
     (get-buffer buf)
     `(rifle ,query)
     :action #'(lambda ()
 			(concat
 			 (buffer-substring-no-properties
 			  (line-beginning-position)
-			  (line-end-position))))))
+			  (line-end-position)))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -246,11 +261,12 @@
 			    :description "The name of the buffer. See the NAME column in ~emacs-list-buffers~.")
 			  '(:name "query"
 			    :type string
-			    :description "The string to pass into org-ql-select-headings-rifle. This is a bare string. Example: \"searchterm\""))
+			    :description "The string to match entry headings against."))
 	      :category "org-ql"))
 
 (defun gptel-org-tools--org-ql-select-tags-local (buf query)
-  (org-ql-select
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select
     (get-buffer buf)
     `(tags-local ,query)
     :action #'(lambda ()
@@ -259,7 +275,7 @@
 		  (line-beginning-position)
 		  (progn
 		    (outline-next-heading)
-		    (line-beginning-position)))))))
+		    (line-beginning-position))))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -272,11 +288,12 @@
 			    :description "The name of the buffer. See the NAME column in `emacs-list-buffers`. Using filename fails.")
 			  '(:name "query"
 			    :type string
-			    :description "The tags to match entry headings against. Example: \"tag1\" \"tag2\""))
+			    :description "The string match entry tags against."))
 	      :category "org-ql"))
 
 (defun gptel-org-tools--org-ql-select-tags (buf query)
-  (org-ql-select
+  (let ((org-ql-cache (make-hash-table)))
+    (org-ql-select
     (get-buffer buf)
     `(tags ,query)
     :action #'(lambda ()
@@ -285,7 +302,7 @@
 		  (line-beginning-position)
 		  (progn
 		    (outline-next-heading)
-		    (line-beginning-position)))))))
+		    (line-beginning-position))))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -298,11 +315,12 @@
 			    :description "The name of the buffer. See the NAME column in `emacs-list-buffers`. Using filename fails.")
 			  '(:name "query"
 			    :type string
-			    :description "The tags to match entry headings against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry headings against."))
 	      :category "org-ql"))
 
-(defun gptel-org-tools--org-ql-select-rifle (buf query)
-  (let ((buffer (get-buffer buf)))
+(defun hash-gptl-org-tools--org-ql-select-rifle ()
+    (let ((org-ql-cache (make-hash-table))
+	  (buffer (get-buffer buf)))
     (if buffer
         (org-ql-select
           buffer
@@ -326,10 +344,11 @@
 			    :description "The name of the buffer. See the NAME column in `emacs-list-buffers`. Using filename fails.")
 			  '(:name "query"
 			    :type string
-			    :description "The strings to match entry headings and content against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry headings and content against."))
 	      :category "org-ql"))
 
 (defun gptel-org-tools--org-ql-select-agenda-tags (query)
+  (let ((org-ql-cache (make-hash-table)))
   (org-ql-select
     (org-agenda-files)
     `(tags-local ,query)
@@ -339,7 +358,7 @@
 		  (line-beginning-position)
 		  (progn
 		    (outline-next-heading)
-		    (line-beginning-position)))))))
+		    (line-beginning-position))))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -349,10 +368,11 @@
 	      :description "Run simple word query  against all files in (org-agenda-files). WITHOUT tag inheritance, only directly tagged headings."
 	      :args (list '(:name "query"
 			    :type string
-			    :description "Plain list of strings to match entry headings and content against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry tags against."))
 	      :category "org-ql"))
 
 (defun gptel-org-tools--org-ql-select-agenda-tags (query)
+  (let ((org-ql-cache (make-hash-table)))
   (org-ql-select
     (org-agenda-files)
     `(tags ,query)
@@ -362,7 +382,7 @@
 		  (line-beginning-position)
 		  (progn
 		    (outline-next-heading)
-		    (line-beginning-position)))))))
+		    (line-beginning-position))))))))
 
 
 (add-to-list 'gptel-org-tools
@@ -372,10 +392,11 @@
 	      :description "Run simple word query  against all files in (org-agenda-files). WITH tag inheritance."
 	      :args (list '(:name "query"
 			    :type string
-			    :description "Plain list of strings to match entry headings and content against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry tags against."))
 	      :category "org-ql"))
 
 (defun gptel-org-tools--org-ql-select-agenda-rifle (query)
+  (let ((org-ql-cache (make-hash-table)))
   (org-ql-select
     (org-agenda-files)
     `(rifle ,query)
@@ -385,7 +406,7 @@
                   (line-beginning-position)
                   (progn
                     (outline-next-heading)
-                    (line-beginning-position)))))))
+                    (line-beginning-position))))))))
 
 (add-to-list 'gptel-org-tools
 	     (gptel-make-tool
@@ -394,7 +415,7 @@
 	      :description "Run simple word query against all files in (org-agenda-files)"
 	      :args (list '(:name "query"
 			    :type string
-			    :description "Plain list of strings to match entry headings and content against. Example: \"tag1\" \"tag2\""))
+			    :description "The string to match entry headings and content against."))
 	      :category "org-ql"))
 
 (provide 'gptel-org-tools)