Files
group_xinghuo_jinrong/docs/course/jinrong-module-analyst/modules/02-pipeline.html
T
zhanghongyu_0626 6f222f1c56 feat(course): Add course assembly script and module structure for advisor training
- Introduced `build_all.py` script to automate the assembly of course modules into a single `index.html` file.
- Created `index.html` for the main course overview, featuring a structured layout and navigation for various modules.
- Developed `_base.html` and `_footer.html` templates for the advisor module, ensuring consistent styling and structure.
- Added `build.sh` script for individual module assembly, enhancing modularity and ease of updates.
- Implemented multiple module HTML files detailing specific training scenarios and functionalities for advisors, including interactive elements and quizzes.

This update significantly enhances the course delivery framework, providing a comprehensive and interactive learning experience for advisors.
2026-09-09 23:22:59 +08:00

106 lines
6.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<section class="module" id="module-2">
<div class="module-inner">
<p class="eyebrow animate-in">模块 2 · NL→SQL 管线</p>
<h1 class="module-title animate-in">一句话怎么变成<br>可审计的表格?</h1>
<p class="module-lead animate-in">
<code>app/service/analyst_agent.py</code> 把用户问题拆成可测试步骤。
像<strong>翻译官 + 安检 + 记账员</strong>:先弄清指标含义,再生成 SQL,层层校验后才执行,最后解读并留痕。
</p>
<div class="screen animate-in">
<h2>七步流水线(动画)</h2>
<p>点击「下一步」看 <span class="term" data-definition="Natural Language to SQL:把自然语言问题翻译成数据库查询语句。">NL→SQL</span> 在代码里怎么走:</p>
<div class="flow-animation" data-steps='[
{"highlight":"flow-actor-1","label":"① 消歧:口径字典命中多义指标 → 返回 suggestions 让用户选"},
{"highlight":"flow-actor-2","label":"② 生成 SQL:DeepSeek + SCHEMA_PROMPT + 权限域提示","packet":true,"from":"1","to":"2"},
{"highlight":"flow-actor-3","label":"③ sql_guard 五层校验:只读 / 表白名单 / 行级归属…","packet":true,"from":"2","to":"3"},
{"highlight":"flow-actor-4","label":"④ 执行:AnalyticsRepo 只读查询(Redis 缓存可命中)","packet":true,"from":"3","to":"4"},
{"highlight":"flow-actor-5","label":"⑤ guardrail:解读数字必须与表格一致,不过则降级","packet":true,"from":"4","to":"5"},
{"highlight":"flow-actor-1","label":"⑥ 留痕:analytics_query_log 写入 SQL/耗时/护栏结果","packet":true,"from":"5","to":"1"}
]'>
<div class="flow-actors">
<div class="flow-actor" id="flow-actor-1"><span class="flow-actor-icon">📖</span><span>消歧 dict</span></div>
<div class="flow-actor" id="flow-actor-2"><span class="flow-actor-icon">🤖</span><span>LLM 生成</span></div>
<div class="flow-actor" id="flow-actor-3"><span class="flow-actor-icon">🛡</span><span>sql_guard</span></div>
<div class="flow-actor" id="flow-actor-4"><span class="flow-actor-icon">🗄</span><span>execute</span></div>
<div class="flow-actor" id="flow-actor-5"><span class="flow-actor-icon">✓</span><span>guardrail</span></div>
</div>
<p class="flow-step-label">校验失败 → 403 或 degrade(只给表格不给瞎编解读)</p>
<div class="flow-controls">
<button class="btn flow-next-btn">下一步</button>
<button class="btn flow-reset-btn">重来</button>
</div>
</div>
</div>
<div class="screen animate-in">
<h2>sql_guard 在拦什么</h2>
<div class="pattern-cards">
<div class="pattern-card">
<h3>只读白名单</h3>
<p>拒绝 INSERT/UPDATE/DELETE 等写操作关键字</p>
</div>
<div class="pattern-card">
<h3>表白名单</h3>
<p><code>core_*</code> + <code>risk_alert</code> 等,超出即 403</p>
</div>
<div class="pattern-card">
<h3>行级归属</h3>
<p>customer 域强制 <code>customer_id = 本人</code>;advisor 只能名下客户</p>
</div>
<div class="pattern-card">
<h3>粒度控制</h3>
<p>ops 聚合域禁止下钻到单个客户明细</p>
</div>
</div>
</div>
<div class="screen animate-in">
<div class="translation-block">
<div class="translation-code">
<span class="translation-label">CODE · analyst_agent.run</span>
<pre><code><span class="code-line">amb = self._detect_ambiguity(question)</span>
<span class="code-line"><span class="code-keyword">if</span> amb: <span class="code-keyword">return</span> self._clarify(amb, trace_id)</span>
<span class="code-line">sql_text, usage = self._generate_sql(...)</span>
<span class="code-line">vres = validate(sql_text, domain, scope) <span class="code-comment"># sql_guard</span></span>
<span class="code-line">exec_result = self.repo.execute_readonly(sql_text)</span>
<span class="code-line">answer, guard = self._generate_verified_answer(...)</span>
<span class="code-line">self._persist(...) <span class="code-comment"># analytics_query_log</span></span></code></pre>
</div>
<div class="translation-english">
<span class="translation-label">白话</span>
<div class="translation-lines">
<p class="tl">指标说不清就先反问,不瞎猜 SQL。</p>
<p class="tl">生成后必须过 sql_guard,执行只走只读连接。</p>
<p class="tl">AI 解读若数字对不上表,降级为「请看表格」;全程写入查询日志备查。</p>
</div>
</div>
</div>
<div class="quiz-container" id="quiz-analyst-m2">
<div class="quiz-question-block"
data-correct="option-c"
data-explanation-right="guardrail 不通过时 status=degrade:保留 table/sql,answer 换成安全文案。"
data-explanation-wrong="不会静默丢数据;表格是 ground truth,解读可被降级。">
<h3 class="quiz-question">数字护栏(guardrail)校验失败时,用户还能看到查询结果表格吗?</h3>
<div class="quiz-options">
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>不能,整单 500 错误</span>
</button>
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>能,但 SQL 会被隐藏</span>
</button>
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
<div class="quiz-option-radio"></div><span>能,解读降级为「以表格为准」</span>
</button>
</div>
<div class="quiz-feedback"></div>
</div>
<button class="quiz-check-btn" onclick="checkQuiz('quiz-analyst-m2')">检查答案</button>
<button class="quiz-reset-btn" onclick="resetQuiz('quiz-analyst-m2')">重做</button>
</div>
</div>
</div>
</section>