--- license: gemma base_model: google/gemma-3-4b-it language: - en library_name: mlx pipeline_tag: text-generation tags: - gemma - gemma3 - lora - mlx - agentic - tool-calling - function-calling - distillation --- # Copal 1 Mini **Copal 1 Mini** is an agentic, tool-calling fine-tune of **Gemma 3 4B IT** — trained to decide when to call a tool, select the right one, interpret its result, and either continue acting or respond, using a lightweight text-based `` / `` convention. It is the first model in the Copal series, focused on tool-use judgment rather than general chat. ## Model Details | | | |---|---| | **Developed by** | Independent research project | | **Base model** | [google/gemma-3-4b-it](https://huggingface.co/google/gemma-3-4b-it) | | **Fine-tuning base checkpoint** | [mlx-community/gemma-3-4b-it-qat-4bit](https://huggingface.co/mlx-community/gemma-3-4b-it-qat-4bit) | | **Architecture** | Gemma 3, 4B parameters (dense, decoder-only transformer) | | **Fine-tuning method** | LoRA (rank 8, scale 20.0), fused into the base weights | | **Fine-tuning framework** | [MLX](https://github.com/ml-explore/mlx) / `mlx-lm`, on Apple Silicon | | **Trained modules** | `q_proj`, `k_proj`, `v_proj`, `o_proj`, `gate_proj`, `up_proj`, `down_proj` across 16 layers | | **Weights** | Released 4-bit quantized (same quantization as the QAT base checkpoint), fused with the adapter — not dequantized | | **Language** | English | | **License** | [Gemma Terms of Use](https://ai.google.dev/gemma/terms) | ## Tool-Calling Format Copal 1 Mini was trained on a simple, model-native text convention rather than a JSON-schema function-calling API. The assistant emits: ``` {"name": "tool_name", "arguments": {"key": "value"}} ``` and the caller returns: ``` {...result...} ``` as the next user turn. This loop repeats until the model responds with plain text instead of a `` block. See **Usage** below for a full example. ## Training Data Copal 1 Mini was fine-tuned on **930 cleaned agentic trajectories** (of 1,152 originally generated, with malformed/incomplete ones filtered out), distilled from **`z-ai/glm-5.2`** via the NVIDIA NIM API. Each trajectory is a full multi-turn tool-use episode: a task prompt, the model's tool call(s), simulated tool results, and either further calls or a final response. Tasks span 10 agentic categories, generated programmatically across many entities (companies, endpoints, databases, file paths, etc.) to avoid template overfitting: - API orchestration - State tracking - Tool selection - Multi-step planning - Clarification (recognizing under-specified requests) - Error recovery - Read-and-decide (branching on tool output) - Concise execution - Browser workflow - Structured output ## Training Procedure - **Method:** Supervised fine-tuning via LoRA (rank 8, dropout 0.0, scale 20.0) - **Optimizer:** Adam, learning rate 1e-5 (constant schedule) - **Sequence length:** 4096 tokens (agentic trajectories run long — multiple tool round-trips per example) - **Gradient checkpointing:** enabled - **Training steps:** 2,500 iterations, with validation every 50 steps - **Checkpoint selection:** the released weights use the **iteration 2,250 checkpoint**, selected for lowest validation loss (0.236); validation loss plateaued with noise from ~iteration 1,000 onward rather than continuing to improve, so later checkpoints offered no reliable benefit on this dataset size ## Evaluation Evaluated against the un-tuned base model on 12 held-out agentic tasks (not seen during training), using the same simulated tool environment and RNG seed for both arms so they see identical tool results: | | Used tools when appropriate | Tool-call parse errors | |---|---|---| | Base (Gemma 3 4B IT) | 8 / 12 | 0 | | **Copal 1 Mini** | **11 / 12** | 0 | Copal invokes tools in more of the situations that call for them, with no degradation in output-format reliability. ## Intended Use Copal 1 Mini is intended for experimentation with lightweight, locally-run agentic/tool-calling assistants — task automation, API orchestration, and agent-loop research on consumer hardware. It is **not** intended for high-stakes, safety-critical, or production use, and it does not use a JSON-schema/OpenAI-style function-calling interface — integrate it via the ``/`` convention above, or adapt your tool-calling harness to it. ## Limitations - Trained on a small (930-example), synthetically generated dataset — behavior can be inconsistent outside the categories represented in training. - Distilled from a single teacher model without human review of every trajectory; teacher biases or occasional tool-use mistakes may be present. - Uses a custom tool-call text format, not a standardized function-calling schema — not a drop-in replacement for APIs expecting OpenAI-style tool calls. - Inherits the general limitations and knowledge cutoff of its base model, Gemma 3 4B IT. - This is an early, first-generation checkpoint in an ongoing series. ## Usage ```python from mlx_lm import load, generate from mlx_lm.sample_utils import make_sampler model, tokenizer = load("VertexAIco/copal-1-mini") system_prompt = """You are Copal, an agentic assistant with access to tools. When you need a tool, respond with exactly: {"name": "...", "arguments": {...}} Otherwise, respond normally in plain text.""" messages = [ {"role": "system", "content": system_prompt}, {"role": "user", "content": "Check the status of https://api.example.com/health and tell me if it's up."}, ] prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True) text = generate(model, tokenizer, prompt=prompt, max_tokens=300, sampler=make_sampler(temp=0.0)) print(text) # -> {"name": "http_request", "arguments": {"method": "GET", "url": "https://api.example.com/health"}} # Execute the tool yourself, then feed the result back as the next user turn: messages.append({"role": "assistant", "content": text}) messages.append({"role": "user", "content": '\n{"status": 200, "ok": true}\n'}) prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True) text = generate(model, tokenizer, prompt=prompt, max_tokens=300, sampler=make_sampler(temp=0.0)) print(text) ``` ## Citation ``` @misc{copal1mini, title = {Copal 1 Mini}, author = {Independent research project}, year = {2026}, note = {LoRA fine-tune of Gemma 3 4B IT for agentic tool-calling, distilled from GLM 5.2} } ``` This model is built on Gemma and subject to the [Gemma Terms of Use](https://ai.google.dev/gemma/terms).