goracle

package module
v0.0.0-...-fa30edc Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2024 License: MIT Imports: 10 Imported by: 0

README

GOracle - A User-Friendly Go Library for LLMs

Overview

GOracle is a simple API for easy integration with AI models (ChatGPT, Gemini etc.)

import "github.com/mr-joshcrane/goracle"

GOracle is a convenience library designed to help Golang developers bring the power of (LLMs) into their Go applications. Our goal is to provide a straightforward and efficient experience for Go developers by offering a common API layer that abstracts the complexities of various LLM platforms down into the client layer, while providing a small stable interface.

It's designed to be small, simple, and powerful!

In fact, this README was ghost written by an LLM, with a lot of oversight from it's human editor. Check out the code here!

Features

  • Simple interaction with LLMs from Go applications.
  • Compatibility with multiple large language models such as OpenAI's GPT and Google's VertexAI.
  • Support for diverse types of reference materials (text, images, and files).
  • State management features for sustained conversations and context control.
  • Extensible design for adding new LLM providers in the future.

The Ask Method

The Ask method is the core function of GOracle. It allows developers to pose questions to an LLM and receive a response. This method takes a question as a string input and optional reference arguments. These references can be used to provide additional context to the LLM in various forms such as text, images, or file content.

Usage Example
o := oracle.NewChatGPTOracle("your-token-here")
response, err := o.Ask("What is the capital of France?")
if err != nil {
    log.Fatal(err)
}
fmt.Println(response)
// Response: Paris!

Reference Concept

A reference in GOracle provides context to the LLM to assist with generating an accurate and relevant response. References can be text excerpts, image data, or file contents that inform the LLM about the context or domain of the question being asked.

Supported Types
  • Textual content as strings or bytes.
  • Images represented in Go's image.Image interface.
  • File content using byte slices with file-reader functionality.
Using References

References can enhance the quality of the LLM's responses by providing relevant examples or additional data. You can include references when using the Ask method.

Reference Usage Example
imageRef := // ... some image.Image object
fileRef := oracle.File("example.txt")
stringRef := "some big mess of text"

response, err := o.Ask( 
    "Can you analyze the content of these references?", 
    imageRef, 
    fileRef,
    stringRef,
)
if err != nil {
    log.Fatal(err)
}
fmt.Println(response)

Please note that GOracle only serves as a convenience tool for LLM integrations and does not include the actual language models. Users are required to have proper access to the LLM platforms (like OpenAI or Google Cloud's VertexAI) with necessary API keys or tokens configured.

Users should also be aware that GOracle has no awareness of billing, so in the interests of your hip pocket, set the appropriate hard caps or limits on spending!

We hope GOracle empowers you to build out your Golang applications with the powerful capabilities of LLMs, bringing complex language understanding and generation features to your user base. Enjoy the simplified experience of using LLMs in your next project!

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func File

func File(path string) []byte

A Reference helper that reads a file from disk and returns the contents as an array of bytes. Content will be a snapshot of the file at the time of calling. Consider calling inside the Ask method or using a closure to ensure lazy evaluation if you're going to be editing read file in place.

func Folder

func Folder(root string, includeFilter ...string) []byte

A Reference helper that takes a folder in a filesystem and returns the contents of all files in that folder as an array of bytes. Content will be a snapshot of the files at the time of calling. Call is recursive, so be careful with what you include. Consider adding one of more filters to the includeFilter such as ".go" to only include certain files or similar globs.

func Image

func Image(i image.Image) []byte

A Reference helper that takes an image and returns it's contents as an array of bytes. Currently encodes to PNGs to be passed to the upstream client. Content will be a snapshot of the image at the time of calling.

Types

type LanguageModel

type LanguageModel interface {
	Completion(ctx context.Context, prompt client.Prompt) (io.Reader, error)
}

LanguageModel is an interface that abstracts a concrete implementation of our language model API call.

type Oracle

type Oracle struct {
	// contains filtered or unexported fields
}

Oracle is a struct that scaffolds a well formed Oracle, designed in a way that facilitates the asking of one or many questions to an underlying Large Language Model.

func NewChatGPTOracle

func NewChatGPTOracle(token string) *Oracle

NewChatGPTOracle takes an OpenAI API token and sets up a new ChatGPT Oracle with sensible defaults.

func NewGoogleGeminiOracle

func NewGoogleGeminiOracle() *Oracle

NewGoogleGeminiOracle uses the

func NewOllamaOracle

func NewOllamaOracle(model string, endpoint string) *Oracle

func NewOracle

func NewOracle(client LanguageModel) *Oracle

NewOracle returns a new Oracle with sensible defaults.

func (*Oracle) Ask

func (o *Oracle) Ask(question string, references ...any) (string, error)

Ask asks the Oracle a question, and returns the response from the underlying Large Language Model. Ask massages the query and supporting references into a standardised format that is relatively generalisable across models.

Example (StandardTextCompletion)
package main

import (
	"fmt"

	"github.com/mr-joshcrane/goracle"
	"github.com/mr-joshcrane/goracle/client"
)

func main() {
	// Basic request response text flow
	c := client.NewDummyClient("A friendly LLM response!", nil)
	o := goracle.NewOracle(c)
	answer, err := o.Ask("A user question")
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
}
Output:

A friendly LLM response!
Example (WithConversationMemory)
package main

import (
	"fmt"

	"github.com/mr-joshcrane/goracle"
	"github.com/mr-joshcrane/goracle/client"
)

func main() {
	// For when you want the responses to be Stateful
	// and depend on the previous answers
	// this is the default and matches the typical chatbot experience
	c := client.NewDummyClient("We talked about the answer to life, the universe, and everything", nil)
	o := goracle.NewOracle(c)

	// This is the default, but can be set manually
	o.Remember()
	_, err := o.Ask("What is the answer to life, the universe, and everything?")
	if err != nil {
		panic(err)
	}
	answer, err := o.Ask("What have we already talked about?")
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
}
Output:

We talked about the answer to life, the universe, and everything
Example (WithExamples)
package main

import (
	"fmt"

	"github.com/mr-joshcrane/goracle"
	"github.com/mr-joshcrane/goracle/client"
)

func main() {
	// Examples allow you to guide the LLM with n-shot learning
	c := client.NewDummyClient("42", nil)
	o := goracle.NewOracle(c)
	o.GiveExample("Fear is the...", "mind killer")
	o.GiveExample("With great power comes...", "great responsibility")
	answer, err := o.Ask("What is the answer to life, the universe, and everything?")
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
}
Output:

42
Example (WithReferences)
package main

import (
	"fmt"
	"image"

	"github.com/mr-joshcrane/goracle"
	"github.com/mr-joshcrane/goracle/client"
)

func main() {
	// Basic request response text flow with multi-modal references
	c := client.NewDummyClient("Yes. There is a reference to swiss cheese in cheeseDocs/swiss.txt", nil)
	o := goracle.NewOracle(c)
	nonCheeseImage := image.NewRGBA(image.Rect(0, 0, 100, 100))
	answer, err := o.Ask(
		"My question for you is, do any of my references make mention of swiss cheese?",
		"Some long chunk of text, that is notably non related",
		goracle.File("invoice.txt"),
		nonCheeseImage,
		goracle.Folder("~/cheeseDocs/"),
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
}
Output:

Yes. There is a reference to swiss cheese in cheeseDocs/swiss.txt
Example (WithoutConversationMemory)
package main

import (
	"fmt"

	"github.com/mr-joshcrane/goracle"
	"github.com/mr-joshcrane/goracle/client"
)

func main() {
	// For when you want the responses to be Staskteless
	// and not depend on the previous answers/examples
	c := client.NewDummyClient("Nothing so far", nil)
	o := goracle.NewOracle(c)

	//
	o.Forget()
	_, err := o.Ask("What is the answer to life, the universe, and everything?")
	if err != nil {
		panic(err)
	}
	answer, err := o.Ask("What have we already talked about?")
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
}
Output:

Nothing so far

func (*Oracle) AskWithContext

func (o *Oracle) AskWithContext(ctx context.Context, question string, references ...any) (string, error)

AskWithContext is similar to *Oracle.Ask but allows for a context to be passed in.

Example (WithTimeout)
package main

import (
	"context"
	"fmt"
	"time"

	"github.com/mr-joshcrane/goracle"
	"github.com/mr-joshcrane/goracle/client"
)

func main() {
	// For when you want to limit the amount of time the LLM has to respond
	c := client.NewDummyClient("A friendly LLM response!", nil)
	o := goracle.NewOracle(c)
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	answer, err := o.AskWithContext(ctx, "A user question")
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
}
Output:

A friendly LLM response!

func (*Oracle) Forget

func (o *Oracle) Forget() *Oracle

Forget [Oracles Oracle] forget the conversation history and do not keep track of the context of the conversation. This is useful for when you want to ask a single question without previous context affecting the answers.

func (*Oracle) GiveExample

func (o *Oracle) GiveExample(givenInput string, idealCompletion string)

GiveExample adds an example to the list of examples. These examples used to guide the models response. Quality of the examples is more important than quantity here. Calling this method on a stateless Oracle will have no effect. This allows for stateless oracles to still benefit from n-shot learning.

func (*Oracle) Remember

func (o *Oracle) Remember() *Oracle

Remember [Oracles Oracle] remember the conversation history and keep track of the context of the conversation. This is the default behaviour. References are not persisted between calls in order to keep the prompt size down. If this behaviour is desired, you can pass the references with oracle.GiveExample like so: oracle.GiveExample(oracle.File("path/to/file", "<your preferred bot response>"))

func (*Oracle) Reset

func (o *Oracle) Reset()

Reset clears the Oracle's previous chat history Useful for when you hit a context limit Doesn't affect the Oracle's purpose, or whether it's stateful or not

func (*Oracle) SetPurpose

func (o *Oracle) SetPurpose(purpose string)

SetPurpose sets the purpose of the Oracle, which frames the models response.

type Prompt

type Prompt struct {
	Purpose       string
	InputHistory  []string
	OutputHistory []string
	References    [][]byte
	Question      string
}

Prompt is a struct that scaffolds a well formed prompt, designed in a way that are ideal for Large Language Models. This is the abstraction we will pass through to the client library so it can be handled appropriately

func (Prompt) GetHistory

func (p Prompt) GetHistory() ([]string, []string)

GetHistory returns a list of examples that are used to guide the Models response. Quality of the examples is more important than quantity here.

func (Prompt) GetPurpose

func (p Prompt) GetPurpose() string

GetPurpose returns the purpose of the prompt, which frames the models response.

func (Prompt) GetQuestion

func (p Prompt) GetQuestion() string

GetQuestion returns the question that the user is asking the Model

func (Prompt) GetReferences

func (p Prompt) GetReferences() [][]byte

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL