- Added `ThresholdRepository` for managing customer loss threshold configurations and notifications. - Introduced `threshold_service` to handle loss threshold alerts based on customer portfolio performance. - Enhanced `customer_prompts` to include new intent for querying product net values. - Updated `customer_service` to integrate new threshold alert functionality into existing workflows. - Implemented `sanitize_postprocess` for improved compliance handling in customer interactions. - Enhanced course documentation to reflect updates in advisor training modules and interactive elements. This update significantly improves the customer experience by providing proactive loss threshold notifications and enhancing the overall service framework.
108 lines
6.8 KiB
HTML
108 lines
6.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">客户能做什么?<br>从 SSE 对话到 Core 只读</h1>
|
||
<p class="module-lead animate-in">
|
||
登录客户(如 <code>CUST-9527</code>)打开「客户助手」后,可走<strong>同步</strong>或
|
||
<span class="term" data-definition="SSE = Server-Sent Events,服务器像打字一样一段段把回复推给浏览器,不用等整段话生成完。">SSE 流式</span>
|
||
对话。未登录访客另有<strong>游客试聊</strong>(只 RAG、不查持仓)。
|
||
2026-09 <code>merger</code> 分支:客户线 SSE 已接通,测试基线 **786 passed**。
|
||
</p>
|
||
|
||
<div class="screen animate-in">
|
||
<h2>四条能力线(指挥 AI 改功能前先对齐)</h2>
|
||
<div class="pattern-cards">
|
||
<div class="pattern-card">
|
||
<h3>对话 SSE / 同步</h3>
|
||
<p><code>POST /api/chat/stream</code> 或 <code>POST /api/chat</code>,请求头 <code>X-Agent-Type: customer</code> + Bearer JWT。</p>
|
||
</div>
|
||
<div class="pattern-card">
|
||
<h3>持仓 / 流水 / 风评 / 净值</h3>
|
||
<p>意图命中后走 Core 模拟库只读查询 Tool(<code>core_ro_tool.py</code>);含 C-05 最新净值(非实时);C-04 查持仓时可 inline 阈值提醒。</p>
|
||
</div>
|
||
<div class="pattern-card">
|
||
<h3>产品规则 RAG</h3>
|
||
<p><code>fin_*</code> 知识库(Milvus)回答申购赎回、费率等产品咨询;画像语境注入但不泄露敏感字段。</p>
|
||
</div>
|
||
<div class="pattern-card">
|
||
<h3>游客试聊</h3>
|
||
<p><code>POST /api/chat/visitor</code> 免登录,游客试聊 9 节点编排(<code>visitor_service.py</code>),不写客户会话表。</p>
|
||
</div>
|
||
</div>
|
||
<div class="callout callout-accent">
|
||
<strong>和理财师线的区别:</strong> 客户线走登录客户 14 节点 LangGraph 编排(<code>customer_service.py</code>),<strong>不走</strong> 顾问通用 tool→llm→guard 编排(<code>agent_service.py</code>)。
|
||
</div>
|
||
</div>
|
||
|
||
<div class="screen animate-in">
|
||
<h2>数据流:浏览器问「我持仓多少」</h2>
|
||
<p>客户发消息后,四 Agent 对话 HTTP 入口(<code>chat.py</code>)按 <code>X-Agent-Type</code> 分流到客户编排,再查 Core。</p>
|
||
|
||
<div class="flow-animation" data-steps='[
|
||
{"highlight":"flow-actor-1","label":"浏览器:ChatPanel 带 JWT + X-Agent-Type: customer"},
|
||
{"highlight":"flow-actor-2","label":"四 Agent 对话 HTTP 入口(chat.py):鉴权、建 session、分流 customer 分支","packet":true,"from":"1","to":"2"},
|
||
{"highlight":"flow-actor-3","label":"customer_service:意图→tool_call→interpret(数值来自 Core)","packet":true,"from":"2","to":"3"},
|
||
{"highlight":"flow-actor-4","label":"Core 只读查询 Tool(core_ro_tool.py):SQL 只读 + fact_text 脱敏模板","packet":true,"from":"3","to":"4"},
|
||
{"highlight":"flow-actor-1","label":"SSE 分块推送完整回复 + MySQL 落会话","packet":true,"from":"4","to":"1"}
|
||
]'>
|
||
<div class="flow-actors">
|
||
<div class="flow-actor" id="flow-actor-1"><span class="flow-actor-icon">🖥</span><span>浏览器</span></div>
|
||
<div class="flow-actor" id="flow-actor-2"><span class="flow-actor-icon">🚪</span><span>对话 HTTP 入口(chat.py)</span></div>
|
||
<div class="flow-actor" id="flow-actor-3"><span class="flow-actor-icon">🤖</span><span>customer_service</span></div>
|
||
<div class="flow-actor" id="flow-actor-4"><span class="flow-actor-icon">🗄</span><span>core_ro_tool</span></div>
|
||
</div>
|
||
<p class="flow-step-label">点击「下一步」看请求怎么走</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">
|
||
<div class="translation-block">
|
||
<div class="translation-code">
|
||
<span class="translation-label">入口 · 四 Agent 对话 HTTP 入口(chat.py)</span>
|
||
<pre><code><span class="code-line"><span class="code-keyword">if</span> agent_type == <span class="code-string">"customer"</span>:</span>
|
||
<span class="code-line"> host_ctx = host_auth_for_customer_service(auth, trace_id=trace_id)</span>
|
||
<span class="code-line"> customer_prep = prepare_customer_stream(</span>
|
||
<span class="code-line"> host_ctx, message, sid, cust_id, req.end_session</span>
|
||
<span class="code-line"> )</span>
|
||
<span class="code-line"> <span class="code-comment"># 图跑完后按 chunks 推 SSE</span></span></code></pre>
|
||
</div>
|
||
<div class="translation-english">
|
||
<span class="translation-label">白话</span>
|
||
<div class="translation-lines">
|
||
<p class="tl">看到 customer 就换轨道:不进 agent_service,改走客户专用编排。</p>
|
||
<p class="tl">先把 JWT 转成 customer_service 认识的 AuthContext(字段名对齐)。</p>
|
||
<p class="tl">流式路径:LangGraph 整图跑完,再把回复切成块推给前端——Tool/RAG 仍是同步完成。</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="quiz-container" id="quiz-customer-m1">
|
||
<div class="quiz-question-block"
|
||
data-correct="option-b"
|
||
data-explanation-right="对。游客走 /api/chat/visitor + visitor_service,免 JWT,不查持仓/流水。"
|
||
data-explanation-wrong="游客试聊和登录客户是两条线:无 JWT、无 Core 客户数据查询。">
|
||
<h3 class="quiz-question">未登录访客在首页试聊,会查到自己的持仓吗?</h3>
|
||
<div class="quiz-options">
|
||
<button class="quiz-option" data-value="option-a" onclick="selectOption(this)">
|
||
<div class="quiz-option-radio"></div><span>会,走同一套 customer_service</span>
|
||
</button>
|
||
<button class="quiz-option" data-value="option-b" onclick="selectOption(this)">
|
||
<div class="quiz-option-radio"></div><span>不会,只 RAG + 闲聊,无客户数据</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-customer-m1')">检查答案</button>
|
||
<button class="quiz-reset-btn" onclick="resetQuiz('quiz-customer-m1')">重做</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|