To experiment with LLMs I chose to use Gemini. The cost is modest and I expect Google to regularly improve the model so that it remains competitive. I wrote a Gemini client in Common Lisp. Some people have already forked the repo, but I've refactored things recently so I thought I'd give a quick rundown of the code.
google repository
https://github.com/jrm-code-project/googleWhen I add APIs to Google, I intend to put them in this repository. It is pretty empty so far, but here is where they will go. Contributions welcome.
Basic Requirements
There are some basic libraries you can load with Zach Beane's
Quicklisp. alexandria
for some selected Common Lisp extensions,
cl-json
for JSON parsing, dexador
for HTTP
requests, and str
for string manipulation. I also
use series
(available from SourceForge). My
own fold
, function
, named-let
,
and jsonx
libraries are also used (available from GitHub).
fold
gives you fold-left
for list
reduction. function
gives
you compose
. jsonx
modifies cl-json
to remove the ambiguity betweeen JSON
objects and nested arrays. named-let
gives you the
named let syntax from Scheme for local iteration and recursion.
Google API
The google
repository contains the beginnings of a
Common Lisp client to Google services. It currently only supports
an interface to Blogger that can return your blog content as a
series of posts and an interface to Google's Custom Search Engine
API. You create a Google services account (there is a free tier,
and a paid tier if you want more). You create a project (you'll
want at least a default project), and within
that project you enable the Google services that you want that project
to have access to.
API Keys and Config Files
For each service you can get an API key.
In your XDG config directory (usually "~/.config/
") you
create a googleapis
directory and subdirectories for
each project you have created.
The ~/.config/googleapis/default-project
file contains
the name of your default project. In the examples below, it
contains the string my-project
.
Within each project directory you create subdirectories for each
service you want to use. In each service directory you create a
file to hold the API key and possibly other files to hold IDs,
options, and other config information. For example, for Blogger you
create ~/.config/googleapis/my-project/Blogger/apikey
to hold your
Blogger API key
and ~/.config/googleapis/my-project/Blogger/blog-id
to
hold your blog ID.
Here is a sample directory structure:
~/.config/googleapis/ ├── my-project/ │ ├── Blogger/ │ │ ├── apikey │ │ └── blog-id │ ├── CustomSearchEngine/ │ │ ├── apikey │ │ ├── hyperspec-id │ │ └── id │ └── Gemini/ │ └── apikey └── default-project
When you create the API keys for the various services, it is a good idea to restrict the API key for only that service. That way, if the API key is compromised, the damage is limited to a single service.
Blogger
The blogger API will eventually have more features, but it currently only allows you to get the posts from a blog as a series.
scan-blogger-posts blog-id
Returns a series of posts from the blog with the given ID. Each post
comes back as a JSON object (hash-table).
The :content
field contains the HTML content of the
post.
Custom Search Engine
The Custom Search Engine API allows you to search a set of web
pages. You create a search engine on Google and pass the
ID custom-search
. It is assumed that the default
CustomSearchEngine id is a default, vanilla search, and that the
hyperspec id searches the Common Lisp Hyperspec.
In each search, be sure to replace the spaces in the query with
plus signs (+
) before searching.
custom-search query &key custom-search-engine-id
Returns search results for query. Each search result comes back as
a JSON object (hash-table).
web-search query
Search the web and return search results for query. Each search result comes back as
a JSON object (hash-table).
hyperspec-search query
Search the Common Lisp Hyperspec and return search results for
query. Each search result comes back as a JSON object (hash-table).
No comments:
Post a Comment