Skip to content

Commit 5ed3149

Browse files
committed
docs: add frontend chatbot presentation materials
1 parent 19c05b1 commit 5ed3149

19 files changed

Lines changed: 623 additions & 292 deletions

.env.example

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,12 @@ QI_POSTGRES_DSN=
3030
# DeepSeek API(本地网页 chatbot 使用)
3131
# 也可以在 config/app_config.json 中配置;环境变量优先级更高。
3232
DEEPSEEK_API_KEY=
33-
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
34-
DEEPSEEK_MODEL=deepseek-chat
35-
DEEPSEEK_TIMEOUT_SECONDS=30
33+
DEEPSEEK_BASE_URL=https://api.deepseek.com
34+
DEEPSEEK_MODEL=deepseek-v4-flash
35+
DEEPSEEK_TIMEOUT_SECONDS=60
36+
DEEPSEEK_THINKING_TYPE=enabled
37+
DEEPSEEK_REASONING_EFFORT=high
38+
DEEPSEEK_MAX_TOKENS=8192
3639

3740
# 本地网页文本覆盖(可选)
3841
CHATBOT_TITLE=Financial Chatbot by Group x

README.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ARIN Query Intelligence is the repository module responsible for query understan
55
- `nlu_result.json`: normalized query, product type, intent, topic, entities, missing slots, risk flags, evidence requirements, and source plan.
66
- `retrieval_result.json`: executed sources, document evidence, structured market/fundamental/macro data, coverage, warnings, and ranking/debug traces.
77

8-
This module does not generate the final chatbot answer and does not make investment conclusions. Downstream modules should consume the two JSON outputs for document learning, sentiment analysis, trend analysis, numerical feature computation, and response generation.
8+
The core Query Intelligence pipeline does not make investment conclusions. The repository also ships a local browser chatbot wrapper at `GET /` and `POST /chat`; that wrapper consumes the same NLU/Retrieval artifacts, calls DeepSeek for response polishing when configured, and falls back to a structured evidence summary when the model is unavailable.
99

1010
## Scope
1111

@@ -24,7 +24,7 @@ HK/US stocks and overseas products are not guaranteed by default. To support the
2424
Important boundary:
2525

2626
- Query Intelligence owns `nlu_result`, `retrieval_result`, source planning, retrieval evidence, and `analysis_summary`.
27-
- `sentiment/` and `scripts/llm_response.py` are downstream consumers. They may use `torch`, `transformers`, FinBERT, or local generation models, but they must not re-infer the user's intent, target entities, or retrieval source plan.
27+
- `sentiment/`, `scripts/llm_response.py`, and the `/chat` browser wrapper are downstream consumers. They may use `torch`, `transformers`, FinBERT, or remote/local generation models, but they must not re-infer the user's intent, target entities, or retrieval source plan.
2828

2929
## Quick Start
3030

@@ -37,6 +37,10 @@ python manual_test/run_manual_query.py
3737
# One-shot manual query
3838
python manual_test/run_manual_query.py --query "你觉得中国平安怎么样?"
3939

40+
# Start the local browser chatbot
41+
export DEEPSEEK_API_KEY="your_deepseek_api_key_here"
42+
python scripts/launch_chatbot.py
43+
4044
# Start FastAPI
4145
uvicorn query_intelligence.api.app:create_app --factory --host 0.0.0.0 --port 8000
4246

@@ -61,11 +65,35 @@ API code is in `query_intelligence/api/app.py`; request/response contracts are i
6165
| Endpoint | Purpose | Input | Output |
6266
|---|---|---|---|
6367
| `GET /health` | Health check | none | `{"status":"ok"}` |
68+
| `GET /` | Local browser chatbot UI | browser | HTML app |
69+
| `POST /chat` | End-to-end NLU + Retrieval + DeepSeek response polishing | `ChatRequest` | Chatbot response JSON |
6470
| `POST /nlu/analyze` | NLU only | `AnalyzeRequest` | `NLUResult` |
6571
| `POST /retrieval/search` | Retrieval from an existing NLU result | `RetrievalRequest` | `RetrievalResult` |
6672
| `POST /query/intelligence` | End-to-end NLU + Retrieval | `PipelineRequest` | `PipelineResponse` |
6773
| `POST /query/intelligence/artifacts` | End-to-end run and write JSON artifacts | `ArtifactRequest` | `ArtifactResponse` |
6874

75+
## Local Frontend Chatbot
76+
77+
The local frontend is a single-page chat app rendered by `query_intelligence/chatbot.py` and served from `query_intelligence/api/app.py`. It runs the same Query Intelligence pipeline, then sends compact evidence to DeepSeek only for final response wording.
78+
79+
![Chinese chatbot response](docs/assets/frontend-chatbot-zh.png)
80+
81+
Default DeepSeek settings are clone-safe and token-free:
82+
83+
| Setting | Default |
84+
|---|---|
85+
| Base URL | `https://api.deepseek.com` |
86+
| Chat path | `/chat/completions` |
87+
| Model | `deepseek-v4-flash` |
88+
| Thinking mode | `enabled` |
89+
| Reasoning effort | `high` |
90+
| JSON output | `response_format={"type":"json_object"}` |
91+
| Max tokens | `8192` |
92+
93+
Use `deepseek-v4-pro` by setting `DEEPSEEK_MODEL=deepseek-v4-pro` or editing `config/app_config.json`. Use `DEEPSEEK_REASONING_EFFORT=max` for heavier reasoning. The API key should be provided through `DEEPSEEK_API_KEY` or a local `.env`; do not commit it.
94+
95+
The UI response JSON includes `answer`, `key_points`, `risk_disclaimer`, `evidence_used`, `evidence_sources`, `llm`, `nlu_result`, and `retrieval_result`. For the full frontend reference and screenshots from real local runs, see [docs/frontend-chatbot.md](docs/frontend-chatbot.md).
96+
6997
### Frontend Request JSON
7098

7199
Recommended endpoint: `POST /query/intelligence`. Use `POST /query/intelligence/artifacts` if the backend should also write files.
@@ -415,8 +443,10 @@ flowchart TD
415443
E --> F["retrieval_result.json"]
416444
F --> G["Document Sentiment Analysis: sentiment/"]
417445
F --> H["LLM Response Utility: scripts/llm_response.py"]
446+
F --> J["Browser Chatbot: POST /chat"]
418447
G --> I["Downstream Analysis and Chatbot Answering"]
419448
H --> I
449+
J --> I
420450
```
421451

422452
Key paths:
@@ -434,7 +464,8 @@ Key paths:
434464
| `query_intelligence/integrations/` | Tushare, AKShare, Cninfo, efinance providers. |
435465
| `query_intelligence/external_data/` | Public dataset sync and asset building. |
436466
| `sentiment/` | Downstream document sentiment preprocessor and FinBERT classifier. |
437-
| `scripts/llm_response.py` | Downstream frontend answer and next-question JSON generator. |
467+
| `query_intelligence/chatbot.py` | Local browser UI renderer and DeepSeek response-polishing client for `/chat`. |
468+
| `scripts/llm_response.py` | Legacy local-transformers frontend answer and next-question JSON generator. |
438469
| `data/answer_generation_sft/` | Few-shot and handoff assets for answer generation experiments. |
439470
| `training/` | ML training scripts. |
440471
| `scripts/` | Sync, runtime materialization, evaluation, live-source verification. |
@@ -776,13 +807,13 @@ Common causes:
776807
- The source has no recent data.
777808
- The retrieval pipeline intentionally skipped an unsafe or irrelevant source.
778809

779-
### The API returns JSON but no natural-language answer
810+
### `/query/intelligence` returns JSON but no natural-language answer
780811

781-
This is expected. Query Intelligence only produces understanding and evidence artifacts. Final chatbot wording, investment-safe answer generation, sentiment analysis, trend analysis, and numerical calculation belong to downstream modules. For the current experimental answer-generation handoff, see `scripts/llm_response.py`.
812+
This is expected. Query Intelligence only produces understanding and evidence artifacts. Final chatbot wording, investment-safe answer generation, sentiment analysis, trend analysis, and numerical calculation belong to downstream modules. Use `POST /chat` or the local browser app for a DeepSeek-polished chatbot response. Use `scripts/llm_response.py` only for the legacy local-transformers frontend handoff flow.
782813

783814
## Frontend LLM Response Handoff
784815

785-
`scripts/llm_response.py` is a downstream utility for producing frontend-ready JSON from compact evidence. It can either consume an existing Query Intelligence record or run Query Intelligence first from a raw query.
816+
`scripts/llm_response.py` is a downstream utility for producing frontend-ready JSON from compact evidence. It can either consume an existing Query Intelligence record or run Query Intelligence first from a raw query. It is separate from the local browser chatbot: `/chat` uses DeepSeek API settings from `config/app_config.json`, while this script remains the local HuggingFace/transformers handoff path in this checkout.
786817

787818
It generates:
788819

README_CN.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ARIN Query Intelligence 是本仓库中负责“提问理解”和“证据检
55
- `nlu_result.json`: 第一阶段 NLU 结果,包含问题归一化、产品类型、意图、主题、实体、缺失槽位、风险标记、证据需求和 source plan。
66
- `retrieval_result.json`: 第二阶段检索结果,包含已执行数据源、文档证据、结构化行情/财务/宏观数据、覆盖度、告警和排序调试信息。
77

8-
本模块不生成最终聊天回复,不做投资结论。下游模块应直接消费这两个 JSON,再进行文档学习、情感分析、趋势分析、数值计算和最终回答生成
8+
Query Intelligence 主干不做投资结论。本仓库同时提供本地网页 Chatbot:`GET /` 渲染聊天页,`POST /chat` 消费同一套 NLU/Retrieval 产物,并在配置了 DeepSeek 时只做最终回答润色;模型不可用时会回退为结构化证据摘要
99

1010
## 支持范围
1111

@@ -24,7 +24,7 @@ ARIN Query Intelligence 是本仓库中负责“提问理解”和“证据检
2424
重要边界:
2525

2626
- Query Intelligence 负责 `nlu_result``retrieval_result`、source planning、检索证据和 `analysis_summary`
27-
- `sentiment/``scripts/llm_response.py` 是下游消费者。它们可以使用 `torch``transformers`、FinBERT 或本地生成模型,但不得重新推断用户意图、目标实体或检索 source plan。
27+
- `sentiment/``scripts/llm_response.py` `/chat` 网页包装层是下游消费者。它们可以使用 `torch``transformers`、FinBERT 或远程/本地生成模型,但不得重新推断用户意图、目标实体或检索 source plan。
2828

2929
## 快速运行
3030

@@ -38,6 +38,7 @@ python manual_test/run_manual_query.py
3838
python manual_test/run_manual_query.py --query "你觉得中国平安怎么样?"
3939

4040
# 启动本地网页 Chatbot(自动打开浏览器,配置见 config/app_config.json)
41+
export DEEPSEEK_API_KEY="your_deepseek_api_key_here"
4142
python scripts/launch_chatbot.py
4243

4344
# 启动 FastAPI 服务
@@ -64,12 +65,35 @@ API 定义在 `query_intelligence/api/app.py`,字段模型定义在 `query_int
6465
| Endpoint | 用途 | 输入 | 输出 |
6566
|---|---|---|---|
6667
| `GET /health` | 健康检查 || `{"status":"ok"}` |
68+
| `GET /` | 本地网页 Chatbot UI | 浏览器访问 | HTML app |
6769
| `POST /nlu/analyze` | 只跑 NLU | `AnalyzeRequest` | `NLUResult` |
6870
| `POST /retrieval/search` | 使用已有 NLU 结果跑检索 | `RetrievalRequest` | `RetrievalResult` |
6971
| `POST /query/intelligence` | 端到端跑 NLU + Retrieval | `PipelineRequest` | `PipelineResponse` |
7072
| `POST /query/intelligence/artifacts` | 端到端运行并落盘两个 JSON | `ArtifactRequest` | `ArtifactResponse` |
7173
| `POST /chat` | 端到端跑检索并调用 DeepSeek 润色 | `{"query":"..."}` | 前端聊天回复 JSON |
7274

75+
## 本地网页 Chatbot
76+
77+
本地前端是 `query_intelligence/chatbot.py` 内置的单页聊天界面,由 `query_intelligence/api/app.py` 暴露。它先跑 Query Intelligence,再把紧凑证据交给 DeepSeek 做回答措辞,不让模型重新发明实体、意图或数据源计划。
78+
79+
![中文聊天回复截图](docs/assets/frontend-chatbot-zh.png)
80+
81+
默认 DeepSeek 配置不包含密钥,适合 fresh clone:
82+
83+
| 配置项 | 默认值 |
84+
|---|---|
85+
| Base URL | `https://api.deepseek.com` |
86+
| Chat path | `/chat/completions` |
87+
| 模型 | `deepseek-v4-flash` |
88+
| Thinking mode | `enabled` |
89+
| Reasoning effort | `high` |
90+
| JSON 输出 | `response_format={"type":"json_object"}` |
91+
| Max tokens | `8192` |
92+
93+
如果要使用更强模型,设置 `DEEPSEEK_MODEL=deepseek-v4-pro`,或修改 `config/app_config.json`。如果要加大思考强度,设置 `DEEPSEEK_REASONING_EFFORT=max`。真实密钥只放在 `DEEPSEEK_API_KEY` 或本地 `.env`,不要提交到仓库。
94+
95+
`POST /chat` 的输出包含 `answer``key_points``risk_disclaimer``evidence_used``evidence_sources``llm``nlu_result``retrieval_result`。完整前端说明和真实本地截图见 [docs/zh/frontend-chatbot.md](docs/zh/frontend-chatbot.md)
96+
7397
### 前端请求 JSON
7498

7599
推荐前端调用 `POST /query/intelligence`。如果需要让服务端直接保存文件,调用 `POST /query/intelligence/artifacts`
@@ -594,8 +618,10 @@ flowchart TD
594618
E --> F["retrieval_result.json"]
595619
F --> G["文档情感分析: sentiment/"]
596620
F --> H["LLM 回答生成工具: scripts/llm_response.py"]
621+
F --> J["网页 Chatbot: POST /chat"]
597622
G --> I["下游分析与聊天回答"]
598623
H --> I
624+
J --> I
599625
```
600626

601627
主要模块:
@@ -613,7 +639,8 @@ flowchart TD
613639
| `query_intelligence/integrations/` | Tushare、AKShare、巨潮、efinance provider。 |
614640
| `query_intelligence/external_data/` | 公开数据集同步、标准化、训练资产构建。 |
615641
| `sentiment/` | 下游文档情感预处理与 FinBERT 分类器。 |
616-
| `scripts/llm_response.py` | 下游前端回答和下一问预测 JSON 生成工具。 |
642+
| `query_intelligence/chatbot.py` | `/chat` 本地网页 UI 渲染和 DeepSeek 回答润色客户端。 |
643+
| `scripts/llm_response.py` | 旧版本地 transformers 前端回答和下一问预测 JSON 生成工具。 |
617644
| `data/answer_generation_sft/` | 回答生成实验用 few-shot 与交接资产。 |
618645
| `training/` | 全部 ML 模型训练脚本。 |
619646
| `scripts/` | 数据同步、runtime materialize、评估、live provider 验证脚本。 |
@@ -1018,13 +1045,13 @@ python -m scripts.materialize_runtime_entity_assets
10181045
- 对应源没有近期数据。
10191046
- 检索 pipeline 对不适合的源做了保护性跳过。
10201047

1021-
### API 只输出 JSON,不返回自然语言答案,正常吗?
1048+
### `/query/intelligence` 只输出 JSON,不返回自然语言答案,正常吗?
10221049

1023-
正常。本模块只负责理解和证据检索。最终聊天回答、投资观点措辞、情感分析、趋势分析和指标计算由下游模块完成。当前实验性的回答生成交接工具见 `scripts/llm_response.py`
1050+
正常。Query Intelligence 主干只负责理解和证据检索。最终聊天回答、投资观点措辞、情感分析、趋势分析和指标计算由下游模块完成。需要 DeepSeek 润色后的网页聊天回复时,使用 `POST /chat` 或本地网页 Chatbot;`scripts/llm_response.py` 仍是本 checkout 中本地 transformers 路径的前端交接工具
10241051

10251052
## 前端 LLM 回答生成交接
10261053

1027-
`scripts/llm_response.py` 是一个下游工具,用紧凑证据生成前端可直接消费的 JSON。它既可以读取已有 Query Intelligence 记录,也可以从原始 query 开始先跑 Query Intelligence。
1054+
`scripts/llm_response.py` 是一个下游工具,用紧凑证据生成前端可直接消费的 JSON。它既可以读取已有 Query Intelligence 记录,也可以从原始 query 开始先跑 Query Intelligence。它和本地网页 Chatbot 是两条不同路径:`/chat` 使用 `config/app_config.json` 中的 DeepSeek API 配置;这个脚本在当前 checkout 中仍是本地 HuggingFace/transformers 回答交接路径。
10281055

10291056
它生成:
10301057

config/app_config.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
"submit_text": "Submit"
1010
},
1111
"deepseek": {
12-
"base_url": "https://api.deepseek.com/v1",
12+
"base_url": "https://api.deepseek.com",
1313
"chat_path": "/chat/completions",
14-
"model": "deepseek-chat",
14+
"model": "deepseek-v4-flash",
1515
"api_key": "",
16-
"timeout_seconds": 30
16+
"timeout_seconds": 60,
17+
"thinking_type": "enabled",
18+
"reasoning_effort": "high",
19+
"max_tokens": 8192
1720
},
1821
"live_data": {
1922
"enabled": true
137 KB
Loading
139 KB
Loading

docs/frontend-chatbot.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Local Frontend Chatbot
2+
3+
Languages: English | [中文](zh/frontend-chatbot.md)
4+
5+
The local frontend chatbot is the browser-facing demo for FinSight. It is intentionally thin: the UI sends a user question to `POST /chat`, the backend runs Query Intelligence, and DeepSeek only rewrites the compact evidence into a user-facing answer.
6+
7+
This wrapper must not replace the NLU/Retrieval backbone. Entity resolution, intent, source planning, evidence retrieval, ranking, warnings, and `analysis_summary` still come from Query Intelligence.
8+
9+
## Run
10+
11+
From a fresh clone:
12+
13+
```bash
14+
pip install -r requirements.txt
15+
export DEEPSEEK_API_KEY="your_deepseek_api_key_here"
16+
python scripts/launch_chatbot.py
17+
```
18+
19+
Then open:
20+
21+
```text
22+
http://127.0.0.1:8765/
23+
```
24+
25+
For repeatable local demos, you can disable slow announcement live calls while keeping local announcement seed data available:
26+
27+
```bash
28+
QI_USE_LIVE_ANNOUNCEMENT=0 python scripts/launch_chatbot.py
29+
```
30+
31+
## Request Flow
32+
33+
```mermaid
34+
flowchart LR
35+
A["Browser UI"] --> B["POST /chat"]
36+
B --> C["QueryIntelligenceService.run_pipeline"]
37+
C --> D["nlu_result"]
38+
C --> E["retrieval_result + analysis_summary"]
39+
E --> F["Compact evidence payload"]
40+
F --> G["DeepSeek chat completions"]
41+
G --> H["answer + key_points + risk_disclaimer"]
42+
H --> I["Evidence source cards"]
43+
```
44+
45+
If DeepSeek is missing, unreachable, or returns invalid JSON, `/chat` returns a structured-summary fallback with `llm.status="fallback"`. It still includes `nlu_result`, `retrieval_result`, and evidence sources.
46+
47+
## DeepSeek Configuration
48+
49+
Defaults live in `config/app_config.json` and can be overridden by environment variables.
50+
51+
| Field | Env var | Default |
52+
|---|---|---|
53+
| `deepseek.api_key` | `DEEPSEEK_API_KEY` | empty |
54+
| `deepseek.base_url` | `DEEPSEEK_BASE_URL` | `https://api.deepseek.com` |
55+
| `deepseek.chat_path` | `DEEPSEEK_CHAT_PATH` | `/chat/completions` |
56+
| `deepseek.model` | `DEEPSEEK_MODEL` | `deepseek-v4-flash` |
57+
| `deepseek.timeout_seconds` | `DEEPSEEK_TIMEOUT_SECONDS` | `60` |
58+
| `deepseek.thinking_type` | `DEEPSEEK_THINKING_TYPE` | `enabled` |
59+
| `deepseek.reasoning_effort` | `DEEPSEEK_REASONING_EFFORT` | `high` |
60+
| `deepseek.max_tokens` | `DEEPSEEK_MAX_TOKENS` | `8192` |
61+
62+
Use `DEEPSEEK_MODEL=deepseek-v4-pro` when you want the higher-capability model. Use `DEEPSEEK_REASONING_EFFORT=max` for heavier thinking. The backend sends `response_format={"type":"json_object"}` and prompts DeepSeek for one strict JSON object.
63+
64+
## API Contract
65+
66+
`POST /chat` accepts the same frontend context fields as the core pipeline:
67+
68+
```json
69+
{
70+
"query": "你觉得中国平安怎么样?",
71+
"user_profile": {},
72+
"dialog_context": [],
73+
"top_k": 20,
74+
"debug": false
75+
}
76+
```
77+
78+
Response fields:
79+
80+
| Field | Meaning |
81+
|---|---|
82+
| `answer` | Final user-facing wording generated by DeepSeek or fallback summary. |
83+
| `key_points` | Short bullet points grounded in retrieved evidence. |
84+
| `risk_disclaimer` | Investment-risk disclaimer. |
85+
| `evidence_used` | Evidence IDs selected by the answer layer. |
86+
| `evidence_sources` | UI-ready source cards with title, type, source name, and optional URL. |
87+
| `llm` | `{provider, model, status, error}` for model observability. |
88+
| `nlu_result` | Full Query Intelligence NLU artifact. |
89+
| `retrieval_result` | Full retrieval artifact, including warnings and `analysis_summary`. |
90+
91+
## Verified Local Run
92+
93+
The following screenshots came from real local browser runs on May 3, 2026. The service was started with `deepseek-v4-flash`, thinking enabled, `reasoning_effort=high`, and a local environment variable for the API key. The key is not written to the repository.
94+
95+
Chinese query:
96+
97+
```text
98+
你觉得中国平安怎么样?
99+
```
100+
101+
![Chinese chatbot response](assets/frontend-chatbot-zh.png)
102+
103+
English query:
104+
105+
```text
106+
What do you think about Ping An Insurance (601318.SH)?
107+
```
108+
109+
![English chatbot response](assets/frontend-chatbot-en.png)
110+
111+
Observed checks:
112+
113+
| Check | Result |
114+
|---|---|
115+
| `GET /health` | `{"status":"ok"}` |
116+
| `POST /chat` Chinese query | `llm.status="ok"`, response in Chinese |
117+
| `POST /chat` English query | `llm.status="ok"`, response in English |
118+
| Browser interaction | Input, submit button, answer card, key points, evidence cards, and disclaimer rendered |
119+
| Dependency issue fixed | Added `socksio` so `httpx` can use local SOCKS proxy variables |
120+
121+
## Troubleshooting
122+
123+
If DeepSeek falls back with a SOCKS proxy error, install dependencies again:
124+
125+
```bash
126+
pip install -r requirements.txt
127+
```
128+
129+
If live providers fail, inspect `retrieval_result.warnings`. The pipeline is expected to degrade gracefully and still answer from fallback providers or shipped runtime assets when possible.

0 commit comments

Comments
 (0)