What this skill produces
A single-page HTML (three columns) that can be opened directly in a browser:
- Left column: problem statement + dynamic console — one variable-parameter slider (e.g. line inclination angle θ / moving point parameter t) driving real-time recomputed geometric quantities (intersection coordinates, slope, dot product, chord length, area…), plus a "theoretical range bar" or "constant-value indicator".
- Middle column: step-by-step solution (formulas use KaTeX), can be collapsed with one click to give space to the board.
- Right column: 2D Canvas dynamic geometry board (conic sections + moving line/moving point + vectors + point labels + grid coordinate axes), overlaid with a pen doodle toolbar.
Form and target template /Users/wuyi/code/code2026/6/template/code_artifact.html consistent.
Dependencies (important)
Computation core lib/analytic_kernel.py depends on sympy. Before running the script, first confirm there is an
interpreter that can import sympy:python3 -c "import sympy"(locally use /opt/homebrew/bin/python3.11,sympy 1.14)。
When libraries are missing: if import errors (sympy or any subsequent library),first ask the user whether to install, and after agreement then install
(python3 -m pip install <库名>) or switch to an interpreter that already has the library installed;do not install directly without asking.
Below, python3 all refer to this interpreter that can run the dependencies.
Workflow
Step 1: Obtain the problem spec (three entry points unified)
Organize the problem into a structured spec (curve type and parameters, known points/conditions, requested type and objects, language).
- Text problem: extract directly.
- Image: extract by visual reading, andecho the recognized problem back to the user for confirmation(problem statement/curve/parameters/requested/language) before continuing.
- Random problem generation: choose curve + problem type, random parameters → kernel solve, use
analytic_kernel.is_clean(...)to judge whether the answer is neat; if not neat, redraw.
Output language follows the prompt language: English prompt → English webpage, Chinese → Chinese. The spec records
language。
Step 2: Use the kernel for exact computation (do not do mental math)
According to references/conventions.md 's solution recipe, call lib/analytic_kernel.py and lib/conics.py:
conics.ellipse/hyperbola/parabola/circle(...)to get the curve object (exact a,b,c, foci, vertices, directrix, asymptotes,eq_latex, and theboarddict)。chord_setup(conic, through)for the frontend engine; simultaneously solve the parametric linex=my+cto get the quadratic equation in y + Vieta quantities (exact).- Target quantities:
dot_product_expr/chord_len_sq_expr/triangle_area_expr/slope_product_central… - Value range:
range_over_m(expr, horizontal_valid=?)—— including open/closed endpoint determination(key correctness point, see below). - Constant value:
is_constant_in_m(expr)。
The kernel can be self-checked from the command line:
python3 lib/analytic_kernel.py # 旗舰题内置断言自检
⚠️ Endpoint open/closed = the crux of correctness: A chord through the focus; the horizontal line (x-axis, θ=0) and the vertical line (θ=90) are both valid lines, and the endpoints they attain must be counted. Example: for the ellipse MA·MB problem, the x-axis attains −3 and the vertical line attains 7/4, so the answer isclosed interval
[-3, 7/4](many study guides mistakenly write it as open(-3, 7/4])。range_over_mhas been judged accordingly, and this way the answer is consistent with the interactive tool—drag the slider to 0° and you read −3. The "axis direction" of a focal chord of a parabola is a degenerate line (intersecting at only one point), and its limiting endpoint is not counted (horizontal_valid=Falseor restrict the param range).
Step 3: Assemble the data and inject it into the template
📍 Output location & sole artifact (most important): Thedelivered to the user is only one
.html, written tothe current working directory (Path.cwd())(unless the user explicitly specifies a path). In the cwd,do not leave any other files—build scripts (.py)、__pycache__, self-check screenshots (.png), and temporary files are allnot deliverables, always put them in/tmpor delete them after use. Alsoneverwrite into the skill's own directory (skills/edu-analytic-geometry/output/is an internal sample of the skill).
Write the "assemble data + inject template"build script to a temporary directory(e.g. /tmp/ag_build.py), and have itonly write .html
to the cwd; the script assembles the lesson / steps / board data (for the schema see references/problem-schema.md),
calls generate.render_html(data, out) to inject template/board.html,delete the script once it has run:
# 构建脚本放 /tmp(不要放 cwd):/tmp/ag_build.py
import sys; sys.dont_write_bytecode = True # 不生成 __pycache__
sys.path.insert(0, "<技能目录>/scripts")
import generate
from pathlib import Path
data = {"lesson": {...}, "steps": [...], "board": {...}}
out = Path.cwd() / "solution-<题目简述>.html" # 唯一产物,落在用户当前目录
generate.render_html(data, out)
python3 -B /tmp/ag_build.py && rm -f /tmp/ag_build.py # -B 不写字节码;跑完删临时脚本,cwd 只剩 .html
steps[*].contentthe values indirectly reference the kernel results(useK.tex(...)to output LaTeX), and the model is only responsible for organizing the explanatory text (in the target language).boarduse the curveboarddict given by the kernel, the exact point coordinates, theparam、derivedconstruction sequence,readouts、rangeBar(for range problems) /constant(for fixed-value problems) /answerBand(shape-parameter problems, such as the eccentricity range).- Shape-parameter problems (slider = eccentricity e, etc.): When the natural dynamic quantity is the shape of the curve itself rather than a moving line/point, let the slider = that parameter,
and write the curve
a/b/c, focus, and moving-point coordinates as@paramofexpression strings(the engine redraws the curve/focus/asymptotes every frame), withstatusreadouts showing the inequality status, andanswerBandhighlighting the answer interval on the parameter axis. See conventions "shape-parameter problems". - Templates you can copy directly:
scripts/generate.pyThe 6build_*in cover various interaction paradigms:ellipse_dot_range(range bar),ellipse_chord_range、ellipse_area_max、ellipse_slopeprod_const(fixed value · central symmetry),parabola_dot_const(fixed value · parabola),hyperbola_ecc_range(shape parameter: slider = e, the curve is redrawn accordingly +status+answerBand)。
Registered problems are output directly (-B does not write bytecode; if no path is passed, it writes to the skill output by default, and when delivering to the user be sure to change it to the .html):
python3 -B scripts/generate.py list # 列出题型
python3 -B scripts/generate.py ellipse_dot_range ./sol.html
python3 -B scripts/generate.py all ./out_dir # 全部题型
Step 4: Self-check (correctness plan)
- kernel answer == answer card
lesson.answer== last-step displayed value == JS standard-position/segment-scan recomputed value, all four consistent (build_*already includesassert)。 rangeBarThe endpoint comes from the kernel'srange_over_m;constantvalue comes from the kernel's fixed value.- Start a local static server (servethe directory containing the output file, i.e. cwd) and use preview to check: no console errors, KaTeX works,
slider real-time recalculation is correct, range bar/fixed value/fixed point/trace behavior matches, brush and collapse panel work.
(When developing inside the skill repository you can use
.claude/launch.json'sag-preview, port 4601; if running elsewhere, start a temporary static server on cwd.) - Self-check screenshots are for your eyes only: the preview tool returns images directly,do not save
.pngto cwd; the local static server is read-only and does not write, it produces no files. Any temporary files produced by the self-check (build script.py, screenshot.png、__pycache__, etc.) must all be cleaned up before delivery.
⚠️ You must close any ports/services you opened: stop them immediately once the preview ends,never leave a process occupying a port。
- Opened by the preview tool:
preview_stop(pass serverId).- Started directly with
http.server: when done usekill, orlsof -nP -iTCP:<port> -sTCP:LISTENto confirm it has been released.- Before delivery, confirm the port has been released before telling the user. Opening without closing = self-check not complete.
Step 5: Delivery
The finished product is written inthe user's current working directory (cwd), named like solution-<题目简述>.html, tell the user the path,
it can be opened directly in a browser. Before delivery confirm:(1) The finished product is in cwd, not in the skill directory;(2) No local services/ports opened for this preview
are left behind;(3) In cwdonly this one .htmlwas added—no .py / .png /
__pycache__ / temporary files (use git status or ls to check; delete any you find).
Extension
- Add a problem type: in
analytic_kernel.pyadd the target quantity function (written as an expression in m) + reuserange_over_m/is_constant_in_m; ingenerate.pyadd abuild_*, choose the interaction paradigm (range bar / fixed value / fixed point / trace / shape parameter answerBand). Seereferences/conventions.mdrecipe table. - Add a curve:
conics.pyalready has ellipse/hyperbola/parabola/circle; the frontendboard.htmlengine already supports four types of rendering, asymptotes, and directrix direction. A new curve only needs to be added in two places. - Add an interactive construction:
board.html'sbuildSceneswitch is the construction library (line_through_angle、intersect_line_conic、point_on_conic、point_reflect、tangent_at、foot_perp…), extend as needed and register it in the schema documentation.
Directory
template/board.html— data-driven template (general 2D renderer + parameter engine + data island__LESSON_DATA__)lib/conics.py— conic section sympy definition library (special points / LaTeX / board dict)lib/analytic_kernel.py— sympy exact solving core (simultaneous equations · Vieta · range · fixed value)scripts/generate.py— injection template + 6 build_* examples + batch/single problem generationreferences/problem-schema.md— data format (board engine schema)references/conventions.md— standard forms, solution recipe table, Vieta/substitution patterns, endpoint open/closed, self-check