For Nosia Users: This guide explains how to create and use Agent Skills in Nosia.
Agent Skills extend Nosia's chat capabilities by allowing you to define custom behaviors that can be triggered during conversations. Skills can be:
- LLM-driven: Simple prompt-based behaviors using the LLM
- Ruby-based: Complex logic implemented as Ruby classes
-
Upload your SKILL.md file via the web UI:
- Navigate to Agent Skills in the web interface
- Click "Upload Skill"
- Upload your SKILL.md file and any additional files
-
Define your skill metadata in the SKILL.md YAML frontmatter:
---
name: my-skill
description: A brief description of what this skill does
execution_mode: llm # or: ruby
trigger_mode: explicit # or: auto, combined
requires_rag_context: true # Set to true if skill needs document/chunk access
# Optional fields:
tags:
- tag1
- tag2
when_to_use: Use this skill when the user asks about specific topics
---
## Instructions
These are the instructions that will be shown to the LLM when this skill is triggered.
Be specific and clear about what the skill should do.Once uploaded and enabled, skills can be triggered in several ways:
- Explicit command:
/skill-name your query - Mention syntax:
@skill-name your query - Auto-detection: (when configured) The system will automatically detect when to use the skill
For advanced use cases, create a Ruby class in app/models/agent_skills/:
module AgentSkills
class MyCustomSkill < Base
def call
# Your custom logic here
# Access chat via: chat
# Access user query via: query
# Access RAG context via: rag_context (if enabled)
# Example: Use the chat's LLM
response = ask("Please answer: #{query}")
# Return a hash with :content and :role
{ content: response, role: "assistant" }
end
end
endRuby skills have access to the following methods:
chat- The current Chat instancequery- The user's query that triggered the skilluser- The current Useraccount- The current Accountagent_skill- This AgentSkill instanceexecution- The current AgentSkillExecution for audit purposesrag_context- RAG context ifrequires_rag_contextis trueask(prompt, **options)- Ask the LLM a questionwith_instructions(instructions, **options, &block)- Set instructions for LLMlog(message, level: :info)- Log a message
For security, only the following Chat methods are available:
askwith_instructionswith_paramswith_temperaturewith_modelsimilarity_searchmessagesuseraccount
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| name | string | Yes | - | Skill identifier (alphanumeric, underscore, hyphen only, must start with letter) |
| description | string | Yes | - | Human-readable description |
| execution_mode | string | No | llm | Either "llm" or "ruby" |
| trigger_mode | string | No | explicit | Either "explicit", "auto", or "combined" |
| requires_rag_context | boolean | No | false | Whether skill needs access to documents/chunks |
| tags | array | No | - | Tags for categorization |
| when_to_use | string | No | - | Instructions for when to use this skill (shown to LLM in auto mode) |
- ** prompts only**: Always sanitize any user input before including it in prompts
- Limited chat access: Ruby skills can only call whitelisted Chat methods
- No arbitrary code: Ruby skills cannot execute arbitrary system commands
- File uploads: Only certain file types are allowed (.md, .markdown, .txt, .yaml, .yml, .json)
- Timeout: Ruby skills have a configurable timeout (default: 30 seconds)
Agent Skills can be configured via environment variables:
| Variable | Default | Description |
|---|---|---|
| AGENT_SKILLS_ENABLED | true | Enable/disable Agent Skills feature |
| AGENT_SKILLS_MAX_FILE_SIZE | 1048576 (1MB) | Maximum file size per upload |
| AGENT_SKILLS_TIMEOUT | 30 | Timeout for Ruby skill execution in seconds |
| GUARD_MODEL | - | Model to use for auto-detection (when DETECTOR is enabled) |
Test your skill by:
- Upload it via the web UI
- Enable it
- In a chat, trigger it using
/skill-nameor@skill-name - Check the chat response
For Ruby skills, ensure:
- The class name matches the pattern:
AgentSkills::{NameCamelized} - The class inherits from
AgentSkills::Base - The class implements a
callmethod - All required context keys are present (chat, query, agent_skill)
---
name: summarizer
description: Summarizes documents and text
execution_mode: llm
trigger_mode: explicit
requires_rag_context: true
---
## Instructions
You are a document summarization assistant. When triggered, you will receive document content and should provide a concise summary.
Focus on:
- Main points
- Key data and metrics
- Important names, dates, and conclusions
- Overall structure
Use markdown formatting for readability. Always cite your source material.Use with: /summarizer What's in my documents about AI? or @summarizer this text...
module AgentSkills
class DocumentSummarizer < Base
def call
chunks = rag_context[:chunks]
if chunks.empty?
return { content: "No documents found matching your query.", role: "assistant" }
end
by_source = chunks.group_by { |c| c[:source] }
summaries = by_source.map do |source, source_chunks|
content = source_chunks.map { |c| c[:content] }.join("\n\n")[0...4000]
with_instructions(summarization_prompt(source)) do
ask("Please summarize the following content from source '#{source}':\n\n#{content}")
end.content
end
{ content: format_response(summaries, by_source.keys), role: "assistant" }
end
private
def summarization_prompt(source)
<<~PROMPT
You are a document summarization assistant. Create a concise summary.
Focus on: main points, key data, important names, dates, conclusions.
Use markdown formatting. Source: #{source}
Respond only with the summary.
PROMPT
end
def format_response(summaries, sources)
"## Document Summary\n\n#{summaries.join("\n\n---\n\n")}\n\n---\n\n**Sources:** #{sources.join(", ")}"
end
end
end- Skill not triggering: Check that the skill is enabled and the name matches your trigger
- Ruby skill not found: Ensure the class name matches
AgentSkills::{CamelizedName} - Missing context: Ruby skills must implement the required interface
- Timeout errors: Ruby skills must complete within the configured timeout
- Validation errors: Check the SKILL.md YAML frontmatter for required fields
- Start simple: Begin with LLM-based skills before implementing Ruby skills
- Test locally: Test your skill thoroughly before uploading
- Use clear names: Skill names should be descriptive and unique
- Set appropriate execution mode: Use LLM for simple behaviors, Ruby for complex logic
- Enable RAG when needed: Only enable
requires_rag_contextif your skill needs document access - Handle errors gracefully: Ruby skills should include error handling
- Log appropriately: Use the
logmethod for debugging - Document your skills: Include clear descriptions and usage instructions
| Method | Endpoint | Description |
|---|---|---|
| GET | /agent_skills |
List all skills for the account |
| GET | /agent_skills/new |
Show upload form |
| POST | /agent_skills |
Upload a new skill |
| GET | /agent_skills/:id |
Show skill details |
| GET | /agent_skills/:id/edit |
Show edit form |
| PATCH/PUT | /agent_skills/:id |
Update a skill |
| DELETE | /agent_skills/:id |
Delete a skill |
| PATCH | /agent_skills/:id/toggle |
Toggle skill enabled/disabled |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/agent_skills |
List all skills (JSON) |
| POST | /api/v1/agent_skills |
Create a skill (JSON) |
| GET | /api/v1/agent_skills/:id |
Show skill (JSON) |
| PATCH/PUT | /api/v1/agent_skills/:id |
Update skill (JSON) |
| DELETE | /api/v1/agent_skills/:id |
Delete skill (JSON) |
All API endpoints are authenticated and scoped to the current account.
If you have existing skills from other platforms (like CrewAI, AutoGen, or LangChain), you can migrate them to Nosia:
- Convert your skill to the SKILL.md format
- Extract any custom logic into Ruby classes under
app/models/agent_skills/ - Ensure your skill follows the naming conventions
- Upload via the web UI or API
Improvements to the Agent Skills system are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for your changes
- Submit a pull request
MIT License - see the LICENSE file for details.