本文档说明如何运行本项目,以及项目源代码架构与主要模块介绍。完整方案设计见 保险/金融咨询大模型智能办理:基于工具调用与策略编排的完整方案及源代码

代码以及文档参考:


一、项目简介

本项目为保险/金融咨询智能办理大模型应用,通过「一次大模型调用 + 策略编排驱动话术」实现售前接待与信息引导收集。支持 Gradio 网页对话与 FastAPI HTTP 接口两种运行方式,槽位数据持久化于本地 SQLite(insurance_consult.db)。


二、快速开始

环境要求

  • Python 3.11+
  • Conda(推荐)或 venv

安装步骤

1. 创建虚拟环境并激活

conda 创建虚拟环境并激活:

Windows:

cd intent_identification/project2_insurance_consult
conda create -n venv_insurance_consult python=3.11 -y
conda activate venv_insurance_consult

Linux/Mac:

cd intent_identification/project2_insurance_consult
conda create -n venv_insurance_consult python=3.11 -y
conda activate venv_insurance_consult

venv 创建虚拟环境并激活:

Windows:

cd intent_identification/project2_insurance_consult
python3.11 -m venv venv_insurance_consult
.\venv_insurance_consult\Scripts\activate

macOS/Linux:

cd intent_identification/project2_insurance_consult
python3.11 -m venv venv_insurance_consult
source venv_insurance_consult/bin/activate
2. 安装依赖
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
3. 配置 API 与数据库

在项目目录下的 config_parser.py 中配置(或通过 .env 覆盖):

  • api_key:大模型 API Key(如 DashScope、OpenAI 等兼容接口)
  • base_url:大模型反向代理或官方 API 地址(若需)

数据库使用本地 SQLite,默认 db_path = "insurance_consult.db",数据文件会生成在当前目录,无需安装或配置数据库服务。首次运行时会自动创建表。

配置 API 密钥

项目目录下创建 .env 文件,添加:

BASE_URL=XXXX
DASHSCOPE_API_KEY=sk-XXXX
MODEL=XXX

注意:需要申请 DashScope 或其它兼容 OpenAI 格式的 API 账号获取 API Key。


三、使用指南

完成上述安装与配置后,可按以下方式将项目运行起来。

怎样运行起来(概览)

用途 运行命令 说明
网页对话界面 python main.py 在浏览器中与保险咨询助手聊天,默认打开 http://127.0.0.1:7860
HTTP API 服务 python server_api_prod.py 对外提供 POST /insurance_chatbot 接口,默认端口 3313

以上命令均需在项目目录 intent_identification/project2_insurance_consult 下、已激活虚拟环境后执行。首次运行前请确保已完成「安装步骤」中的依赖安装与 .env(或 config_parser.py)配置。

运行前检查

  • 已创建并激活虚拟环境(conda 或 venv)
  • 已执行 pip install -r requirements.txt 安装依赖
  • 已在项目目录下创建 .env 并配置 BASE_URLDASHSCOPE_API_KEY(或按需在 config_parser.py 中配置)
  • 数据库使用本地 SQLite,无需额外安装;首次运行会自动创建 insurance_consult.db 及表

方式一:Gradio 图形界面(推荐)

  1. 进入项目目录并确认虚拟环境已激活。
  2. 直接运行: python main.py,或使用 uvicorn main:app --host 0.0.0.0 --port 7860。本机访问: http://127.0.0.1:7860
  3. 在页面中输入问题即可与保险咨询助手对话,支持流式输出。

方式二:FastAPI 接口(用于生产或对接前端)

  1. 在项目目录下、已激活虚拟环境中执行:python server_api_prod.pyuvicorn server_api_prod:app --host 0.0.0.0 --port 3313
  2. 服务默认监听 3313 端口。接口说明:
    • 地址POST /insurance_chatbot
    • 请求体(JSON)groupId(string)、current_message(string)、history(list)
    • 响应:SSE 流式输出(text/event-stream),逐块返回助手回复内容

方式三:测试 API 接口(可选)

使用项目中的 server_post_prod.py 模拟客户端请求。先启动 API 服务,将脚本内 demo_url 改为 http://127.0.0.1:3313/insurance_chatbot,然后执行 python server_post_prod.py

数据与持久化

  • 对话槽位信息保存在项目目录下的 SQLite 数据库中(默认 insurance_consult.db),首次运行时会自动建表。
  • 同一 groupId 的多轮对话会共用一个槽位记录,实现跨轮次信息收集与持久化。

四、项目结构与源代码架构

4.1 目录与主要文件

文件 说明
main.py Gradio 网页对话入口,启动后可在浏览器中聊天
server_api_prod.py FastAPI 服务入口,提供 POST /insurance_chatbot 流式接口
server_post_prod.py 示例客户端,用于测试 API 服务
chat_process_client.py 核心:对话主流程(首轮引导、LLM 调用、工具解析、槽位更新、模板反问/总结)
function_utils.py 槽位排序、缺失槽位查找 get_next_message_by_slots、总结模板类 FunctionCallSummaryConfig
tools_definition.py 工具定义(Function Calling 的 tools 描述、槽位与话术配置)
config_parser.py API、数据库等配置
db_helper.py SQLite 连接与槽位表读写
requirements.txt Python 依赖

4.2 主流程(文字版)

用户输入 → 读取历史槽位 → 首轮固定引导语/后续进入LLM
    → LLM流式输出
        ├── 普通回复(finish_reason=stop):直接流式返回
        └── 工具调用(finish_reason=tool_calls)
            → 解析并执行工具 → 更新all_filled_slots → 写库
            → 调用get_next_message_by_slots
                ├── 有缺失 → 模板化反问
                ├── 无缺失且有下一主题 → 总结+开启下一主题
                ├── 全部完成 → 发送final_message_template
                └── 无缺失且槽位未变 → 调用LLM自由对话

4.3 主流程(Mermaid 流程图)

以下流程图可在支持 Mermaid 的 Markdown 查看器(如 VS Code、GitHub、Typora)中渲染。

信息收集完成

开启下一主题

get_next_message_by_slots

当前主题有缺失

Function Calling 分支

自由回复·直接返回

非首轮·进入LLM

首轮·无LLM

入口

stop

tool_calls

用户输入 current_message

len history == 0?

发送固定引导语 introduce_message

stream_string 流式输出

本轮结束

Read_SlotInfo 读取历史槽位

拼接 system_prompt + history + current_message

聊天补全流式调用

LLM finish_reason?

直接 yield delta.content

解析 complete_tool_calls

遍历执行 FunctionCallSummaryConfig

更新 all_filled_slots

update_SlotInfo 写库

total_missing_field 非空?

missing_slot_ask_prompt 模板化反问

get_next_message_by_slots

next_collect_slot_list 非空?

prefix_summary + whole_function_response

is_all_field_missing?

main_question_schema 预定义话术

params_schema 拼接缺失槽位

next_message stream_string

is_slot_changed?

final_message_template conclusion_message

聊天补全自由对话

4.4 简化核心路径

用户输入

首轮?

固定引导语

LLM调用

工具调用?

直接返回

更新槽位+写库

当前主题有缺失?

模板化反问

get_next_message_by_slots

还有下一主题?

总结+开启下一主题

槽位有更新?

结束语

输出


五、典型对话示例与源码调用追踪

以下通过具体对话示例说明系统行为及背后的源码调用路径(逻辑与 project1 留学项目一致,仅槽位与话术为保险场景)。

示例一:首轮对话(固定引导语)

用户你好

机器人:欢迎咨询保险服务,我是您的智能顾问。请问您的年龄、职业和大概年收入区间?

源码调用chat_process_client.pyif len(history)==0 判定为首轮;固定文案 introduce_messagestream_string(introduce_message) 流式输出后 return;不调用 LLM;新用户会先 insert_SlotInfo 写入空槽位,type 为「保险咨询」。


示例二:用户只回答部分槽位(如仅年龄,未说明职业与收入)

用户我35岁

LLM 行为:触发 get_policyholder_basic,抽取 age="35岁"occupationincome_range 为空或「未提到」。

机器人:收到反馈:年龄:35岁;请进一步提供:职业、年收入区间。

源码调用:LLM 返回 tool_calls,解析得到 get_policyholder_basic 部分参数;total_missing_fields 非空,进入模板化反问分支;params_schema 拼出「职业」「年收入区间」等缺失项;stream_string(missing_slot_ask_prompt) 流式输出并 return


示例三:用户完整回答主题一(三个槽位都填满)

用户我35岁,工程师,年收入50万左右

LLM 行为:触发 get_policyholder_basic,抽取 ageoccupationincome_range 均填满。

机器人:已收到您的反馈:年龄、职业、年收入区间。我们继续,您是否是家里主要经济支柱?目前有几个孩子?

源码调用one_tool_missing_fields==0,调用 FunctionCallSummaryConfig.get_policyholder_basic(...) 生成总结;update_SlotInfo 写库;get_next_message_by_slots 返回下一主题 get_family_info 的缺失槽位;main_question_schema["get_family_info"] 作为下一句问法;stream_string(next_message) 流式输出并 return


示例四:用户一次性回答多个主题(跨主题填槽)

用户我35岁,年收入50万,想买重疾和寿险

LLM 行为:可能触发 get_policyholder_basic(age、income_range 等)与 get_insurance_demand(product_types 等)。

机器人:收到反馈:年龄、年收入区间、险种意向等;并继续追问当前或下一主题的缺失槽位(如职业、保额预期、缴费预算等)。

源码调用complete_tool_calls 包含多个工具;循环中逐个更新 all_filled_slots,累加 whole_function_responseget_next_message_by_slots 找到第一个仍有缺失的主题,按 is_all_field_missing 选择预定义话术或 params_schema 拼接缺失槽位;stream_string(next_message) 输出。


示例五:用户未触发 Function Calling(自由对话)

用户重疾险和寿险有什么区别?

LLM 行为finish_reason == "stop",直接生成文本回复,不触发 tool_calls

源码调用chunk.choices[0].delta.content 有内容且 finish_reason == "stop",直接 yield 流式返回;不进入 complete_tool_calls 分支。


示例六:信息全部搜集完成后的结束语

当前槽位:所有 6 个主题的槽位均已填满。

用户没有了,就这些

LLM 行为:触发 get_other_infospecial_needs="没有了",该主题填满。

机器人:我们已清楚您的需求:年龄:xx 职业:xx … 其他补充:没有了。正在为您匹配方案,请稍候……

源码调用get_next_message_by_slots 返回 ([], False, '')not next_collect_slot_list and is_slot_changed 为真;final_message_template["conclusion_message"].format(*slot_values) 用全部槽位值填充;stream_string(finished_message) 流式输出并 return

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐