
What I learned building 15 custom skills for AI coding agents
Every developer on my team uses the same AI setup now. Not because I mandated it, but because I built skills so useful they spread by word of mouth. Here is what I learned from building a shared configuration that actually works.
The Fragmentation Problem
When we first rolled out Claude Code and Codex to the development team, everyone set up their own configuration. One developer used a custom prompt template he found on GitHub. Another relied on default settings. A third built his own workflows in a separate tool. The results were all over the place.
Some agents were helpful. Some were dangerous. Some were just weird - one colleague's agent kept trying to rewrite everything in Haskell because he had mentioned functional programming once in a Slack message.
I realized the problem was not the AI models. They were all capable. The problem was the configuration - the instructions, the tool definitions, the workflows that determined how the agent behaved. Without standardization, each agent setup operated with its own rule set. Some were amplifying productivity. Others were creating more work.
I decided to build a shared configuration - a set of skills and workflows that could be reused across PHP projects and developer setups. What followed was iteration, failure, learning, and eventually, adoption.
What a "Skill" Actually Is
In the AI agent world, a skill is a self-contained capability that the agent can invoke. It has an instruction set, input parameters, output expectations, and error handling. Think of it like a function in a programming language, but designed for natural language interaction.
A well-written skill does three things:
It defines scope. The skill knows exactly what it is supposed to do and what is out of bounds. A Jira integration skill does not try to also update Confluence. A code review skill does not rewrite entire files.
It documents assumptions. The skill's instruction set describes its expectations: "You will receive a Jira ticket key. You may assume the ticket exists and you have permission to read it." No vague expectations - clear contracts.
It handles failure. When the API fails, when the input is malformed, when the agent misunderstands - the skill has a recovery strategy. Retry. Escalate. Ask for clarification. Not just crash and return an error.
The Fifteen Skills (and Four Sub-Agents)
I built fifteen skills total, organized into four categories: integrations, workflows, quality, and tooling. Four sub-agents sit alongside them and handle the operations that need their own context window.
Integrations (5 skills)
Jira Integration. The cornerstone skill. It pulls ticket context - description, comments, attachments, linked issues - and understands the workflow. It knows what "in progress" means in our setup. It can create subtasks, add comments, transition tickets. Most importantly, it respects permissions and never exposes sensitive data in logs.
Bitbucket Integration. Pull requests, branch operations, commit conventions. The skill enforces our format: APP-427 fix: Short description. It creates PRs with the right reviewers, labels, and target branches. It knows when a PR is ready to merge (all checks pass, approved) and when it needs revision.
Gitea Integration. Same surface area as the Bitbucket skill but for repositories hosted on our internal Gitea instance. Useful for tooling and infrastructure code that lives separately from the main product.
Confluence Integration. Documentation lookup. When the agent needs context about architectural decisions, API contracts, or deployment procedures, it queries Confluence first. The skill is configured with the most relevant spaces and documents, so it does not waste time searching the entire knowledge base.
Outlook Integration. This one started as a joke - "can the AI schedule my meetings?" - but turned out to be one of the most-used skills. It checks calendar availability, suggests meeting times, creates invites with appropriate attendees, drafts agendas based on ticket context, and pulls inbox items into the work queue.
Workflows (4 skills)
Laravel Workflow. The most complex skill. It orchestrates the entire Laravel development pipeline: branch creation with Jira ticket key, worktree setup via the dev orchestrator, composer install, npm install, asset compilation, testing, and PR creation. It knows the convention: APP-427-ticket-description. It integrates with the parallel-manager agent so multiple workflows can run simultaneously without port conflicts.
Symfony Workflow. Similar to Laravel but with Symfony-specific tooling. Doctrine migrations instead of Laravel migrations. Twig templates instead of Blade. YAML configuration instead of .env. The skill abstracts these differences so developers using either framework get a consistent experience.
WordPress Workflow. Theme and plugin development - block hooks, custom post types, REST endpoints, WooCommerce customizations. The skill knows the WP-specific gotchas (escaping, capability checks, nonce validation) and never lets them slip past code review.
Client Vue 2 Workflow. The most specialized of the lot - a Vue 2 component pipeline for a client's landing-page system. Five responsive breakpoints, scoped SCSS, zip package delivery. The skill encodes the conventions the client expects so a new component lands close to spec on the first try.
Quality (2 skills)
PHP Testing. Before any code leaves the developer's machine, this skill runs PHPUnit or Pest, checks code coverage, validates PHPStan rules, and ensures no debug code made it to the PR. It can run focused tests on changed files or the full suite. It returns a detailed report that the workflow skill uses to determine if the PR is ready.
BaseService Pattern. One of our internal projects has a BaseService abstraction for CRUD, fluent query builders, relation hydration, filters, grid / table / page rendering, and CSV exports. Whenever an agent touches a service that extends it, this skill loads the right conventions so the agent does not invent a parallel pattern.
Tooling (4 skills)
Dev Orchestrator. A local CI/CD runner with a nine-stage pipeline from branch validation through Docker services to running servers. The workflow skills delegate environment management to it - one source of truth for how a project comes up locally.
Memory. Agents are stateless by default. This skill gives them continuity. It stores context across sessions: which tickets are being worked on, what decisions were made, what blockers were encountered. When an agent starts a new session, it loads the relevant context and picks up where it left off.
Assistant. A daily picture pulled from Jira, Confluence, and Outlook: tickets in motion, meetings, pending tasks, comments overnight. The agent uses this to suggest where to start the day and what is silently waiting.
Backup. Snapshots the agent's configuration - credentials, skills, memory - for disaster recovery. Idempotent; nothing pushes when there is no diff. After a workstation rebuild, the same agent comes back from a single command.
The Sub-Agents (4)
Sub-agents are separate from skills because they need their own context window. Each one handles work that would otherwise pollute the main conversation.
Parallel Manager. Coordinates multiple worktrees and agents running simultaneously. Assigns ports, allocates database names, tracks which environments are active. The mechanism that lets one developer have four Jira tickets in flight at once without environments stepping on each other.
Laravel Simplifier. Reviews incoming code - whether from a human or another agent - and looks for opportunities to simplify. Extracts long methods, replaces custom loops with collection pipelines, eliminates duplication, improves naming. Never changes behavior, only structure. Operates as a reviewer in the PR pipeline.
Code Explorer. Fast navigation through large codebases. Used when the main agent needs to find where something is defined or referenced without pulling whole files into its own window.
Research. Web search integrated into the agent workflow. When the agent needs documentation it cannot find internally, this sub-agent queries Brave Search, filters for authoritative sources, and summarizes the findings - all in a separate context so the main conversation stays focused.
The Configuration Problem
Building the skills was only half the battle. Getting them to work together required a shared configuration. Every developer's agent needed the same skills, the same defaults, the same credentials. But hardcoding credentials is a security risk, and manual setup is error-prone.
I solved this with a configuration repository that everyone clones. The repo contains:
- Skill definitions in JSON/YAML
- Environment variable templates (never containing secrets)
- Setup scripts that pull credentials from the company password manager
- Documentation explaining what each skill does and when to use it
New developers run one script: ./setup.sh. It installs dependencies, prompts for their API keys, pulls credentials from the password manager, and configures their agents. An hour later, they have the same setup as someone who has been here for two years.
The Adoption Challenge
I announced the shared configuration in a team channel. Response: crickets. A week later, only a small part of the team had installed it.
I had built it. I documented it. I made it easy to install. Why wasn't anyone using it?
The answer was obvious in hindsight: I had not demonstrated value. I had told people "this is better." I had not shown them "this makes your specific problem go away."
So I changed tactics. Instead of announcing, I started using the configuration myself exclusively. When someone asked how I finished a ticket so quickly, I showed them my agent running the Laravel workflow. When someone complained about code quality, I showed them the Laravel Simplifier suggestions. When someone spent thirty minutes searching for documentation, I showed them the Confluence lookup.
Word spread faster than any announcement. Within a month, everyone was using it. Not because I mandated it, but because they saw it working.
What I Learned
Building this shared configuration taught me more about AI engineering than any model fine-tuning or prompt engineering ever could. Here is what stuck:
Standardization creates network effects. When everyone uses the same skills, improvements benefit everyone. When Developer A improves the Jira skill's error handling, Developer B gets that improvement automatically. There is no "my custom setup that only I understand."
Documentation is part of the skill. A skill without documentation is a trap. The moment someone does not understand what a skill does or why it exists, they will either misuse it or avoid it. Documentation lives alongside the skill definition - same repository, same versioning.
Skills should be composable. The Parallel Manager does not know about Laravel or Jira or Bitbucket. It only knows about worktrees and ports. The Laravel Workflow skill knows about Laravel and the orchestrator, and it composes the Parallel Manager skill. Each skill has a single responsibility. The intelligence emerges from composition, not from monolithic skills.
Credentials management cannot be an afterthought. I made the mistake of hardcoding some API keys in early versions (in a private repo, but still). Security review caught it. Now every credential is pulled from a password manager at runtime, with fallback to environment variables for local development. The setup script handles all of this automatically.
The Results
After rollout, the useful signals were clear:
- More developers reused the same configuration instead of maintaining private prompts
- Common PHP workflows became easier to repeat from ticket to PR
- Agents caught more formatting, context, and testing issues before human review
- New skills could be improved once and reused across projects
- The team had a shared language for what AI was allowed to do
These numbers matter. But the cultural shift matters more. AI is no longer a toy some developers play with. It is part of our standard workflow, as fundamental as Git and code review. And because everyone uses the same setup, we can improve it together.
What Comes Next
The configuration is not static. Every week someone suggests an improvement. Last month, we added a skill that generates API documentation from code comments. This month, we are building a skill that analyzes PR diffs and suggests test cases that should be added.
The goal is not to build the "perfect" configuration - that does not exist. The goal is to build a living system that gets better the more people use it. That is what I love about this approach: the intelligence is not just in the AI model. It is in the collective wisdom of the team, encoded in skills that everyone shares and improves.
The best AI configuration is the one that becomes part of the team's collective knowledge, not individual secret sauce.
