Academic Forge

repository·site-first·Indexed 25 days ago

https://github.com/hughyau/academicforge

A platform for selecting and installing academic-focused AI skills for agents such as Claude Code, OpenCode, and Codex. It functions as a 'mod loader' for academic workflows, providing tools for structural biology, genomics, data visualization, and scientific writing, including the Claude Science collection of 32 skills.

Tokens
101K
Snippets
178
Records
382
Agent score
82%

What's inside academicforge

  1. How the Modal environment build process works

    site-first

    To use custom compute environments, you must distinguish between the control-plane kernel (the repl tool) and the compute_provider kernel.

    • compute_provider kernel: A dedicated Python shell where the modal SDK is authenticated. It is used to build images and populate weight volumes. It requires a one-time approval and has guardrails (e.g., 30-minute timeout cap on CPU sandboxes, no gpu= parameter allowed).
    • Control-plane kernel (repl): Used for job submission via host.compute.create(). It does not have access to Modal credentials. It only receives the resulting image reference string from the provider kernel.

    This separation ensures that building an image (which requires high-privilege SDK access) is a distinct, validated task from running a job (which uses a narrow, parameterized path).

  2. Include statistical rigor in visualizations

    site-first

    Always include the following in your figures to ensure scientific rigor:

    • Error bars: Specify if they represent SD, SEM, or CI in the caption.
    • Sample size (n): Include in the figure or caption.
    • Significance markers: Use symbols like *, **, ***.
    • Individual data points: Show them when possible alongside summary statistics.
    # Show individual points with summary statistics
    ax.scatter(x_jittered, individual_points, alpha=0.4, s=8)
    ax.errorbar(x, means, yerr=sems, fmt='o', capsize=3)
    
    # Mark significance
    ax.text(1.5, max_y * 1.1, '***', ha='center', fontsize=8)
  3. Categorize indication regulatory maturity

    site-first

    When performing regulatory research, explicitly categorize the indication's maturity level to contextualize the available guidance:

    • Well-established (e.g., IPF, MASH): Detailed FDA guidance is available.
    • Emerging (e.g., sarcopenia): Limited or no formal guidance exists.
    • Novel (e.g., ageing): No existing regulatory framework.
  4. Run Claude Science skills as pure skills on any agent

    site-first

    The skills located in skills/claude-science/ have been re-architected as pure skills. This means they no longer require the proprietary Anthropic Claude Science kernel, the host object, or specific LLM API keys to function.

    Key Characteristics

    • Self-contained: Every kernel.py is deterministic Python (e.g., PDF parsing, DOI verification, image composition) that runs without a specialized runtime.
    • Model-Agnostic: Instead of the skill calling host.llm() internally, the skill provides raw data (text, images, etc.) to your agent. The agent's base model is then responsible for the reasoning, classification, or summarization tasks.
    • Zero Configuration: Most skills require no API keys or environment variables to run locally.
  5. Manage compute handles and container lifecycles

    site-first

    A single compute handle corresponds to one container.

    Lifecycle Rules

    • Warm Reuse: Subsequent submit_job() calls on the same handle reuse the warm container.
    • Sequential Execution: Each submit_job() wipes the /work directory. Call job $N+1$ only after receiving the compute_done notification for job $N$. For parallel jobs, use separate handles.
    • Closing Handles: Always call c.close() after the final job in a sequence is complete and the harvest is confirmed. Do not close a handle if it holds unrecovered outputs (see result_rejected or harvest_failed).
    • Termination: A container is terminated by the sandbox's idle watchdog after ~30 minutes of inactivity, or by its container timeout.

    Cleanup

    Before finishing a task, ensure all handles are closed and no sandboxes remain alive in the compute_provider kernel. Use modal.Sandbox.list(app_id=app.app_id) to verify. Use c.close() to tear down job-surface containers; reserve sb.terminate() only for sandboxes you created manually in the kernel.

  6. Use parallel subagents for Biology & SoC research

    site-first

    To optimize the Phase 3 research process, use the following specialized subagents:

    • pubmed MCP: Use this for biological research, specifically finding recent review articles on disease mechanisms and pathways.
    • WebSearch (site:fda.gov): Use this specifically to identify approved drugs and their regulatory status.
    • WebSearch (general): Use this to find specialty society guidelines (e.g., NCCN, AASLD) and treatment algorithms.
  7. Identify the correct documentation for Anthropic products

    site-first

    Anthropic offers three distinct products. To ensure accuracy, use the specific documentation resource mapped to the product being discussed:

    • Claude API: For technical implementation details including function calling/tool use, batch processing, SDK usage, rate limits, pricing, and model specifications.
    • Claude Code: For CLI-based development tasks, including installation, Node.js requirements, platform/OS support, MCP server integration, and configuration.
    • Claude.ai: For consumer-facing questions regarding subscription plans (Pro vs Team vs Enterprise) and feature limits.
  8. Maintain academic integrity in tutoring

    site-first

    Adjust your approach based on whether the learner is a self-learner or being assessed.

    For Self-Learners:

    • There is no integrity policy. Your only obligation is to ensure they actually learn the material.

    For Learners in a Course (Assessed):

    • Do not produce final answers to graded problem sets, exams, or quizzes.
    • Do not write text intended to be turned in (e.g., essays).
    • Do teach the concept using examples distinct from the assigned work.
    • Do walk through parallel problems.
    • Do review their attempts by pointing out what to reconsider rather than grading them.
    • Coding assignments: Explain concepts and debug errors, but do not write the function the student was asked to write.

    How to decline: When refusing to provide a direct answer, state what you can do: "I won't write the essay, but I'd like to help — want to talk through your argument?"

  9. Format --fixed_positions_jsonl correctly

    site-first

    The --fixed_positions_jsonl flag is used to hold specific residues fixed during redesign. The input file must be a JSONL file where each line is a JSON object keyed by the PDB stem first, then the chain ID, then a list of 1-indexed residue numbers.

    Correct Format: {"backbone": {"A": [10, 11, 12], "B": []}}

    Common Error: If you pass only the inner dictionary (e.g., {"A": [10, 11, 12]}), the tool will not match the PDB stem and will silently redesign every residue instead of fixing them.

    Tip: Use the provided helper_scripts/make_fixed_positions_dict.py to generate the correctly shaped dictionary from a chain and range string.

    {"backbone": {"A": [10, 11, 12], "B": []}}
  10. Understand Modal network egress policies

    site-first

    Network egress (outbound connectivity) for job sandboxes is a per-provider setting configured in Settings → Compute → modal → Network Restrictions. It is applied to every new sandbox at creation time and cannot be changed per submission.

    There are four possible states:

    1. Not configured (NULL): The default state. The sandbox has Unrestricted access to the open internet.
    2. Allowlist: The sandbox can only connect to a specific list of domains. This list is a merge of:
      • The host's mirror of the user's local sandbox allowlist.
      • Built-in seed domains (e.g., download.pytorch.org, pypi.nvidia.com).
      • The provider's extra domains.
      • The environment's declared domains.
      • Note: A mirror:false policy is never seeded and only uses the user's explicit list.
    3. No network: A kill-switch state where all outbound connections are refused. In this state, environment-declared domains and allowlists are ignored.
    4. Unrestricted: Explicitly open internet access.
  11. Use Kernel Sidecars (`kernel.py` / `kernel.R`) for skill workflows

    site-first

    If a skill requires reusable helper functions, you can include a kernel.py (Python) or kernel.R (R) file at the skill's root. When an agent calls a skill, these files are executed in a persistent kernel, making the defined functions available to the agent.

    Validation Rules for kernel.py (Top-level restrictions): To ensure safe loading, only specific constructs are allowed at the module level. Anything else (classes, function calls, if/for blocks, non-literal assignments) will cause a [kernel.py rejected] error.

    • Functions: Use def or async def. No decorators are allowed at the top level. Default arguments must be literals (e.g., def f(url=None):). Do not use def f(url=MY_CONSTANT):.
    • Imports: Use import or from ... import name. No import * is allowed. Defer third-party imports (like requests) to inside function bodies. The environment includes a starter set: numpy, pandas, scipy, matplotlib, seaborn, and pillow.
    • Constants: You may assign literals to plain names (e.g., VERSION = "1"). Computed values like os.path.join(...) are rejected and must be moved inside functions.
    • Naming: Names starting with _ are reserved by the loader and cannot be used at the top level.

    Accessing the Skill Directory: Because the skill directory is not on sys.path, you cannot use from scripts.X import .... To run a standalone script located in the scripts/ directory, use sys._getframe().f_code.co_filename to locate the directory and subprocess to execute it.

    # kernel.py
    import os, sys, subprocess
    
    def run_pipeline(cfg_path):
        # Locate the skill directory via the function's code filename
        here = os.path.dirname(sys._getframe().f_code.co_filename)
        if not here:
            raise RuntimeError("skill dir unavailable in this runtime")
        
        # Path to a standalone script in the scripts/ folder
        tool = os.path.join(here, "scripts", "pipeline.py")
        
        # Execute via subprocess
        return subprocess.run([sys.executable, tool, cfg_path],
                              capture_output=True, text=True, check=True).stdout