- 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.
142 lines
7.8 KiB
HTML
142 lines
7.8 KiB
HTML
<section class="module" id="module-1">
|
||
<div class="module-inner">
|
||
<p class="eyebrow animate-in">模块 1 · 问数入口</p>
|
||
<h1 class="module-title animate-in">问数工作台 vs 分析对话<br>两套门,别走错</h1>
|
||
<p class="module-lead animate-in">
|
||
数据分析 Agent 走<strong>平台鉴权</strong>(<code>get_platform_auth_context</code>),
|
||
和对话线不同——<strong>不要</strong>带 <span class="term" data-definition="HTTP 请求头,声明本次请求走哪条 Agent 业务线(customer/advisor/risk/analyst)。问数 API 故意不需要它。">X-Agent-Type</span>。
|
||
像进档案室查账:只出示工牌(JWT),不用说明「我是来聊天还是来问数」。
|
||
</p>
|
||
|
||
<div class="screen animate-in">
|
||
<h2>前端两条菜单</h2>
|
||
<div class="pattern-cards">
|
||
<div class="pattern-card">
|
||
<h3>问数工作台</h3>
|
||
<p><code>/app/analytics/query</code> → <code>AnalystQueryPage</code><br>
|
||
真·NL→SQL:表格 + SQL + 解读,调 <code>POST /api/analyst/chat</code></p>
|
||
</div>
|
||
<div class="pattern-card">
|
||
<h3>分析对话(占位)</h3>
|
||
<p><code>/app/analytics/chat</code> → <code>AnalystChatShell</code><br>
|
||
横幅写明「轻量对话占位;查数请用问数工作台」——还没接独立问数图</p>
|
||
</div>
|
||
</div>
|
||
<div class="callout callout-accent">
|
||
<strong>指挥 AI 改功能时:</strong> 要表格和 SQL 就改 <code>analyst.py</code> / <code>analyst_agent.py</code>;
|
||
要聊天体验才碰 <code>analytics/chat</code> 占位页,别和问数混成一个接口。
|
||
</div>
|
||
<div class="callout callout-warning">
|
||
<strong>customer self 域:</strong> 客户 token 进问数 → <code>domain=self</code>,
|
||
<code>sql_guard</code> 强制 SQL 带本人 <code>customer_id</code>;免责声明追加 <code>CUSTOMER_AI_RISK_NOTE</code>。
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screen animate-in">
|
||
<h2>后端「四件套」路由</h2>
|
||
<p>全部挂在 <code>app/api/analyst.py</code>,前缀 <code>/api/analyst</code>:</p>
|
||
<div class="file-tree animate-in">
|
||
<div class="tree-item tree-folder">POST /chat</div>
|
||
<div class="tree-item tree-indent">问数主入口 → AnalystAgent.run()</div>
|
||
<div class="tree-item tree-folder">GET /dashboard</div>
|
||
<div class="tree-item tree-indent">智能看板卡片(按角色返回 metrics)</div>
|
||
<div class="tree-item tree-folder">POST /assets</div>
|
||
<div class="tree-item tree-indent">口径/样例沉淀(仅 analyst 角色可写)</div>
|
||
<div class="tree-item tree-folder">GET /ops/metrics</div>
|
||
<div class="tree-item tree-indent">运营指标:查询总量 / 被拦截次数</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screen animate-in">
|
||
<h2>群聊:分析员点「提问」之后</h2>
|
||
<p>STAFF-20001 在问数工作台输入「客户总数是多少」——简化版:</p>
|
||
|
||
<div class="chat-window" id="chat-analyst-m1">
|
||
<div class="chat-messages">
|
||
<div class="chat-message" data-msg="0" data-sender="browser" style="display:none">
|
||
<div class="chat-avatar" style="background:#2A7B9B">前</div>
|
||
<div class="chat-bubble">
|
||
<span class="chat-sender" style="color:#2A7B9B">AnalystQueryPage</span>
|
||
<p>POST /api/analyst/chat · 只带 Bearer JWT(无 X-Agent-Type)</p>
|
||
</div>
|
||
</div>
|
||
<div class="chat-message" data-msg="1" data-sender="api" style="display:none">
|
||
<div class="chat-avatar" style="background:#5A9DB8">API</div>
|
||
<div class="chat-bubble">
|
||
<span class="chat-sender" style="color:#5A9DB8">analyst.py</span>
|
||
<p>get_platform_auth_context → analyst_auth_from_deps</p>
|
||
</div>
|
||
</div>
|
||
<div class="chat-message" data-msg="2" data-sender="agent" style="display:none">
|
||
<div class="chat-avatar" style="background:#1F6280">Agent</div>
|
||
<div class="chat-bubble">
|
||
<span class="chat-sender" style="color:#1F6280">AnalystAgent</span>
|
||
<p>消歧 → 生成 SQL → sql_guard → 执行 → 解读</p>
|
||
</div>
|
||
</div>
|
||
<div class="chat-message" data-msg="3" data-sender="browser" style="display:none">
|
||
<div class="chat-avatar" style="background:#2A7B9B">前</div>
|
||
<div class="chat-bubble">
|
||
<span class="chat-sender" style="color:#2A7B9B">表格 + answer</span>
|
||
<p>Ant Design Table 渲染 columns/rows;折叠面板展示 SQL</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="chat-typing" id="chat-analyst-m1-typing" style="display:none">
|
||
<div class="chat-avatar" id="chat-analyst-m1-typing-avatar">…</div>
|
||
<div class="chat-typing-dots"><span class="typing-dot"></span><span class="typing-dot"></span><span class="typing-dot"></span></div>
|
||
</div>
|
||
<div class="chat-controls">
|
||
<button class="btn chat-next-btn">下一条</button>
|
||
<button class="btn chat-all-btn">全部播放</button>
|
||
<button class="btn chat-reset-btn">重播</button>
|
||
<span class="chat-progress"></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screen animate-in">
|
||
<div class="translation-block">
|
||
<div class="translation-code">
|
||
<span class="translation-label">前端 · analyst.ts</span>
|
||
<pre><code><span class="code-line"><span class="code-keyword">await</span> apiFetch(<span class="code-string">'/api/analyst/chat'</span>, {</span>
|
||
<span class="code-line"> method: <span class="code-string">'POST'</span>,</span>
|
||
<span class="code-line"> token, <span class="code-comment">// Bearer JWT only</span></span>
|
||
<span class="code-line"> body: JSON.stringify({ question, session_id }),</span>
|
||
<span class="code-line">})</span></code></pre>
|
||
</div>
|
||
<div class="translation-english">
|
||
<span class="translation-label">白话</span>
|
||
<div class="translation-lines">
|
||
<p class="tl">问数和读持仓一样:登录令牌够了,不用声明 Agent 类型。</p>
|
||
<p class="tl">后端用角色(analyst/advisor/customer…)决定能查哪片数据域,不靠 X-Agent-Type。</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="quiz-container" id="quiz-analyst-m1">
|
||
<div class="quiz-question-block"
|
||
data-correct="option-b"
|
||
data-explanation-right="对。/api/analyst/* 走平台鉴权,apiFetch 只传 token,不传 agentType。"
|
||
data-explanation-wrong="X-Agent-Type 是对话线和部分风控 REST 用的。问数故意不走那条门禁。">
|
||
<h3 class="quiz-question">问数工作台调 POST /api/analyst/chat,请求头要带 X-Agent-Type: analyst 吗?</h3>
|
||
<div class="quiz-options">
|
||
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
|
||
<div class="quiz-option-radio"></div><span>要,和 chat 线一样</span>
|
||
</button>
|
||
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
|
||
<div class="quiz-option-radio"></div><span>不要,只带 Bearer JWT</span>
|
||
</button>
|
||
<button class="quiz-option" data-value="option-c" onclick="selectOption(this)">
|
||
<div class="quiz-option-radio"></div><span>只有 dashboard 不要,chat 要</span>
|
||
</button>
|
||
</div>
|
||
<div class="quiz-feedback"></div>
|
||
</div>
|
||
<button class="quiz-check-btn" onclick="checkQuiz('quiz-analyst-m1')">检查答案</button>
|
||
<button class="quiz-reset-btn" onclick="resetQuiz('quiz-analyst-m1')">重做</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|