π§© Integrating Local LLMs into ShinkaEvolve¶
π§ Overview¶
The original ShinkaEvolve code does not include built-in support for running local LLMs. To enable this functionality, parts of the codebase can be modified to integrate locally hosted models.
ποΈ Code Organization¶
ShinkaEvolve uses a modular architecture that supports multiple LLM providers.
The relevant code for LLM interaction is located in the LLM/ folder, which manages all model communications.
ShinkaEvolve distinguishes between two LLM types:
- Regular LLMs
- Embedding LLMs
βοΈ Adding a Regular LLM¶
To add support for a regular LLM, follow these steps. They will show an example of adding support for gpt-oss models running with unsloth, which provides an API compatible with OpenAI API (v1/completions). This LLM can then be specified in the configuration variables:
π§ Step 1: Modify the Client¶
The file client.py is responsible for creating clients that interact with LLMs.
Each client instance is later used to query a specific model.
To add a local model, introduce a new client configuration. The API URL is extracted from the model name, which follows this format:
Example¶
elif "local-gptoss-unsloth" in model_name:
# Extract URL from model name
pattern = r"https?://"
match = re.search(pattern, model_name)
if match:
start_index = match.start()
url = model_name[start_index:]
else:
raise ValueError(f"Invalid URL in model name: {model_name}")
# Create OpenAI-compatible client
client = openai.OpenAI(
api_key="filler",
base_url=url
)
# Structured output mode (if required)
if structured_output:
client = instructor.from_openai(
client,
mode=instructor.Mode.JSON,
)
π Step 2: Create the Local Query Function¶
Inside the models/ folder, create a new subfolder to store the query functions for your local models:
Donβt forget to include an empty
__init__.pyfile.
This folder should contain a custom query function for the local model. I called my file local_gptoss_unsloth.py.
It should follow the same structure as other functions in LLM/models/, but with small adjustments.
My Key Adjustments¶
- Replace
max_output_tokenswithmax_tokensto match the local API. -
Extract additional response metadata such as:
-
total_tokens thinking_tokens(if your model includes reasoning traces)
This function is later imported and registered in query.py.
π§© Step 3: Update __init__.py¶
Configure __init__.py to include and expose the new local query function, so it can be imported elsewhere.
from .local.local_gptoss_unsloth import query_local_gptoss_unsloth # ADDED THIS LINE
from .result import QueryResult
__all__ = [
"query_anthropic",
"query_openai",
"query_deepseek",
"query_gemini",
"query_local_gptoss_unsloth", # ADDED THIS LINE
"QueryResult",
]
π¬ Step 4: Update query.py¶
Import and register the new local query function in query.py.
Imports¶
from .models import (
query_anthropic,
query_openai,
query_deepseek,
query_gemini,
query_local_gptoss_unsloth, # ADDED THIS LINE
QueryResult,
)
Model Selection Logic¶
π§ Step 5: Other Observations¶
The file query.py also defines functions such as:
sample_model_kwargssample_batch_kwargs
However, these are not referenced anywhere else in the repository, so no modifications are required here for now.
β Summary¶
| Step | File | Change | Description |
|---|---|---|---|
| 1 | client.py |
Add new client block | Create OpenAI-compatible client for local LLM |
| 2 | models/local/query_local_gptoss_unsloth.py |
New function | Query local model, adjust tokens, extract reasoning info |
| 3 | __init__.py |
Add import | Expose new query function |
| 4 | query.py |
Register model | Add conditional for local LLM |
| 5 | β | Review only | Ignored unused functions |
𧬠Adding a Local Embedding Model¶
For embedding models, you can use Ollama, which follows the OpenAI API format.
The only relevant file is embedding.py.
Code Addition¶
elif model_name.startswith("local-"):
# Pattern: local-(model-name)-(http or https url)
match = re.match(r"local-(.+?)-(https?://.+)", model_name)
if match:
model_to_use = match.group(1)
url = match.group(2)
else:
raise ValueError(f"Invalid local model format: {model_name}")
client = openai.OpenAI(
base_url=url,
api_key="filler"
)
Notes¶
- Compatible with any Ollama model.
- The model name must follow this convention:
model-name and url, and uses them to query Ollama.
Query Logic¶
The existing line in embedding.py remains unchanged:
For local embedding models, self.model corresponds to the extracted model name.
The only addition to the Embedding Client class:
π Result¶
ShinkaEvolve can now connect to locally hosted LLMs and embedding models through OpenAI-compatible APIs. This setup supports Ollama and other frameworks such as gpt-oss under Unsloth.
If your model has different requirements, follow the same pattern with a distinct model identifier and your own custom logic.