Thursday, September 4, 2025

Gemini API

I chose to experiment with the Gemini LLM. I figured that Google is likely to remain competitive in AI for a while. I didn't want to be chasing the latest and greatest LLM every few weeks.

Requirements

You will need these prerequisites

You will need a Google Cloud account and a project with the Gemini API enabled. You will need to create an API key.

Put your Gemini API key in ~/.config/googleapis/{project}/Gemini/apikey

Create a directory ~/Gemini/ to hold Gemini related files. In this directory, create subdirectory ~/Gemini/transcripts/ to hold conversation logs.

Usage

Basic Usage

+default-model+
The default Gemini model to use. You can set this to any model supported by your Google Cloud project. It starts as "gemini-2.5-flash".

invoke-gemini prompt
Invoke Gemini with prompt and return the response as a string. An empty context will be used. Use this to start new conversations.

continue-gemini prompt
Invoke Gemini with prompt and return the response as a string. The accumulated context will be used. Use this to continue your conversation.

Conversations will be logged in ~/Gemini/transcripts/ in files named NNNNNNNNNN-NN.txt. The first number being the universal time that the conversation started, the second number being the number of turns in the conversation.

Advanced Usage

Results generation can be controlled via these special variables:

  • *CANDIDATE-COUNT*
  • *ENABLE-ADVANCED-CIVIC-ANSWERS*
  • *FREQUENCY-PENALTY*
  • *INCLUDE-THOUGHTS*
  • *LANGUAGE-CODE*
  • *LOGPROBS*
  • *MAX-OUTPUT-TOKENS*
  • *MEDIA-RESOLUTION*
  • *MULTI-SPEAKER-VOICE-CONFIG*
  • *PREBUILT-VOICE-CONFIG*
  • *PRESENCE-PENALTY*
  • *RESPONSE-JSON-SCHEMA*
  • *RESPONSE-LOGPROBS*
  • *RESPONSE-MIME-TYPE*
  • *RESPONSE-MODALITIES*
  • *RESPONSE-SCHEMA*
  • *SAFETY-SETTINGS*
  • *SEED*
  • *SPEECH-CONFIG*
  • *STOP-SEQUENCES*
  • *SYSTEM-INSTRUCTION*
  • *TEMPERATURE*
  • *THINKING-BUDGET*
  • *THINKING-CONFIG*
  • *TOOL-CONFIG*
  • *TOOLS*
  • *TOP-K*
  • *TOP-P*
  • *VOICE-CONFIG*
  • *VOICE-NAME*

See the Gemini API documentation for details on what these do. If you leave them alone, you will get the default values. I suggest binding *include-thoughts* to T in order to have thoughts printed during processing and *temperature* to a value between 0 (very deterministic) and 2 (very random) if you want something other than the default value of 1. Don't fool around with the other values unless you know what you are doing.

Prompts

The default prompt is just a string. This is so that you can use the LLM as a string to string mapping. However, you can supply a fully structured content object with multiple parts if you wish. For example, you could supply

(content
    (part "Describe this function.")
    (part "```lisp
(defun foo (x) (+ x 3))
```"))

Tools

  • *enable-bash* — enable the shell command tool.
  • *enable-eval* — enable the lisp interpreter tool.
  • *enable-interaction* — allow the LLM to query the user for input.
  • *enable-lisp-introspection — allow the LLM to query if symbols are bound or fbound and to query ASDF and Quicklisp modules and load them.
  • *enable-personality* — give the LLM a pseudorandom personality.
  • *enable-web-functions — allow the LLM to perform HTTP GET and POST commands.
  • *enable-web-search — allow the LLM to perform web searches.

Personality

Unless you disable personality (default is enabled), the LLM will be instructed to respond in a randomly selected literary or celebrity style. This is just for amusement. Some personalities are quite obnoxious. Personalities change every day.

without-personality &body body
disable personality while executing body.

new-personality
Select a new personality at random. Use this if you find the current personality too obnoxious.

personalities.txt personalities are selected from this file. Each line contains a personality description. Blank lines and comments are ignored.

MCP

Currently only stdio MCP servers are supported.

~/.config/mcp/mcp.lisp contains the configurations for any MCP servers you wish to supply to the model. Here is an example file:

((:mcp-servers

  ("memory"
   (:command "npx")
   (:args "-y" "@modelcontextprotocol/server-memory")
   (:env ("MEMORY_FILE_PATH" . "/home/jrm/memory.json"))
   (:system-instruction "You have access to a persistent memory that stores entities and relationships between them.  You can add, update, delete, and query entities and relationships as needed."))

  ("sequential-thinking"
   (:command "npx")
   (:args "-y" "@modelcontextprotocol/server-sequential-thinking")
   (:system-instruction "You can use this tool to break down complex tasks into smaller, manageable steps.  You can create, view, and complete steps as needed."))

  ("mcp-server-time"
   (:command "uvx")
   (:args "mcp-server-time")
   (:system-instruction "You have access to the current date and time along with time zone information."))
  ))

No comments: