How to Reduce AI Agent Token Costs for Stickman Animations with Reusable Skills

    A simple prompt can turn an AI coding agent into an expensive trial-and-error loop. This article explains why that happens when generating stickman animations, and shows how to move from one-off prompting to a reusable engineering workflow. It covers scoping skills to a project, writing structured rules in SKILL.md, separating data, rendering, and scheduling, adding automated validation, and reducing token consumption by lowering repeated input, invalid output, context growth, and debugging overhead.

    1. Starting from a Failed Generation

    Asking a code agent to generate a stickman explainer animation looks like a small task: one web page, three scenes, and fifteen seconds of animation. It seems like something that does not require serious architecture design.

    The actual result can be quite different: the stickman’s head-to-body ratio becomes distorted, the arm lines are crooked, animation logic and page structure become tangled together, styles and logic become entangled, and adjusting the pacing requires rewriting most of the file. Fixing one issue creates another. After several rounds of iteration, token consumption is far higher than expected. The developer’s monthly bill can climb from tens of dollars and even double.

    Many developers have had similar experiences: a requirement can be described in one sentence, but the bill grows faster than expected. Where is the problem?

    First, the goal is incomplete. If the request only says “write an animation,” the model has no reason to prioritize visual quality or code structure. It may treat “it opens and it plays” as the acceptance criterion, rather than “it looks good, is easy to modify, and is reusable.”

    Second, quality constraints are not included in the input. Rules such as the head-to-body ratio, movement speed, and captions for each scene are not explicitly expressed. The model can only guess based on default probabilities. Once the generated result is unsatisfactory, the only option is to repeatedly refine it with additional manual instructions, and every round consumes both input and output tokens.

    Third, the output structure is not layered. A single file may contain the timeline, character drawing, scene animation, layout styles, and copy content all at once. Any modification requires rereading the entire file. The change may be local, but the context cost is global.

    To reduce cost, it is not enough to simply “write a few more prompts and try a few more times.” One-time inspiration needs to be converted into reusable engineering assets. The core carrier for this is a Skill.

    2. What Is a Skill: Turning “Professional Practice” into a Reusable Knowledge Package

    In a code agent, a Skill can be understood as a “skill package” or a “domain knowledge package.” It is a set of structured resources, usually including a specification document, optional scripts or templates, and a quality checklist. It is placed in a skill directory agreed upon by the project. When the agent executes a task, it first checks whether the current directory contains a skill related to the requirement. Once a match is found, it loads the rules in that skill and follows them.

    For the stickman animation scenario, a Skill should at least answer four questions:

    • Canvas and duration: What aspect ratio should be used, how long should the animation be, and what pacing should it follow?
    • Character design: What head-to-body ratio, limb lengths, joint positions, and line styles should be used?
    • Motion rules: What angles and pacing should be used for actions such as walking cycles, arm swings, and turns?
    • Code organization: How should files be split, how should data be organized, and how should output be validated?

    Once these rules are fixed, every subsequent generation is effectively “filling content inside a validated framework.” This is a key step in encoding art standards, interaction motion rules, and front-end engineering conventions into an AI workflow.

    3. Create a Directory First: Scan Only the Current Project’s Skill Folder

    When asking the agent to check for skills, make sure the scope is limited to the current working directory, such as the skills/ folder in the project root. Do not let it scan the entire disk. A full scan wastes time and may mistakenly treat rules from other projects as conventions for the current project.

    A recommended structure is to split skills into independent modules by responsibility:

    1. stickman-showcase/
    2. ├── index.html # Page structure and styles
    3. ├── styles.css # Layout and visual styles
    4. ├── storyboard.json # Scenes, copy, and timing
    5. ├── renderer.js # Character drawing and keyframes
    6. ├── scenes.js # Scene scheduling and timeline
    7. ├── skills/
    8. │ └── stickman-animation/
    9. │ └── SKILL.md # Rule specification
    10. └── tools/
    11. └── check-output.mjs # Output validation script

    Note that an earlier example may place SKILL.md directly in the skills/ root directory. This section uses a hierarchical structure that keeps the full skill set inside a skill subdirectory. Both approaches work. Once a skill is split into “rules + templates + validation,” it is no longer just a document. It becomes a lightweight engineering specification.

    4. Write a Clear Skill: Use Structured Rules to Constrain Visuals and Code

    The core of SKILL.md is executable constraints, not vague design advice. Statements such as “lines should look good” or “motion should feel natural” cannot be quantified or executed by the model. Rules need to be specific to angles, durations, proportions, and file names. The following example can be used as the starting point for a skill specification:

    1. # Skill: Stickman Explainer Animation
    2. ## Use Cases
    3. Generate a single-page 2D stickman explainer animation in 16:9 landscape format.
    4. ## Canvas Specification
    5. - Logical canvas: 1280×720, using an SVG viewBox and scaling proportionally to the window
    6. - Total timeline: 15 seconds, split into 3 scenes, each 5 seconds long. A scene starts only after the previous scene has finished.
    7. ## Character Specification
    8. - Use the hip as the origin for positioning. Skeleton nodes: head, neck, shoulders, elbows, hands, hips, knees, and feet.
    9. - Key proportions: head radius = height × 0.08; torso = height × 0.30;
    10. upper arm = 0.18, forearm = 0.16, thigh = 0.24, shin = 0.22, all measured relative to character height.
    11. - Lines: stroke-width 6, round line caps, main color #333333, accent color #2f6fed.
    12. - Use circular joints consistently to avoid broken angles from simple linear connections.
    13. ## Motion Specification
    14. - Walking cycle: single step duration 0.6 seconds. Vertical hip movement must not exceed 2% of character height. Front and back leg swing: ±20°.
    15. - Arm swing: elbow bend from 15° to 60°. Arms should swing opposite to the leg on the same side.
    16. - Do not use sliding-style movement where the whole body shifts more than 10 px/s. Step motion and displacement must be synchronized.
    17. ## Scene Specification
    18. - Scene content is driven by storyboard.json. scenes.js is only responsible for scheduling and must not hard-code captions.
    19. - Transitions use a unified 0.4-second opacity fade-in/fade-out. Do not use fancy effects such as scaling or rotation.
    20. - Keep only the main animation on the page. Do not add decorative backgrounds or icons.
    21. ## Code Organization
    22. - index.html contains structure only. Styles go in styles.css. Logic goes in scenes.js and renderer.js.
    23. - Variable naming conventions: canvas constants start with CANVAS_, character constants start with FIG_.
    24. - Character drawing functions only receive a skeleton angle dictionary and must not read global time variables.
    25. ## Acceptance Criteria
    26. - When opened in a browser, the 3 scenes play in sequence, with a total duration of about 15 seconds.
    27. - The visuals have no misalignment or flicker, and character proportions match the rules in this specification.
    28. - A single HTML file must not exceed 60 KB, excluding external resources.
    29. - When modifying any caption, only storyboard.json needs to be edited. No JS changes should be required.

    Rules need this level of detail because models are much better at following explicit numbers than interpreting vague adjectives. Writing “head-to-body ratio of about 1:6.5” as a computable proportional constant, and breaking “natural motion” into leg swing angle, step duration, and maximum hip displacement, makes the generation result reproducible. At the same time, the skill description should only describe general principles and specifications. It should not bind to any specific model or product feature, so that it can be reused stably in different environments.

    5. A Direct Comparison: The Skill-Based Generation Flow

    Once preparation is complete, the task can be split into two steps. First, let the agent confirm whether a matching skill already exists in the skill directory. Second, after confirming that it exists, generate according to the skill rules.

    The prompt does not need to describe in detail “what it should look like.” It only needs to state the theme, aspect ratio, duration, and output location.

    A prompt example:

    1. Please check only whether the current project's skills/ directory contains a skill related to stickman animation.
    2. If it exists, read SKILL.md and strictly follow its specifications to generate a single-page 15-second stickman explainer animation in the current directory.
    3. The theme is “pain points of a solo creator taking short videos internationally.”
    4. Use 16:9 landscape format and split the animation into 3 scenes.
    5. After completion, run a self-check with tools/check-output.mjs, and report the time taken and the list of changed files.

    Compared with plain generation, the skill-based output shows clear improvements in several dimensions:

    Comparison Dimension Plain Generation Skill-Based Generation
    Character design Proportions are guessed by the model and often become distorted Proportion constants are fixed and remain consistent across scenes
    Motion quality Arm swings and steps become disconnected, often looking like sliding Loop parameters and displacement are synchronized, with consistent pacing
    Code structure Structure, styles, logic, and copy are mixed in one file Files are split by responsibility, and copy is decoupled from rendering
    Modification cost Adjusting one scene often requires rewriting large portions of code Changing a data file is enough to take effect
    Validation method Relies on human visual inspection, so issues are found late Scripts automatically check file splitting and duration consistency
    Rework count Multiple rounds of “change it again,” causing context to keep expanding Mostly one-pass generation, with only minor adjustments

    This approach is not limited to stickman animations. Any output with fixed visual specifications, such as data charts, flowcharts, device diagrams, or teaching demonstrations, can be handled using the same method: “turn specifications into a Skill, and validate the generated result with scripts.”

    6. The Token Perspective: Why the Cost Can Drop Significantly

    To understand the cost-saving effect, it helps to see how tokens are consumed in an AI coding session. Generally, each request needs to send the system prompt, conversation history, and current instruction as input tokens. The model’s reply is counted as output tokens. The longer the session becomes, the more historical content is sent repeatedly. If the model repeatedly generates large blocks of code only to have them discarded and rewritten, output token usage can rise sharply.

    This approach reduces consumption in four areas.

    First, it reduces repeated descriptions on the input side. Once the rules are written into a skill file, each task only needs to specify the theme and output requirements. There is no need to repeat in every conversation round: “How large should the head be, how slow should the motion be, and how should files be organized?”

    Second, it reduces invalid output. When constraints are clear, the first generation is closer to usable. The model does not need several rounds of “rewrite a new version.”

    Third, it controls context expansion. Modular files mean each modification usually involves only a single small file. Instead of repeatedly reading a several-thousand-line large file, the model only needs to read the few dozen lines that need to change. The longer the session, the more obvious this saving becomes.

    Fourth, it reduces debugging overhead. Script-based validation helps catch structural and timing issues during generation, avoiding cases such as “only discovering misalignment during playback” and then rewriting the output.

    The actual amount saved depends on task complexity, model capability, and session organization. It is more meaningful to treat “cost reduction” as a systematic improvement brought by methodology than to focus on a fixed number.

    If there are additional needs such as dashboards or presentation pages beyond animations, you can further layer skill management:

    • General rules: canvas, duration, accessibility requirements, and code organization conventions.
    • Project rules: business copy, brand colors, and proprietary terms.
    • Task rules: specific scenes and themes for a single request.

    After this layering, general rules can be reused across multiple projects. Project rules only need to be maintained once. Task rules are created anew for each task. This avoids rule files becoming longer and longer and conflicting with each other.

    7. Modular Templates: Making Modification Cost Approach Zero

    The skill specification solves “how to write.” Templates solve “where to modify.” The following renderer.js example separates “constants — skeleton calculation — drawing” into three layers. None of the layers directly depends on the implementation details of another layer:

    1. // ===== 1. Constants layer: changes are only allowed within the constraints defined by SKILL.md =====
    2. const FIG = {
    3. height: 260, // Character height in logical pixels
    4. headRatio: 0.08, // Head radius / height
    5. torsoRatio: 0.30, // Torso length / height
    6. upperArm: 0.18, // Upper arm / height
    7. foreArm: 0.16, // Forearm / height
    8. thigh: 0.24, // Thigh / height
    9. shin: 0.22, // Shin / height
    10. lineWidth: 6,
    11. color: '#333333'
    12. };
    13. // Convert degrees to radians to avoid scattered conversion logic in drawing code
    14. const rad = (deg) => (deg * Math.PI) / 180;
    15. // ===== 2. Skeleton calculation layer: input pose angles, output node coordinates =====
    16. // pose structure: { hip:{x,y}, lean, legFront, legBack, armFront, armBack, kneeBend, elbowBend }
    17. function buildSkeleton(pose) {
    18. const H = FIG.height;
    19. const hip = { x: pose.hip.x, y: pose.hip.y };
    20. const neck = {
    21. x: hip.x + Math.sin(rad(pose.lean)) * H * FIG.torsoRatio,
    22. y: hip.y - Math.cos(rad(pose.lean)) * H * FIG.torsoRatio
    23. };
    24. const headR = H * FIG.headRatio;
    25. const head = { x: neck.x, y: neck.y - headR };
    26. // Lower body: hip → knee → foot. Knee bend determines the lower-leg direction.
    27. const leg = (swing, bend) => {
    28. const knee = {
    29. x: hip.x + Math.sin(rad(swing)) * H * FIG.thigh,
    30. y: hip.y + Math.cos(rad(swing)) * H * FIG.thigh
    31. };
    32. const ankle = {
    33. x: knee.x + Math.sin(rad(swing - bend)) * H * FIG.shin,
    34. y: knee.y + Math.cos(rad(swing - bend)) * H * FIG.shin
    35. };
    36. return { knee, ankle };
    37. };
    38. // Upper body: shoulder → elbow → hand
    39. const shoulderY = neck.y + H * 0.04;
    40. const arm = (swing, bend) => {
    41. const elbow = {
    42. x: neck.x + Math.sin(rad(swing)) * H * FIG.upperArm,
    43. y: shoulderY + Math.cos(rad(swing)) * H * FIG.upperArm
    44. };
    45. const hand = {
    46. x: elbow.x + Math.sin(rad(swing + bend)) * H * FIG.foreArm,
    47. y: elbow.y + Math.cos(rad(swing + bend)) * H * FIG.foreArm
    48. };
    49. return { elbow, hand };
    50. };
    51. return {
    52. head, neck, hip,
    53. headR,
    54. legFront: leg(pose.legFront, pose.kneeBend),
    55. legBack: leg(pose.legBack, pose.kneeBend * 0.6),
    56. armFront: arm(pose.armFront, pose.elbowBend),
    57. armBack: arm(pose.armBack, pose.elbowBend * 0.8)
    58. };
    59. }
    60. // ===== 3. Drawing layer: consumes skeleton coordinates only and performs no pose calculation =====
    61. function drawFigure(svg, bone) {
    62. const line = (a, b) =>
    63. `<line x1="${a.x}" y1="${a.y}" x2="${b.x}" y2="${b.y}" />`;
    64. const dot = (p) =>
    65. `<circle cx="${p.x}" cy="${p.y}" r="4" />`;
    66. return `
    67. <g stroke="${FIG.color}" stroke-width="${FIG.lineWidth}"
    68. stroke-linecap="round" fill="${FIG.color}">
    69. <circle cx="${bone.head.x}" cy="${bone.head.y}" r="${bone.headR}"
    70. fill="none" />
    71. ${line(bone.neck, bone.hip)}
    72. ${line(bone.hip, bone.legFront.knee)}${line(bone.legFront.knee, bone.legFront.ankle)}
    73. ${line(bone.hip, bone.legBack.knee)}${line(bone.legBack.knee, bone.legBack.ankle)}
    74. ${line(bone.neck, bone.armFront.elbow)}${line(bone.armFront.elbow, bone.armFront.hand)}
    75. ${line(bone.neck, bone.armBack.elbow)}${line(bone.armBack.elbow, bone.armBack.hand)}
    76. ${dot(bone.hip)}${dot(bone.neck)}
    77. </g>`;
    78. }
    79. export { FIG, buildSkeleton, drawFigure };

    This structure brings three direct benefits.

    • Pose and rendering are decoupled. Adjusting the walking cycle only requires changing the angles passed to buildSkeleton. There is no need to touch SVG string concatenation.
    • Constants are centralized. All proportions can be found in FIG. During review, it is immediately clear whether any value goes out of bounds.
    • Reuse becomes easier. drawFigure does not depend on time variables. The same character can appear in any scene, and it is also easier to extend to multi-character scenarios later.

    With this structure, the model’s “degrees of freedom” when generating code are compressed into a very small range. Output quality naturally becomes more stable, and the number of generation rounds needed also decreases.

    8. Use Scripts to Close the Loop: Turning “It Looks Okay” into Automated Validation

    Once the specification is written, someone still needs to check whether it is being followed. Making the validation script part of the skill and having the agent run it automatically after generation is the most economical approach:

    1. // tools/check-output.mjs: lightweight self-check. Only structural checks are performed, not visual review.
    2. import { readFileSync, statSync, existsSync } from 'node:fs';
    3. const required = ['index.html', 'styles.css', 'storyboard.json', 'scenes.js', 'renderer.js'];
    4. const errors = [];
    5. for (const f of required) {
    6. if (!existsSync(f)) errors.push(`Missing file: ${f}`);
    7. }
    8. // The total duration of all scenes should equal the total timeline duration.
    9. const board = JSON.parse(readFileSync('storyboard.json', 'utf8'));
    10. const total = board.scenes.reduce((sum, s) => sum + s.duration, 0);
    11. if (Math.abs(total - board.timeline) > 0.01) {
    12. errors.push(`Scene duration total ${total}s does not match timeline ${board.timeline}s`);
    13. }
    14. // Captions should not be empty, to avoid blank scenes.
    15. board.scenes.forEach((s, i) => {
    16. if (!s.caption || !s.caption.trim()) errors.push(`Scene ${i + 1} is missing a caption`);
    17. });
    18. // Single-file size limit, to prevent unrelated decoration from accumulating.
    19. const htmlSize = statSync('index.html').size / 1024;
    20. if (htmlSize > 60) errors.push(`index.html size ${htmlSize.toFixed(1)}KB exceeds the 60KB limit`);
    21. if (errors.length) {
    22. console.error('Self-check failed:\n' + errors.map((e) => ' - ' + e).join('\n'));
    23. process.exit(1);
    24. }
    25. console.log('Self-check passed');

    This script does only three things: check whether required files exist, check whether the timeline and scenes are internally consistent, and check whether the file size exceeds the limit. It does not try to judge “whether the visuals look good.” Instead, it automates problems that are easy to overlook but also easy to fix, avoiding pushing them to the manual acceptance stage. It also avoids adding another generation conversation for such issues.

    9. Make the Content Theme Clear: Let Content Serve the Narrative

    The stickman is only the form of expression. What really matters is the content being conveyed. Take “pain points of a solo creator taking short videos internationally” as an example. The three scenes can be arranged as follows:

    • Scene 1: Working alone. One person handles ideation, filming, editing, publishing, and customer support. The visuals can use a timeline to show “the same person being pulled in multiple directions by many tasks.”
    • Scene 2: Local friction. When targeting overseas markets, language habits, platform rules, aesthetic preferences, and time zone differences all become barriers. Misaligned speech bubbles can be used to show “information does not line up.”
    • Scene 3: Process breakthrough. Break ideation, scripts, assets, and publishing into reusable templates. End with a contrast between “chaos and order,” and provide an actionable direction.

    Scene data is recommended to be placed separately in storyboard.json. For example:

    1. {
    2. "timeline": 15,
    3. "scenes": [
    4. { "id": 1, "start": 0, "duration": 5, "caption": "One person handles every step", "mood": "tense" },
    5. { "id": 2, "start": 5, "duration": 5, "caption": "Language, platform rules, and time zones are all barriers", "mood": "confused" },
    6. { "id": 3, "start": 10, "duration": 5, "caption": "Templateize the workflow to scale", "mood": "determined" }
    7. ]
    8. }

    After separating content from presentation, changing the theme only requires replacing the captions and mood labels. The visual rules do not need to change at all. This is also a hidden benefit of modularization: content iteration no longer triggers code rewrites.

    10. Common Pitfalls and How to Avoid Them

    In practice, several issues appear repeatedly. They are worth avoiding in advance.

    • Rules that are too detailed become “hard-coded.” If the skill file is filled with frame-by-frame parameters for every action, the model may find it harder to combine movements flexibly. The better approach is to specify proportions, pacing, and boundaries, and leave concrete actions for the model to express within those constraints.
    • Only writing “what not to do,” not “what to do.” A negative list can prevent drift, but it cannot guide implementation. Each prohibition should ideally be paired with an executable positive requirement.
    • Relying on human visual inspection. Human eyes are good at judging “whether it looks good,” but not at judging “whether it violates a specification.” Checks that can be automated should be given to scripts, so human effort can focus on creativity and narrative.
    • Ignoring accessibility and performance. Animations should respect the system’s “reduce motion” preference and avoid high-frequency flashing. Also, control the number of DOM nodes to prevent frame drops on lower-end devices.
    • Stuffing all rules into one file. The longer the rules, the more likely the model is to “miss reading” parts of them. Split sections by canvas, character, motion, scene, and code organization, and keep each section concise. This improves both hit rate and compliance.

    11. Summary: Turning “One-Time Generation” into a “Reusable Production Line”

    Returning to the initial question: why can a one-sentence requirement burn through a surprisingly high bill?

    The root cause is the absence of quality-control mechanisms. The model can only repeatedly try and fail without constraints, and the cost of trial and error is ultimately paid by the token bill.

    The path presented in this article can be summarized in four steps:

    1. Codify specifications: Write proportions, pacing, and code organization into reusable skill files.
    2. Layer the structure: Keep data, rendering, scheduling, and styles independent so modifications remain local.
    3. Automate validation: Use scripts to enforce file completeness, duration consistency, and size limits.
    4. Use a cost perspective: Use input repetition, invalid output, and context length as core metrics, and continuously optimize session organization.

    For developers, the direct benefits of this method are less rework, clearer structure, and reproducible results. For teams, it means that outputs with fixed specifications, such as animations, charts, and presentation pages, can be produced steadily like a production line.

    When rules are written into a Skill, an AI agent is no longer a temporary worker that must be re-explained every time. It becomes a collaborator that follows established specifications. Cost reduction does not come from using AI less. It comes from organizing AI input and output more intelligently.