add-mia-method
Use when adding a new membership inference attack (MIA) method to Fast-MIA from a research paper or GitHub repository
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when adding a new membership inference attack (MIA) method to Fast-MIA from a research paper or GitHub repository
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | add-mia-method |
| description | Use when adding a new membership inference attack (MIA) method to Fast-MIA from a research paper or GitHub repository |
Implement a new MIA method in Fast-MIA from a paper URL (required) and optional GitHub reference implementation. Follows a 5-phase process with human approval at each gate before proceeding.
/add-mia-method <paper-url> [github-url]
paper-url — required (any URL: arXiv, ACL Anthology, NeurIPS, ICML, PDF direct link, etc.)github-url — optional reference implementationDownload the paper. The source depends on the host. arXiv provides an HTML version for most papers (but not all — newly submitted papers, or TeX sources that fail HTML conversion, only have a PDF), so prefer HTML there and fall back to the PDF. Other hosts (ACL Anthology, OpenReview, NeurIPS/ICML/PMLR, direct PDF links, etc.) are downloaded as PDF. The Read tool parses PDFs natively, so a PDF is always a valid outcome.
mkdir -p references/papers
PAPER_URL="<paper-url>"
# Try to extract an arXiv ID (e.g. 2301.12345 or 2301.12345v2) from the URL.
ARXIV_ID=$(python3 -c "
import re, sys
m = re.search(r'([0-9]{4}\.[0-9]{4,5}(?:v\d+)?)', sys.argv[1])
print(m.group(1) if m else '')
" "$PAPER_URL")
if [ -n "$ARXIV_ID" ]; then
# --- arXiv: try the HTML version first, fall back to the PDF ---
if curl -fsSL "https://arxiv.org/html/${ARXIV_ID}" \
| uvx html2text > "references/papers/${ARXIV_ID}.md" 2>/dev/null \
&& [ -s "references/papers/${ARXIV_ID}.md" ]; then
echo "Fetched HTML version -> references/papers/${ARXIV_ID}.md"
else
# HTML unavailable (404) or empty: fall back to the PDF.
rm -f "references/papers/${ARXIV_ID}.md"
curl -fsSL "https://arxiv.org/pdf/${ARXIV_ID}" \
-o "references/papers/${ARXIV_ID}.pdf"
echo "HTML unavailable; saved PDF -> references/papers/${ARXIV_ID}.pdf"
fi
else
# --- Non-arXiv: resolve a direct PDF URL from the page URL ---
case "$PAPER_URL" in
*.pdf) PDF_URL="$PAPER_URL" ;; # already a PDF link
*aclanthology.org*) PDF_URL="${PAPER_URL%/}.pdf" ;; # .../2023.acl-long.1.pdf
*openreview.net*) PDF_URL="${PAPER_URL/forum/pdf}" ;; # forum?id=.. -> pdf?id=..
*) PDF_URL="$PAPER_URL" ;; # last resort: try as-is
esac
# Build a filesystem-safe slug for the output filename.
SLUG=$(python3 -c "
import re, sys
seg = sys.argv[1].rstrip('/').split('/')[-1]
seg = re.sub(r'\.pdf$', '', seg, flags=re.I)
print(re.sub(r'[^A-Za-z0-9._-]+', '-', seg) or 'paper')
" "$PDF_URL")
if curl -fsSL "$PDF_URL" -o "references/papers/${SLUG}.pdf" \
&& [ -s "references/papers/${SLUG}.pdf" ]; then
echo "Saved PDF -> references/papers/${SLUG}.pdf"
else
rm -f "references/papers/${SLUG}.pdf"
echo "Could not download a PDF from ${PDF_URL}"
fi
fi
Read whichever file was produced:
.md file was produced (arXiv HTML), read it with the Read tool..pdf file was produced, read it with the Read tool directly — the Read
tool parses PDFs natively. Use the pages argument for papers over 10 pages
(max 20 pages per call; page through the whole document).If no file was downloaded (the curl step failed or produced an empty file —
e.g. the host is behind a login wall, or the PDF lives at a non-obvious URL),
inform the user and ask them to provide a direct PDF URL you can download, or to
save the PDF into references/papers/ themselves.
Clone the GitHub reference (if provided):
git clone --depth 1 <github-url> references/repos/<repo-name>
Then read relevant files (e.g. the main scoring module) with the Read tool. Prefer tracing imports to locate helper functions rather than reading every file.
Produce a summary containing:
snake_case identifier used as the config type and module nametexts and model — does the method need labels, tokenizer, or neither?run() override needed? — yes only when the method needs extra models, augmented prompts, or multi-step inference; state the reason explicitlyPresent this summary and wait for explicit user approval before proceeding to Phase 2. If the user corrects an interpretation, revise the summary and confirm again.
Map the algorithm to BaseMethod. Present the following design:
MinKMethodtype, e.g. minkprocess_output() logic — exact formula as Python pseudocoderun() override — yes/no and the reason (from Phase 1)requires_labels = False (default)requires_tokenizer = False (default)requires_sampling_params = True (default)Closest existing methods for reference:
loss — mean log-probzlib — loss divided by zlib compression sizelower — loss on lowercased textmink — min-k% token log-probsref — loss minus reference model lossrecall — few-shot perplexity ratioconrecall — contrastive recallsamia — self-adversarial MIAdcpdd — DC-PDD tokenizer-based scoringpac — PAC-based scoringneighbour — masked-LM neighbour calibration (target loss minus mean neighbour loss)Present the design and wait for explicit user approval before proceeding to Phase 3.
Make the following three changes. For each sub-step, show the complete diff or file content to the user before writing.
src/methods/<module_name>.pyUse this template (replace placeholders):
# Copyright (c) 2025 Nikkei Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Any
# Add other imports as needed (numpy, vllm, etc.)
from vllm.outputs import RequestOutput
from .base import BaseMethod
class <ClassName>(BaseMethod):
"""<One-line description of the method>"""
def __init__(self, method_config: dict[str, Any] = None) -> None:
super().__init__("<module_name>", method_config)
# Extract config params; raise ValueError for missing required ones:
# self.param = self.method_config.get("param")
# if self.param is None:
# raise ValueError("<ClassName> requires 'param' in params.")
def process_output(self, output: RequestOutput) -> float:
token_log_probs = self._extract_token_log_probs(output)
# Implement the scoring formula here
...
Rules:
run() override is needed, add it after process_output() following the signature in BaseMethodself.get_outputs(...) inside run(), never model.generate(...) directlyrun(), call self.cleanup_model(model) at the endsrc/methods/factory.pyAdd one import and one entry. The existing METHOD_BUILDERS dict is defined in this file. Add:
from .<module_name> import <ClassName>
to the import block, and:
"<module_name>": <ClassName>,
to METHOD_BUILDERS.
src/methods/__init__.pyAdd:
from .<module_name> import <ClassName>
to the import block, and "<ClassName>" to __all__.
Wait for user approval on all three changes before writing any files.
In tests/unit/test_factory.py, add the class import at the top:
from src.methods.<module_name> import <ClassName>
Add a parametrize entry to TestMethodFactory.test_create_method:
("<module_name>", <ClassName>, {<minimal_valid_params_dict>}),
Use the smallest set of params that allows __init__() to succeed. For methods with no required params, use {}.
make test
Expected: all tests pass. If any test fails, diagnose the failure, fix the implementation, and re-run before reporting.
make lint
Expected: no errors. Fix any ruff errors before reporting.
Report all results to the user.
Summarize what was implemented:
type identifiermethods:
- type: "<module_name>"
params:
# list params with their defaults
Then prompt:
For contributions, also update
README.md,docs/docs/index.md, anddocs/docs/how-to-use.mdperdocs/docs/adding-methods.md.
run() unless Phase 1 analysis shows a clear need. The default in BaseMethod covers the common case.__init__() with a ValueError and a descriptive message.RequestOutput interface — do not add new framework dependencies.