GithubHelp home page GithubHelp logo

gollum's Introduction

GOLLuM

Production-grade LLM tooling. At least, in theory -- stuff changes fast so don't expect stability from this library so much as ideas for your own apps.

Features

  • Sane LLM provider abstraction.
  • Automated function dispatch
    • Parses arbitrary Go structs into JSONSchema for OpenAI - and validates when unmarshaling back to your structs
    • Simplified API to generate results from a single prompt or template
  • Highly performant vector store solution with exact search
    • SIMD acceleration for 10x better perf than naive approach, constant memory usage
    • Drop-in integration with OpenAI and other embedding providers
    • Carefully mocked, tested, and benchmarked.
  • Implementation of HyDE (hypothetical documents embeddings) for enhanced retrieval
  • MIT License

Examples

Dispatch

Function dispatch is a highly simplified and easy way to generate filled structs via an LLM.

type dinnerParty struct {
	Topic       string   `json:"topic" jsonschema:"required" jsonschema_description:"The topic of the conversation"`
	RandomWords []string `json:"random_words" jsonschema:"required" jsonschema_description:"Random words to prime the conversation"`
}
completer := openai.NewClient(os.Getenv("OPENAI_API_KEY"))
d := gollum.NewOpenAIDispatcher[dinnerParty]("dinner_party", "Given a topic, return random words", completer, nil)
output, _ := d.Prompt(context.Background(), "Talk to me about dinosaurs")

The result should be a filled `dinnerParty`` struct.

expected := dinnerParty{
		Topic:       "dinosaurs",
		RandomWords: []string{"dinosaur", "fossil", "extinct"},
	}

Some similar libraries / ideas:

Parsing

Simplest

Imagine you have a function GetWeather --

type getWeatherInput struct {
	Location string `json:"location" jsonschema_description:"The city and state, e.g. San Francisco, CA" jsonschema:"required"`
	Unit     string `json:"unit,omitempty" jsonschema:"enum=celsius,enum=fahrenheit" jsonschema_description:"The unit of temperature"`
}

type getWeatherOutput struct {
    // ...
}

// GetWeather does something, this dosctring is annoying but theoretically possible to get
func GetWeather(ctx context.Context, inp getWeatherInput) (out getWeatherOutput, err error) {
    return out, err
}

This is a common pattern for API design, as it is eay to share the getWeatherInput struct (well, imagine if it were public). See, for example, the GRPC service definitions, or the Connect RPC implementation. This means we can simplify the logic greatly by assuming a single input struct.

Now, we can construct the responses:

type getWeatherInput struct {
	Location string `json:"location" jsonschema_description:"The city and state, e.g. San Francisco, CA" jsonschema:"required"`
	Unit     string `json:"unit,omitempty" jsonschema:"enum=celsius,enum=fahrenheit" jsonschema_description:"The unit of temperature"`
}

fi := gollum.StructToJsonSchema("weather", "Get the current weather in a given location", getWeatherInput{})

chatRequest := openai.ChatCompletionRequest{
    Model: "gpt-3.5-turbo-0613",
    Messages: []openai.ChatCompletionMessage{
        {
            Role:    "user",
            Content: "Whats the temperature in Boston?",
        },
    },
    MaxTokens:   256,
    Temperature: 0.0,
    Tools:       []openai.Tool{{Type: "function", Function: openai.FunctionDefinition(fi)}},
    ToolChoice:  "weather",
}

ctx := context.Background()
resp, err := api.SendRequest(ctx, chatRequest)
parser := gollum.NewJSONParser[getWeatherInput](false)
input, err := parser.Parse(ctx, resp.Choices[0].Message.ToolCalls[0].Function.Arguments)

This example steps through all that, end to end. Some of this is 'sort of' pseudo-code, as the OpenAI clients I use haven't implemented support yet for functions, but it should also hopefully show that minimal modifications are necessary to upstream libraries.

It is also possible to go from just the function definition to a fully formed OpenAI FunctionCall. Reflection gives name of the function for free, godoc parsing can get the function description too. I think in practice though that it's fairly unlikely that you need to change the name/description of the function that often, and in practice the inputs change more often. Using this pattern and compiling once makes the most sense to me.

We should be able to chain the call for the single input and for the ctx + single input case and return it easily.

Recursion on arbitrary structs without explicit definitions

Say you have a struct that has JSON tags defined.

fi := gollum.StructToJsonSchema("ChatCompletion", "Call the OpenAI chat completion API", chatCompletionRequest{})

chatRequest := chatCompletionRequest{
    ChatCompletionRequest: openai.ChatCompletionRequest{
        Model: "gpt-3.5-turbo-0613",
        Messages: []openai.ChatCompletionMessage{
            {
                Role:    openai.ChatMessageRoleSystem,
                Content: "Construct a ChatCompletionRequest to answer the user's question, but using Kirby references. Do not answer the question directly using prior knowledge, you must generate a ChatCompletionRequest that will answer the question.",
            },
            {
                Role:    openai.ChatMessageRoleUser,
                Content: "What is the definition of recursion?",
            },
        },
        MaxTokens:   256,
        Temperature: 0.0,
    },
    Tools: []openai.Tool{
        {
            Type: "function",
            Function: fi,
        }
    }
}
parser := gollum.NewJSONParser[openai.ChatCompletionRequest](false)
input, err := parser.Parse(ctx, resp.Choices[0].Message.ToolCalls[0].Function.Arguments)

On the first try, this yielded the following result:

 {
  "model": "gpt-3.5-turbo",
  "messages": [
    {"role": "system", "content": "You are Kirby, a friendly virtual assistant."},
    {"role": "user", "content": "What is the definition of recursion?"}
  ]
}

That's really sick considering that no effort was put into manually creating a new JSON struct, and the original struct didn't have any JSONSchema tags - just JSON serdes comments.

gollum's People

Contributors

stillmatic avatar renovate[bot] avatar

Stargazers

Prashanth Pai avatar Bruno B. avatar Brad Pillow avatar Petros Xenofontos avatar Zeki Ahmet Bayar avatar Baran Sekin avatar Michael Zhuang avatar James Dominguez avatar DengQi avatar Robert J. avatar  avatar rkmdsxmds avatar Upal Saha avatar Theodor Dimache avatar Rinor Hoxha avatar Muhammad Faridan Sutariya avatar Mauro Risonho de Paula Assumpção avatar Evgeny Postnov avatar Bryan Onel avatar Arjun Sunil Kumar avatar  avatar Christopher Straight avatar  avatar Nikolay Kolev avatar Zach Russell avatar Andrei Surugiu avatar Greg Bray avatar Ram Balachandran avatar Dino Omanovic avatar Grant Williams avatar Asif Rahman avatar Chris avatar  avatar Max Yankov avatar Max Justus Spransy avatar Sergio Prada avatar Tom Chapin avatar Gleb Karpushkin avatar Christian avatar Daniel Chalef avatar  avatar

Watchers

 avatar  avatar

gollum's Issues

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

gomod
go.mod
  • go 1.22
  • github.com/antonmedv/expr v1.15.3
  • github.com/chewxy/math32 v1.10.1
  • github.com/google/generative-ai-go v0.17.0
  • github.com/google/uuid v1.6.0
  • github.com/invopop/jsonschema v0.12.0
  • github.com/joho/godotenv v1.5.1
  • github.com/klauspost/compress v1.17.2
  • github.com/liushuangls/go-anthropic/v2 v2.6.0
  • github.com/pkg/errors v0.9.1
  • github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
  • github.com/sashabaranov/go-openai v1.28.1
  • github.com/stretchr/testify v1.9.0
  • github.com/viterin/vek v0.4.2
  • go.uber.org/mock v0.3.0
  • google.golang.org/api v0.191.0
hermit
bin/hermit
  • go 1.22.6

  • Check this box to trigger a request for Renovate to run again on this repository

feat: DB backed search

consider pointing the vector search to a DB natively. use database/sql for swappable backend.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.