{"id":39079769,"url":"https://github.com/natexcvi/go-llm","last_synced_at":"2026-01-17T18:29:22.323Z","repository":{"id":165533269,"uuid":"624383095","full_name":"natexcvi/go-llm","owner":"natexcvi","description":"A framework for building LLM based agents and integrating them into larger applications.","archived":false,"fork":false,"pushed_at":"2024-12-08T19:31:05.000Z","size":491,"stargazers_count":85,"open_issues_count":6,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-08T20:28:02.067Z","etag":null,"topics":["agent","agi","go","gpt","llm"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/natexcvi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-06T10:50:08.000Z","updated_at":"2024-12-08T19:31:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"e9f59c47-7c36-490f-b665-13a8ff5c165a","html_url":"https://github.com/natexcvi/go-llm","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/natexcvi/go-llm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natexcvi%2Fgo-llm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natexcvi%2Fgo-llm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natexcvi%2Fgo-llm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natexcvi%2Fgo-llm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/natexcvi","download_url":"https://codeload.github.com/natexcvi/go-llm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/natexcvi%2Fgo-llm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28515650,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T18:28:00.501Z","status":"ssl_error","status_checked_at":"2026-01-17T18:28:00.150Z","response_time":85,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","agi","go","gpt","llm"],"created_at":"2026-01-17T18:29:22.243Z","updated_at":"2026-01-17T18:29:22.310Z","avatar_url":"https://github.com/natexcvi.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go LLM\n[![Go](https://github.com/natexcvi/go-llm/actions/workflows/go.yml/badge.svg)](https://github.com/natexcvi/go-llm/actions/workflows/go.yml)\n\nIntegrate the power of large language models (LLM) into your Go application.\n\nThis project aims to abstract away much of the plumbing (free text to structured data, contextual memory, tool wrapping, retry logic, etc.) so you can focus on the business logic of your agent.\n\n```mermaid\ngraph LR\n    subgraph Input\n    A[Structured Input] --\u003e B[Compiled Task]\n    end\n    subgraph LLM-Based Agent\n    C[Task Template] --\u003e B[Compiled Task]\n    B --\u003e D((Agent))\n    D --\"Reasoning\"--\u003e D\n    D --\"Action\"--\u003e E[Environment]\n    E --\"Observation\"--\u003e D\n    D --\"Answer\"--\u003e G[Output Validators]\n    G --\u003e D\n    end\n    subgraph Output\n    G --\"Answer\"--\u003e F[Structured Output]\n    end\n```\n\n## Usage Example\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/natexcvi/go-llm/agents\"\n\t\"github.com/natexcvi/go-llm/engines\"\n\t\"github.com/natexcvi/go-llm/memory\"\n\t\"github.com/natexcvi/go-llm/tools\"\n)\n\ntype CodeBaseRefactorRequest struct {\n\tDir  string\n\tGoal string\n}\n\nfunc (req CodeBaseRefactorRequest) Encode() string {\n\treturn fmt.Sprintf(`{\"dir\": \"%s\", \"goal\": \"%s\"}`, req.Dir, req.Goal)\n}\n\nfunc (req CodeBaseRefactorRequest) Schema() string {\n\treturn `{\"dir\": \"path to code base\", \"goal\": \"refactoring goal\"}`\n}\n\ntype CodeBaseRefactorResponse struct {\n\tRefactoredFiles map[string]string `json:\"refactored_files\"`\n}\n\nfunc (resp CodeBaseRefactorResponse) Encode() string {\n\tmarshalled, err := json.Marshal(resp.RefactoredFiles)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn string(marshalled)\n}\n\nfunc (resp CodeBaseRefactorResponse) Schema() string {\n\treturn `{\"refactored_files\": {\"path\": \"description of changes\"}}`\n}\n\nfunc main() {\n\ttask := \u0026agents.Task[CodeBaseRefactorRequest, CodeBaseRefactorResponse]{\n\t\tDescription: \"You will be given access to a code base, and instructions for refactoring.\" +\n\t\t\t\"your task is to refactor the code base to meet the given goal.\",\n\t\tExamples: []agents.Example[CodeBaseRefactorRequest, CodeBaseRefactorResponse]{\n\t\t\t{\n\t\t\t\tInput: CodeBaseRefactorRequest{\n\t\t\t\t\tDir:  \"/Users/nate/code/base\",\n\t\t\t\t\tGoal: \"Handle errors gracefully\",\n\t\t\t\t},\n\t\t\t\tAnswer: CodeBaseRefactorResponse{\n\t\t\t\t\tRefactoredFiles: map[string]string{\n\t\t\t\t\t\t\"/Users/nate/code/base/main.py\": \"added try/except block\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tIntermediarySteps: []*engines.ChatMessage{\n\t\t\t\t\t(\u0026agents.ChainAgentThought{\n\t\t\t\t\t\tContent: \"I should scan the code base for functions that might error.\",\n\t\t\t\t\t}).Encode(engine),\n\t\t\t\t\t(\u0026agents.ChainAgentAction{\n\t\t\t\t\t\tTool: tools.NewBashTerminal(),\n\t\t\t\t\t\tArgs: json.RawMessage(`{\"command\": \"ls /Users/nate/code/base\"}`),\n\t\t\t\t\t}).Encode(engine),\n\t\t\t\t\t(\u0026agents.ChainAgentObservation{\n\t\t\t\t\t\tContent:  \"main.py\",\n\t\t\t\t\t\tToolName: tools.NewBashTerminal().Name(),\n\t\t\t\t\t}).Encode(engine),\n\t\t\t\t\t(\u0026agents.ChainAgentThought{\n\t\t\t\t\t\tContent: \"Now I should read the code file.\",\n\t\t\t\t\t}).Encode(engine),\n\t\t\t\t\t(\u0026agents.ChainAgentAction{\n\t\t\t\t\t\tTool: tools.NewBashTerminal(),\n\t\t\t\t\t\tArgs: json.RawMessage(`{\"command\": \"cat /Users/nate/code/base/main.py\"}`),\n\t\t\t\t\t}).Encode(engine),\n\t\t\t\t\t(\u0026agents.ChainAgentObservation{\n\t\t\t\t\t\tContent:  \"def main():\\n\\tfunc_that_might_error()\",\n\t\t\t\t\t\tToolName: tools.NewBashTerminal().Name(),\n\t\t\t\t\t}).Encode(engine),\n\t\t\t\t\t(\u0026agents.ChainAgentThought{\n\t\t\t\t\t\tContent: \"I should refactor the code to handle errors gracefully.\",\n\t\t\t\t\t}).Encode(engine),\n\t\t\t\t\t(\u0026agents.ChainAgentAction{\n\t\t\t\t\t\tTool: tools.NewBashTerminal(),\n\t\t\t\t\t\tArgs: json.RawMessage(`{\"command\": \"echo 'def main():\\n\\ttry:\\n\\t\\tfunc_that_might_error()\\n\\texcept Exception as e:\\n\\t\\tprint(\\\"Error: %s\\\", e)' \u003e /Users/nate/code/base/main.py\"}`),\n\t\t\t\t\t}).Encode(engine),\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tAnswerParser: func(msg string) (CodeBaseRefactorResponse, error) {\n\t\t\tvar res CodeBaseRefactorResponse\n\t\t\tif err := json.Unmarshal([]byte(msg), \u0026res); err != nil {\n\t\t\t\treturn CodeBaseRefactorResponse{}, err\n\t\t\t}\n\t\t\treturn res, nil\n\t\t},\n\t}\n\tagent := agents.NewChainAgent(engines.NewGPTEngine(os.Getenv(\"OPENAI_TOKEN\"), \"gpt-3.5-turbo-0613\"), task, memory.NewBufferedMemory(0)).WithMaxSolutionAttempts(12).WithTools(tools.NewPythonREPL(), tools.NewBashTerminal())\n\tres, err := agent.Run(CodeBaseRefactorRequest{\n\t\tDir:  \"/Users/nate/Git/go-llm/tools\",\n\t\tGoal: \"Write unit tests for the bash.go file, following the example of python_repl_test.go.\",\n\t})\n\t...\n}\n```\n\u003e **Note**\n\u003e \n\u003e Fun fact: the `tools/bash_test.go` file was written by this very agent, and helped find a bug!\n\n## Components\n### Engines\nConnectors to LLM engines. Currently only OpenAI's GPT chat completion API is supported.\n### Tools\nTools that can provide agents with the ability to perform actions interacting with the outside world.\nCurrently available tools are:\n- `PythonREPL` - a tool that allows agents to execute Python code in a REPL.\n- `IsolatedPythonREPL` - a tool that allows agents to execute Python code in a REPL, but in a Docker container.\n- `BashTerminal` - a tool that allows agents to execute bash commands in a terminal.\n- `GoogleSearch` - a tool that allows agents to search Google.\n- `WebpageSummary` - an LLM-based tool that allows agents to get a summary of a webpage.\n- `WolframAlpha` - a tool that allows agents to query WolframAlpha's short answer API.\n- `KeyValueStore` - a tool for storing and retrieving information. The agent can use this tool to re-use long pieces of information by-reference, removing duplication and therefore reducing context size.\n- `AskUser` - an interactivity tool that lets the agent ask a human operator for clarifications when needed.\n- `JSONAutoFixer` - a meta tool that is enabled by default. When the arguments to any tool are provided in a form that is not valid JSON, this tool attempts to fix the payload using a separate LLM chain.\n- `GenericAgentTool` - lets an agent run another agent, with pre-determined tools, dynamically providing it with its task and input and collecting its final answer.\n\n\u003e **Warning**\n\u003e \n\u003e The `BashTerminal` and regular `PythonREPL` tools let the agent run arbitrary commands on your machine, use at your own risk. It may be a good idea to use the built-in support for action confirmation callbacks (see the `WithActionConfirmation` method on the `ChainAgent` type).\n\n#### Model-Native Function Calls\n`go-llm` tools support the [new OpenAI function call interface](https://openai.com/blog/function-calling-and-other-api-updates?ref=upstract.com) transparently, for model variants that have this feature.\n\n### Memory\nA memory system that allows agents to store and retrieve information.\nCurrently available memory systems are:\n- `BufferMemory` - which provides each step of the agent with a fixed buffer of recent messages from the conversation history.\n- `SummarisedMemory` - which provides each step of the agent with a summary of the conversation history, powered by an LLM.\n\n### Agents\nAgents are the main component of the library. Agents can perform complex tasks that involve iterative interactions with the outside world.\n\n### Prebuilt (WIP)\nA collection of ready-made agents that can be easily integrated with your application.\n\n### Evaluation (WIP)\nA collection of evaluation tools for agents and engines.\n## Example\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/natexcvi/go-llm/engines\"\n\t\"github.com/natexcvi/go-llm/evaluation\"\n)\n\nfunc goodness(_ *engines.ChatPrompt, _ *engines.ChatMessage, err error) float64 {\n\tif err != nil {\n\t\treturn 0\n\t}\n\n\treturn 1\n}\n\nfunc main() {\n\tengine := engines.NewGPTEngine(os.Getenv(\"OPENAI_TOKEN\"), \"gpt-3.5-turbo-0613\")\n\tengineRunner := evaluation.NewLLMRunner(engine)\n\n\tevaluator := evaluation.NewEvaluator(engineRunner, \u0026evaluation.Options[*engines.ChatPrompt, *engines.ChatMessage]{\n\t\tGoodnessFunction: goodness,\n\t\tRepetitions:      5,\n\t})\n\n\ttestPack := []*engines.ChatPrompt{\n\t\t{\n\t\t\tHistory: []*engines.ChatMessage{\n\t\t\t\t{\n\t\t\t\t\tText: \"Hello, how are you?\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tText: \"I'm trying to understand how this works.\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tHistory: []*engines.ChatMessage{\n\t\t\t\t{\n\t\t\t\t\tText: \"Could you please explain it to me?\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tresults := evaluator.Evaluate(testPack)\n\tfmt.Println(\"Goodness level of the first prompt:\", results[0])\n\tfmt.Println(\"Goodness level of the second prompt:\", results[1])\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnatexcvi%2Fgo-llm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnatexcvi%2Fgo-llm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnatexcvi%2Fgo-llm/lists"}