12 changed files with 490 additions and 136 deletions
-1
View File
@@ -195,7 +195,6 @@ async def classify_advisor_intent(
{"role": "user", "content": prompt}, {"role": "user", "content": prompt},
], ],
temperature=0, temperature=0,
max_tokens=120,
), ),
timeout=timeout, timeout=timeout,
) )
+27 -23
View File
@@ -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="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="avatar navlink" onclick="navTo('screen-account')">李</div></div>
<div class="section" style="padding-bottom:0"> <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> <h1 style="font-size:34px;font-weight:600;color:var(--navy)">用户中心</h1>
<div class="xs muted mt8">139****0041</div>
</div> </div>
<div class="section" style="padding-top:20px"> <div class="section" style="padding-top:20px">
<div class="grid g4"> <div class="row between" style="margin-bottom:16px">
<div class="card stat"><div class="label">总资产</div> <span class="navlink xs" onclick="navTo('screen-home')">← 返回首页</span>
<div class="value">¥ 1,284,600</div><div class="sub">较昨日 +0.42%</div></div> <button class="btn btn-sm">刷新账户数据</button></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="grid g3">
<div class="card stat"><div class="label">风险等级</div> <div class="card stat" style="background:var(--navy);border-color:var(--navy)">
<div class="value">C3</div><div class="sub">稳健型</div></div> <div class="label" style="color:#bfdbfe">账户余额</div>
<div class="card stat"><div class="label">待办</div> <div class="value" style="color:#fff">¥0.00</div>
<div class="value">2</div><div class="sub">风险测评待更新</div></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>
<div class="grid g2 mt16"> <div class="grid g2 mt16">
<div class="card"><div class="card-head"><div> <div class="card"><div class="card-head"><div>
<div class="card-title">我的持仓</div><div class="card-desc">按市值排序</div></div> <div class="card-title">我的持仓</div>
<button class="btn btn-sm btn-ghost">刷新</button></div> <div class="card-desc">点击任一行查看该基金详情</div></div></div>
<div class="table-wrap"><table> <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> <tbody>
<tr><td>华夏成长混合</td><td>12,400.00</td><td>¥ 27,081</td><td class="up">+12.4%</td></tr> <tr class="navlink" onclick="navTo('screen-detail')">
<tr><td>华夏复兴股票</td><td>5,200.00</td><td>¥ 15,818</td><td class="down">-3.1%</td></tr> <td><div class="b sm">XX沪港深灵活配置</div>
<tr><td>华夏稳健债券</td><td>30,000.00</td><td>¥ 39,780</td><td class="up">+2.6%</td></tr> <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> </tbody></table></div></div>
<div class="card"><div class="card-head"><div> <div class="card"><div class="card-head"><div>
<div class="card-title">快捷操作</div></div></div> <div class="card-title">快捷操作</div></div></div>
<div class="card-body"> <div class="card-body">
<div class="row wrap"> <div class="row wrap">
<button class="btn btn-primary">申购</button><button class="btn">赎回</button> <button class="btn btn-primary">申购基金</button><button class="btn">赎回基金</button></div>
<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>
<div class="mt16 b sm">交易记录</div> <div class="mt16 b sm">交易记录</div>
<div class="xs muted mt8">· 09-12 申购 华夏稳健债券 ¥ 10,000</div> <div class="xs muted mt8">当前后端暂未提供交易记录查询接口,页面不会展示虚构数据。</div>
<div class="xs muted">· 09-05 赎回 华夏复兴股票 1,000 份</div> <div class="mt16 b sm">消息通知</div>
<div class="xs muted mt8">当前后端暂未提供用户消息查询接口。</div>
</div></div> </div></div>
</div> </div>
</div> </div>
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,7 +1,7 @@
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts"; import "./.next/dev/types/routes.d.ts";
import "./.next/types/root-params.d.ts"; import "./.next/dev/types/root-params.d.ts";
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
-84
View File
@@ -157,9 +157,6 @@
"cpu": [ "cpu": [
"arm" "arm"
], ],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"optional": true, "optional": true,
"os": [ "os": [
@@ -176,9 +173,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"optional": true, "optional": true,
"os": [ "os": [
@@ -195,9 +189,6 @@
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"optional": true, "optional": true,
"os": [ "os": [
@@ -214,9 +205,6 @@
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"optional": true, "optional": true,
"os": [ "os": [
@@ -233,9 +221,6 @@
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"optional": true, "optional": true,
"os": [ "os": [
@@ -252,9 +237,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"libc": [
"glibc"
],
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"optional": true, "optional": true,
"os": [ "os": [
@@ -271,9 +253,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"libc": [
"musl"
],
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"optional": true, "optional": true,
"os": [ "os": [
@@ -290,9 +269,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"libc": [
"musl"
],
"license": "LGPL-3.0-or-later", "license": "LGPL-3.0-or-later",
"optional": true, "optional": true,
"os": [ "os": [
@@ -309,9 +285,6 @@
"cpu": [ "cpu": [
"arm" "arm"
], ],
"libc": [
"glibc"
],
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -334,9 +307,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"libc": [
"glibc"
],
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -359,9 +329,6 @@
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
"libc": [
"glibc"
],
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -384,9 +351,6 @@
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
"libc": [
"glibc"
],
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -409,9 +373,6 @@
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
"libc": [
"glibc"
],
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -434,9 +395,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"libc": [
"glibc"
],
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -459,9 +417,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"libc": [
"musl"
],
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -484,9 +439,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"libc": [
"musl"
],
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -689,9 +641,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -708,9 +657,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -727,9 +673,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -746,9 +689,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -932,9 +872,6 @@
"arm64" "arm64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -952,9 +889,6 @@
"arm64" "arm64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -972,9 +906,6 @@
"x64" "x64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -992,9 +923,6 @@
"x64" "x64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -1341,9 +1269,6 @@
"arm64" "arm64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0", "license": "MPL-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -1365,9 +1290,6 @@
"arm64" "arm64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0", "license": "MPL-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -1389,9 +1311,6 @@
"x64" "x64"
], ],
"dev": true, "dev": true,
"libc": [
"glibc"
],
"license": "MPL-2.0", "license": "MPL-2.0",
"optional": true, "optional": true,
"os": [ "os": [
@@ -1413,9 +1332,6 @@
"x64" "x64"
], ],
"dev": true, "dev": true,
"libc": [
"musl"
],
"license": "MPL-2.0", "license": "MPL-2.0",
"optional": true, "optional": true,
"os": [ "os": [
-1
View File
@@ -106,7 +106,6 @@ async def rewrite_query(
{"role": "user", "content": prompt}, {"role": "user", "content": prompt},
], ],
temperature=0, temperature=0,
max_tokens=512,
) )
except Exception: # noqa: BLE001 改写失败不阻断原查询 except Exception: # noqa: BLE001 改写失败不阻断原查询
logger.warning("NL2SQL 查询问题改写失败,继续使用原问题", exc_info=True) logger.warning("NL2SQL 查询问题改写失败,继续使用原问题", exc_info=True)
-1
View File
@@ -67,7 +67,6 @@ async def render_answer(
{"role": "user", "content": prompt}, {"role": "user", "content": prompt},
], ],
temperature=0, temperature=0,
max_tokens=256,
) )
except Exception: # noqa: BLE001 摘要失败回退固定文本 except Exception: # noqa: BLE001 摘要失败回退固定文本
return fallback return fallback
+1 -1
View File
@@ -74,7 +74,7 @@ async def generate_sql(
}, },
] ]
try: 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 统一收敛模型异常 except Exception as exc: # noqa: BLE001 统一收敛模型异常
raise SqlGenerationError("SQL 模型调用失败") from exc raise SqlGenerationError("SQL 模型调用失败") from exc
sql = _clean_model_output(output) sql = _clean_model_output(output)
+3
View File
@@ -20,6 +20,7 @@ class Intent(StrEnum):
COMPANY_INFO = "company_info" COMPANY_INFO = "company_info"
CHITCHAT = "chitchat" CHITCHAT = "chitchat"
OFF_TOPIC = "off_topic" OFF_TOPIC = "off_topic"
TRANSFER_HUMAN = "transfer_human"
NO_MATCH = "no_match" NO_MATCH = "no_match"
@@ -61,6 +62,8 @@ INTENT_SYSTEM_PROMPT = (
"- chitchat: 普通寒暄,如问候、致谢、告别、询问你是谁/你能做什么、在吗等一两句话的闲聊\n" "- chitchat: 普通寒暄,如问候、致谢、告别、询问你是谁/你能做什么、在吗等一两句话的闲聊\n"
"- off_topic: 用户要求你实质性地处理与金融、基金、公司业务无关的事情," "- off_topic: 用户要求你实质性地处理与金融、基金、公司业务无关的事情,"
"如写代码、讲笑话、写作文、问天气、聊政治、情感咨询、做数学题等\n" "如写代码、讲笑话、写作文、问天气、聊政治、情感咨询、做数学题等\n"
"- transfer_human: 用户明确要求转接人工客服,或表达不满、投诉、对智能客服不信任,"
"希望由真人处理,如“转人工”“找人工客服”“我要投诉”“人工服务”“我要见真人”“别跟我说废话找客服”等\n"
"- no_match: 无法归入以上任何一类\n" "- no_match: 无法归入以上任何一类\n"
"注意:寒暄性质的一两句话归为 chitchat;一旦用户提出金融之外的实质性请求,归为 off_topic。\n" "注意:寒暄性质的一两句话归为 chitchat;一旦用户提出金融之外的实质性请求,归为 off_topic。\n"
"只输出一行 JSON,格式:{\"intent\": \"<小写英文标签>\", \"query\": \"<完整问题>\"}," "只输出一行 JSON,格式:{\"intent\": \"<小写英文标签>\", \"query\": \"<完整问题>\"},"
-1
View File
@@ -18,7 +18,6 @@ async def check() -> None:
{"role": "user", "content": "只回复:连接正常"}, {"role": "user", "content": "只回复:连接正常"},
], ],
temperature=0, temperature=0,
max_tokens=16,
) )
print("chat: ok", answer[:32]) print("chat: ok", answer[:32])
except Exception as exc: except Exception as exc:
+1 -1
View File
@@ -42,7 +42,7 @@ source 只能是 dialogue_confirmed、dialogue_stated、dialogue_inferred。
) )
interest_signal = self._interest_fallback(query) interest_signal = self._interest_fallback(query)
try: 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) result = self._parse(response)
except Exception: except Exception:
if interest_signal: if interest_signal:
+7
View File
@@ -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: elif intent == Intent.CHITCHAT:
answer = await self._chitchat(session_id) answer = await self._chitchat(session_id)
elif intent == Intent.NL2SQL_REQUEST: elif intent == Intent.NL2SQL_REQUEST: