Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
433cc22667 | ||
|
|
75c7b2e6f3 | ||
|
|
102cae6692 | ||
|
|
177a28b1de |
@@ -195,7 +195,6 @@ async def classify_advisor_intent(
|
||||
{"role": "user", "content": prompt},
|
||||
],
|
||||
temperature=0,
|
||||
max_tokens=120,
|
||||
),
|
||||
timeout=timeout,
|
||||
)
|
||||
@@ -221,4 +220,4 @@ async def classify_advisor_intent(
|
||||
return _rule_fallback(query)
|
||||
|
||||
|
||||
__all__ = ["IntentClassification", "classify_advisor_intent", "resolve_advisor_intent"]
|
||||
__all__ = ["IntentClassification", "classify_advisor_intent", "resolve_advisor_intent"]
|
||||
+27
-23
@@ -612,45 +612,49 @@
|
||||
<div class="links"><span onclick="navTo('screen-home')">首页</span><span onclick="navTo('screen-products')">基金产品</span><span onclick="navTo('screen-account')">用户中心</span><span onclick="navTo('screen-admin')">员工工作台</span></div>
|
||||
<div class="avatar navlink" onclick="navTo('screen-account')">李</div></div>
|
||||
<div class="section" style="padding-bottom:0">
|
||||
<div class="xs faint">欢迎回来</div>
|
||||
<div class="xs faint">Personal Account</div>
|
||||
<h1 style="font-size:34px;font-weight:600;color:var(--navy)">用户中心</h1>
|
||||
<div class="xs muted mt8">139****0041</div>
|
||||
</div>
|
||||
<div class="section" style="padding-top:20px">
|
||||
<div class="grid g4">
|
||||
<div class="card stat"><div class="label">总资产</div>
|
||||
<div class="value">¥ 1,284,600</div><div class="sub">较昨日 +0.42%</div></div>
|
||||
<div class="card stat"><div class="label">持仓收益</div>
|
||||
<div class="value up">+¥ 86,240</div><div class="sub">收益率 +7.19%</div></div>
|
||||
<div class="card stat"><div class="label">风险等级</div>
|
||||
<div class="value">C3</div><div class="sub">稳健型</div></div>
|
||||
<div class="card stat"><div class="label">待办</div>
|
||||
<div class="value">2</div><div class="sub">风险测评待更新</div></div>
|
||||
<div class="row between" style="margin-bottom:16px">
|
||||
<span class="navlink xs" onclick="navTo('screen-home')">← 返回首页</span>
|
||||
<button class="btn btn-sm">刷新账户数据</button></div>
|
||||
|
||||
<div class="grid g3">
|
||||
<div class="card stat" style="background:var(--navy);border-color:var(--navy)">
|
||||
<div class="label" style="color:#bfdbfe">账户余额</div>
|
||||
<div class="value" style="color:#fff">¥0.00</div>
|
||||
<div class="sub" style="color:#93c5fd">该账户暂无余额记录</div></div>
|
||||
<div class="card stat"><div class="label">持仓总金额</div>
|
||||
<div class="value">¥6,740.45</div><div class="sub">共 1 只基金</div></div>
|
||||
<div class="card stat"><div class="label">风险测评</div>
|
||||
<div class="value" style="font-size:19px">待完成测评</div>
|
||||
<div class="sub">当前后端仅提供提交接口</div></div>
|
||||
</div>
|
||||
|
||||
<div class="grid g2 mt16">
|
||||
<div class="card"><div class="card-head"><div>
|
||||
<div class="card-title">我的持仓</div><div class="card-desc">按市值排序</div></div>
|
||||
<button class="btn btn-sm btn-ghost">刷新</button></div>
|
||||
<div class="card-title">我的持仓</div>
|
||||
<div class="card-desc">点击任一行查看该基金详情</div></div></div>
|
||||
<div class="table-wrap"><table>
|
||||
<thead><tr><th>基金</th><th>持有份额</th><th>市值</th><th>收益</th></tr></thead>
|
||||
<thead><tr><th>基金</th><th>持有份额</th><th>市值</th><th>盈亏</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>华夏成长混合</td><td>12,400.00</td><td>¥ 27,081</td><td class="up">+12.4%</td></tr>
|
||||
<tr><td>华夏复兴股票</td><td>5,200.00</td><td>¥ 15,818</td><td class="down">-3.1%</td></tr>
|
||||
<tr><td>华夏稳健债券</td><td>30,000.00</td><td>¥ 39,780</td><td class="up">+2.6%</td></tr>
|
||||
<tr class="navlink" onclick="navTo('screen-detail')">
|
||||
<td><div class="b sm">XX沪港深灵活配置</div>
|
||||
<div class="xs faint">110011 · R4</div></td>
|
||||
<td>3,910.0000</td><td>¥6,740.45</td><td class="down">-10.11</td></tr>
|
||||
</tbody></table></div></div>
|
||||
|
||||
<div class="card"><div class="card-head"><div>
|
||||
<div class="card-title">快捷操作</div></div></div>
|
||||
<div class="card-body">
|
||||
<div class="row wrap">
|
||||
<button class="btn btn-primary">申购</button><button class="btn">赎回</button>
|
||||
<button class="btn">转换</button><button class="btn">重新测评</button></div>
|
||||
<div class="mt16 b sm">消息通知</div>
|
||||
<div class="xs muted mt8">· 您的风险测评将于 30 天后过期</div>
|
||||
<div class="xs muted">· 华夏成长混合 09-13 净值已更新</div>
|
||||
<button class="btn btn-primary">申购基金</button><button class="btn">赎回基金</button></div>
|
||||
<div class="mt16 b sm">交易记录</div>
|
||||
<div class="xs muted mt8">· 09-12 申购 华夏稳健债券 ¥ 10,000</div>
|
||||
<div class="xs muted">· 09-05 赎回 华夏复兴股票 1,000 份</div>
|
||||
<div class="xs muted mt8">当前后端暂未提供交易记录查询接口,页面不会展示虚构数据。</div>
|
||||
<div class="mt16 b sm">消息通知</div>
|
||||
<div class="xs muted mt8">当前后端暂未提供用户消息查询接口。</div>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+441
-13
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -1,7 +1,7 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import "./.next/types/routes.d.ts";
|
||||
import "./.next/types/root-params.d.ts";
|
||||
import "./.next/dev/types/routes.d.ts";
|
||||
import "./.next/dev/types/root-params.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
||||
Generated
-84
@@ -157,9 +157,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -176,9 +173,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -195,9 +189,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -214,9 +205,6 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -233,9 +221,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -252,9 +237,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -271,9 +253,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -290,9 +269,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -309,9 +285,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -334,9 +307,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -359,9 +329,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -384,9 +351,6 @@
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -409,9 +373,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -434,9 +395,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -459,9 +417,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -484,9 +439,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -689,9 +641,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -708,9 +657,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -727,9 +673,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -746,9 +689,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -932,9 +872,6 @@
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -952,9 +889,6 @@
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -972,9 +906,6 @@
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -992,9 +923,6 @@
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1341,9 +1269,6 @@
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1365,9 +1290,6 @@
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1389,9 +1311,6 @@
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1413,9 +1332,6 @@
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
||||
@@ -106,7 +106,6 @@ async def rewrite_query(
|
||||
{"role": "user", "content": prompt},
|
||||
],
|
||||
temperature=0,
|
||||
max_tokens=512,
|
||||
)
|
||||
except Exception: # noqa: BLE001 改写失败不阻断原查询
|
||||
logger.warning("NL2SQL 查询问题改写失败,继续使用原问题", exc_info=True)
|
||||
@@ -115,4 +114,4 @@ async def rewrite_query(
|
||||
return value or original
|
||||
|
||||
|
||||
__all__ = ["rewrite_query"]
|
||||
__all__ = ["rewrite_query"]
|
||||
+1
-2
@@ -67,8 +67,7 @@ async def render_answer(
|
||||
{"role": "user", "content": prompt},
|
||||
],
|
||||
temperature=0,
|
||||
max_tokens=256,
|
||||
)
|
||||
except Exception: # noqa: BLE001 摘要失败回退固定文本
|
||||
return fallback
|
||||
return answer.strip() or fallback
|
||||
return answer.strip() or fallback
|
||||
+2
-2
@@ -74,7 +74,7 @@ async def generate_sql(
|
||||
},
|
||||
]
|
||||
try:
|
||||
output = await llm_client.chat(messages, temperature=0, max_tokens=256)
|
||||
output = await llm_client.chat(messages, temperature=0)
|
||||
except Exception as exc: # noqa: BLE001 统一收敛模型异常
|
||||
raise SqlGenerationError("SQL 模型调用失败") from exc
|
||||
sql = _clean_model_output(output)
|
||||
@@ -86,4 +86,4 @@ async def generate_sql(
|
||||
raise SqlGenerationError("模型返回的 SQL 无法解析") from exc
|
||||
if len(statements) != 1 or not isinstance(statements[0], exp.Select):
|
||||
raise SqlGenerationError("模型只允许返回单条 SELECT")
|
||||
return GeneratedSql(sql=statements[0].sql(dialect="mysql"))
|
||||
return GeneratedSql(sql=statements[0].sql(dialect="mysql"))
|
||||
+4
-1
@@ -20,6 +20,7 @@ class Intent(StrEnum):
|
||||
COMPANY_INFO = "company_info"
|
||||
CHITCHAT = "chitchat"
|
||||
OFF_TOPIC = "off_topic"
|
||||
TRANSFER_HUMAN = "transfer_human"
|
||||
NO_MATCH = "no_match"
|
||||
|
||||
|
||||
@@ -61,6 +62,8 @@ INTENT_SYSTEM_PROMPT = (
|
||||
"- chitchat: 普通寒暄,如问候、致谢、告别、询问你是谁/你能做什么、在吗等一两句话的闲聊\n"
|
||||
"- off_topic: 用户要求你实质性地处理与金融、基金、公司业务无关的事情,"
|
||||
"如写代码、讲笑话、写作文、问天气、聊政治、情感咨询、做数学题等\n"
|
||||
"- transfer_human: 用户明确要求转接人工客服,或表达不满、投诉、对智能客服不信任,"
|
||||
"希望由真人处理,如“转人工”“找人工客服”“我要投诉”“人工服务”“我要见真人”“别跟我说废话找客服”等\n"
|
||||
"- no_match: 无法归入以上任何一类\n"
|
||||
"注意:寒暄性质的一两句话归为 chitchat;一旦用户提出金融之外的实质性请求,归为 off_topic。\n"
|
||||
"只输出一行 JSON,格式:{\"intent\": \"<小写英文标签>\", \"query\": \"<完整问题>\"},"
|
||||
@@ -164,4 +167,4 @@ async def intent_recognize(
|
||||
except Exception:
|
||||
logger.exception("intent recognition failed")
|
||||
return IntentResult(Intent.NO_MATCH, query, bool(rendered))
|
||||
return parse_intent_result(raw, fallback_query=query, used_history=bool(rendered))
|
||||
return parse_intent_result(raw, fallback_query=query, used_history=bool(rendered))
|
||||
@@ -18,7 +18,6 @@ async def check() -> None:
|
||||
{"role": "user", "content": "只回复:连接正常"},
|
||||
],
|
||||
temperature=0,
|
||||
max_tokens=16,
|
||||
)
|
||||
print("chat: ok", answer[:32])
|
||||
except Exception as exc:
|
||||
@@ -32,4 +31,4 @@ async def check() -> None:
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(check())
|
||||
asyncio.run(check())
|
||||
@@ -42,7 +42,7 @@ source 只能是 dialogue_confirmed、dialogue_stated、dialogue_inferred。
|
||||
)
|
||||
interest_signal = self._interest_fallback(query)
|
||||
try:
|
||||
response = await self.llm_client.chat(prompt, temperature=0, max_tokens=800)
|
||||
response = await self.llm_client.chat(prompt, temperature=0)
|
||||
result = self._parse(response)
|
||||
except Exception:
|
||||
if interest_signal:
|
||||
@@ -123,4 +123,4 @@ source 只能是 dialogue_confirmed、dialogue_stated、dialogue_inferred。
|
||||
return result
|
||||
|
||||
|
||||
__all__ = ["DialogueMemoryExtractor"]
|
||||
__all__ = ["DialogueMemoryExtractor"]
|
||||
@@ -103,6 +103,13 @@ class AnonymousCustomerAgent:
|
||||
"我是华夏科技的智能客服,只能解答基金与公司业务相关的问题,"
|
||||
"您可以问我基金知识、开户流程或公司信息~",
|
||||
)
|
||||
elif intent == Intent.TRANSFER_HUMAN:
|
||||
answer = await _config(
|
||||
self.config_getter,
|
||||
"agent.customer.template.transfer_human",
|
||||
"好的,正在为您转接人工客服,请稍候。"
|
||||
"您也可以拨打官方客服热线 400-XXX-XXXX 直接联系我们。",
|
||||
)
|
||||
elif intent == Intent.CHITCHAT:
|
||||
answer = await self._chitchat(session_id)
|
||||
elif intent == Intent.NL2SQL_REQUEST:
|
||||
@@ -248,4 +255,4 @@ class AnonymousCustomerAgent:
|
||||
return bool(
|
||||
re.search(r"(?<!\d)1[3-9]\d{9}(?!\d)", query)
|
||||
or re.search(r"(?:客户|customer)[_ -]?(?:id|号)?\s*[::]?\s*[A-Za-z0-9_-]{4,}", query, re.I)
|
||||
)
|
||||
)
|
||||
Reference in New Issue
Block a user