LLM Functions

repository·main·Indexed 20 days ago

https://github.com/sigoden/llm-functions

A framework for building LLM tools and agents using Bash, JavaScript, and Python. It leverages function calling to connect LLMs to custom code and system commands, integrating with AIChat and the Model Context Protocol (MCP). It includes mcp-bridge for using external MCP tools and mcp-llm-functions for exposing local tools and agents via MCP. Management is handled through the argc CLI for building, testing, and linking tools.

Tokens
8.6K
Snippets
27
Records
31
Agent score
73%

What's inside llm-functions

  1. How agents are structured and defined

    main

    An Agent is a combination of a Prompt, Tools (Function Calling), and Documents (RAG). Each agent resides in its own directory within the agents/ folder and follows this structure:

    └── agents
        └── myagent
            ├── functions.json                  # JSON declarations (Auto-generated)
            ├── index.yaml                      # Agent definition
            ├── tools.txt                       # Shared tools
            └── tools.{sh,js,py}                # Agent-specific tools

    The index.yaml file defines the agent's behavior. Key fields include:

    • name: The agent's name.
    • description: A description of the agent.
    • version: The version string.
    • instructions: The system prompt/instructions for the LLM.
    • conversation_starters: A list of suggested user prompts.
    • variables: Custom variables available to the agent.
    • documents: A list of local files, directories, or remote URLs for RAG.
    name: TestAgent                             
    description: This is test agent
    version: 0.1.0
    instructions: You are a test ai agent to ... 
    conversation_starters:
      - What can you do?
    variables:
      - name: foo
        description: This is a foo
    documents:
      - local-file.txt
      - local-dir/
      - https://example.com/remote-file.txt
  2. MCP (Model Context Protocol) support

    main

    LLM Functions provides two MCP-related capabilities:

    • mcp/server: Allows LLM-Functions tools and agents to be used via the Model Context Protocol.
    • mcp/bridge: Allows external MCP tools to be used by LLM-Functions.
  3. Expose LLM-functions tools via MCP

    main

    You can expose the tools and agents from the llm-functions repository through the Model Context Protocol (MCP) by configuring an MCP client (like Claude Desktop) to run the mcp-llm-functions package. This allows LLMs to access the functions defined in your local llm-functions directory.

    {
      "mcpServers": {
        "tools": {
          "command": "npx",
          "args": [
            "mcp-llm-functions",
            "<llm-functions-dir>"
          ]
        }
      }
    }
  4. Generate tools using aichat

    main

    You can use aichat to automatically generate tool or agent scripts by providing a natural language description of the requirements.

    To create a common tool script: Pass the documentation and a description of the tool to aichat using the -f flag.

    To create an agent tools script: Provide both the agent documentation and the tool documentation to aichat to define a complex agent with multiple functions and an index.yaml configuration.

    aichat -f docs/tool.md <<-'EOF'
    create tools/get_youtube_transcript.py
    
    description: Extract transcripts from YouTube videos
    parameters:
       url (required): YouTube video URL or video ID
       lang (default: "en"): Language code for transcript (e.g., "ko", "en")
    EOF
  5. Link tools and agents to AIChat

    main

    Use the link commands to integrate specific scripts or connect the entire repository to your AIChat configuration.

    • Link specific capabilities:
      • argc link-web-search <script_path>
      • argc link-code-interpreter <script_path>
    • Link entire repository: argc link-to-aichat (links this repo to the aichat functions_dir).
    argc link-web-search web_search_tavily.sh 
    argc link-code-interpreter execute_py_code.py 
    argc link-to-aichat
  6. How to write custom JavaScript tools

    main

    Create a JavaScript file in the ./tools/ directory. Use JSDoc-style comments to define the tool's interface. The run function is the entry point.

    Example execute_js_code.js:

    /**
     * Execute the javascript code in node.js.
     * @typedef {Object} Args
     * @property {string} code - Javascript code to execute, such as `console.log("hello world")`
     * @param {Args} args
     */
    exports.run = function ({ code }) {
      eval(code);
    }
  7. Configure MCP-Bridge via mcp.json

    main

    To allow external Model Context Protocol (MCP) tools to be used by LLM-Functions, create a mcp.json file in your <llm-functions-dir>. This file defines the MCP servers that the bridge will launch and register.

    Each server entry in mcpServers can include:

    • command: The executable to run.
    • args: An array of arguments for the command.
    • env: An object containing environment variables required by the server.
    • prefix: A boolean (defaulting to true) that determines if tool names should be automatically prefixed with the server name (e.g., sqlite_query). Set this to false to use the raw tool names and avoid clashes manually.
    {
      "mcpServers": {
        "sqlite": {
          "command": "uvx",
          "args": [
            "mcp-server-sqlite",
            "--db-path",
            "/tmp/foo.db"
          ]
        },
        "git": {
          "command": "uvx",
          "args": [
            "mcp-server-git",
            "--repository",
            "path/to/git/repo"
          ],
          "prefix": false
        },
        "github": {
          "command": "npx",
          "args": [
            "-y",
            "@modelcontextprotocol/server-github"
          ],
          "env": {
            "GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
          }
        }
      }
    }
  8. Manage LLM functions and agents with Argcfile.sh

    main

    The Argcfile.sh script is a management tool for LLM functions and agents in an AIChat environment, functioning similarly to how a Makefile works with make. It is recommended to run this script using the argc command, which provides better autocompletion and cross-platform compatibility (including Windows).

    argc <command>
  9. Expose a specific LLM-function agent via MCP

    main

    To serve a specific agent instead of the general toolset, configure your MCP client to pass the <agent-name> as an argument to mcp-llm-functions. Replace <llm-functions-dir> with the absolute path to your llm-functions repository and <agent-name> with the name of the agent you wish to expose.

    {
      "mcpServers": {
        "<agent-name>": {
          "command": "node",
          "args": [
            "mcp-llm-functions",
            "<llm-functions-dir>",
            "<agent-name>"
          ]
        }
      }
    }
  10. Quickly create tool scripts with argc

    main

    The Argcfile.sh script includes a create@tool command to scaffold tool scripts (.sh, .js, or .py) with parameter definitions automatically generated based on suffixes.

    Command Syntax: argc create@tool <filename> <parameters>

    Parameter Suffixes:

    • !: Required property.
    • *: Array property.
    • +: Required array property.
    • (No suffix): Optional property.
    argc create@tool _test.sh foo bar! baz+ qux*
  11. Define tool parameters in JavaScript

    main

    In JavaScript, use JSDoc-style comments to define the tool's parameters. The @typedef block defines an Args object where each @property represents a parameter.

    • /** ... */: The comment block containing the tool description and parameter definitions.
    • @typedef {Object} Args: Defines the type of the argument object.
    • @property {<type>} <name> <description>: Defines a parameter.
      • <type>: Data type (e.g., string, boolean, number, string[], or {foo|bar} for enums).
      • <name>: The parameter name.
      • <description>: Description of the parameter.
      • []: Append brackets to the name (e.g., [name]) to indicate an optional parameter.

    You can export the tool using exports.run = function (args) { ... } or via ESM export function run() { ... }.

    /**
     * Demonstrate how to create a tool using Javascript and how to use comments.
     * @typedef {Object} Args
     * @property {string} string - Define a required string property
     * @property {'foo'|'bar'} string_enum - Define a required string property with enum
     * @property {string} [string_optional] - Define a optional string property
     * @property {boolean} boolean - Define a required boolean property
     * @property {Integer} integer - Define a required integer property
     * @property {number} number - Define a required number property
     * @property {string[]} array - Define a required string array property
     * @property {string[]} [array_optional] - Define a optional string array property
     * @param {Args} args
     */
    exports.run = function (args) {
      // ... your JavaScript code ...
    }
  12. Define tool parameters in Python

    main

    In Python, use standard type hints in the function signature and provide parameter descriptions in the function's docstring.

    • Type Hints: Use standard types like str, bool, int, float, List[str], or Literal["foo", "bar"] for enums.
    • Optional Parameters: Use Optional[...] from the typing module.
    • Docstrings: Use the Args: section in the docstring to provide descriptions for each parameter.

    Example structure:

    def run(param: type, optional_param: Optional[type] = None):
        """
        Description.
        Args:
            param: Description of param
        """
    def run(
        string: str,
        string_enum: Literal["foo", "bar"],
        boolean: bool,
        integer: int,
        number: float,
        array: List[str],
        string_optional: Optional[str] = None,
        array_optional: Optional[List[str]] = None,
    ):
        """Demonstrate how to create a tool using Python and how to use comments.
        Args:
            string: Define a required string property
            string_enum: Define a required string property with enum
            boolean: Define a required boolean property
            integer: Define a required integer property
            number: Define a required number property
            array: Define a required string array property
            string_optional: Define a optional string property
            array_optional: Define a optional string array property
        """
        # ... your Python code ...