银行客服智能体架构设计与效率优化实战

news2026/3/25 2:30:30
银行客服智能体架构设计与效率优化实战最近在参与一个银行客服系统的智能化改造项目目标是解决传统客服响应慢、人力成本高的问题。经过几个月的实战我们基于NLP和知识图谱设计了一套智能体架构效果还不错响应速度提升了3倍多。今天就来分享一下从架构设计到性能优化的全流程经验希望能给有类似需求的同学一些参考。1. 背景与核心痛点分析银行客服场景的挑战远比想象中复杂。在项目初期我们深入业务部门调研梳理出以下几个核心痛点高并发咨询压力特别是在月初、月末、节假日等时段咨询量会呈井喷式增长。传统的人工坐席模式需要配备大量客服人员应对峰值但闲时又造成人力闲置成本结构极不经济。业务复杂度爆炸银行业务种类繁多从简单的账户查询、转账到复杂的理财产品咨询、贷款申请、跨境业务等知识库庞大且更新频繁。新员工培训周期长老员工也难免出现回答不一致的情况。7×24小时不间断服务要求客户期望获得全天候的服务但人力实现三班倒成本高昂且夜间服务质量难以保证。服务标准化与合规性挑战金融行业的回答必须严谨、准确符合监管要求。纯人工服务容易因情绪、疲劳导致表述偏差引发客户投诉或合规风险。多渠道服务体验割裂客户可能通过电话、网页、APP、微信等多个渠道咨询传统系统下各渠道信息不互通客户每次都需要重复描述问题体验很差。正是这些痛点催生了我们对智能化客服解决方案的迫切需求。我们的目标不仅仅是“有人应答”而是要构建一个“高效、准确、合规、可扩展”的智能服务体。2. 技术路径对比与选型在确定最终方案前我们对比了三种主流的技术路径基于规则引擎、基于传统NLP模型、以及我们最终采用的智能体架构。下面这个简单的对比表格能清晰反映差异维度规则引擎 (如Drools)传统NLP模型 (如意图分类器)智能体架构 (NLP知识图谱会话管理)开发/QPS高规则匹配速度快中依赖模型推理速度中涉及多模块协同准确率低只能处理预设场景泛化能力差中对训练数据质量要求高对复杂、多轮对话支持弱高结合知识图谱进行推理能处理复杂、上下文相关的问题维护成本极高业务规则一变需要人工梳理和修改大量规则容易产生冲突中需要持续标注数据、重新训练和更新模型相对较低知识以图谱形式结构化增删改查灵活模型可在线学习微调业务适应性差适合流程固定、逻辑简单的场景一般适合意图明确的单轮问答强适合业务复杂、需多轮交互和逻辑推理的银行场景通过对比规则引擎虽然响应快但维护是噩梦传统NLP模型在简单问答上可行但无法理解“我上个月买的那个理财产品收益怎么样”这类需要上下文和知识关联的问题。因此一个融合了精准意图识别、结构化知识查询、上下文会话管理的智能体架构成为了我们的必然选择。3. 核心架构设计详解我们的智能体采用分层、事件驱动的设计思想核心目标是实现高内聚、低耦合便于各模块独立迭代和扩展。上图展示了智能体的核心分层架构从接入到响应数据流清晰可控。整个架构主要分为四层接入层统一网关。负责接收来自APP、微信、网页等不同渠道的请求进行协议转换、鉴权、限流和初步的日志记录。我们使用Spring Cloud Gateway实现利用其过滤器链很好地完成了这些通用功能。意图识别与处理层智能大脑。这是最核心的一层。意图识别模块使用NLP模型对用户query进行意图分类是查询余额、转账还是咨询理财。槽位填充模块识别出意图后需要提取关键信息实体例如转账中的“收款人”、“金额”。这里我们结合了基于词典和序列标注模型的方法。事件生成器将识别出的“意图”和“槽位”封装成一个结构化的“事件”Event例如TransferIntentEvent(amount5000, payee张三)。这个事件是驱动后续流程的核心。知识图谱与决策层智慧引擎。知识图谱我们将银行的产品、条款、业务流程、常见问答等知识以“实体-关系-属性”的形式构建成图谱。例如“理财产品A”实体有“风险等级”、“预期年化”、“起购金额”等属性并与“货币基金”类别存在“属于”关系。决策引擎接收到“事件”后决策引擎会查询知识图谱并结合会话历史进行推理。例如用户问“风险低的理财有哪些”引擎会在图谱中查找“风险等级低”的理财产品实体并组织成自然语言回复。会话管理与输出层记忆与表达。会话管理维护每个对话的上下文状态。这里我们创新性地应用了“事件溯源Event Sourcing”模式。我们不直接保存对话的最终状态而是持久化存储所有发生过的“事件”序列如UserAskedEvent,IntentRecognizedEvent,AnswerProvidedEvent。当需要重建某个会话的状态时只需按序重放所有事件即可。这带来了巨大好处历史对话可完整追溯、调试极其方便、易于实现“回到上一步”等功能。自然语言生成将决策引擎返回的结构化数据转换成流畅、友好、符合银行话术规范的自然语言回复通过接入层返回给用户。4. 关键代码实现片段理论讲完了来看看一些落地代码。我们以意图识别和会话缓存优化为例。意图识别Spring Boot Apache OpenNLP我们选择了Apache OpenNLP进行初始验证因为它轻量、易集成。实际生产中后期我们融合了BERT模型来提升复杂意图的准确率。import opennlp.tools.doccat.*; import opennlp.tools.tokenize.SimpleTokenizer; import opennlp.tools.util.*; import java.io.*; import java.util.HashMap; import java.util.Map; /** * 意图分类器服务 * 1. 训练基于标注好的问答数据训练模型 * 2. 预测对用户输入进行意图分类 */ Service public class IntentClassifierService { private DoccatModel model; private final String MODEL_PATH models/intent-model.bin; PostConstruct public void init() throws IOException { // 服务启动时加载已持久化的模型。如果不存在则训练并保存。 File modelFile new File(MODEL_PATH); if (modelFile.exists()) { try (InputStream modelIn new FileInputStream(modelFile)) { model new DoccatModel(modelIn); } } else { trainAndSaveModel(); } } /** * 训练意图分类模型 * 特征提取这里使用简单的词袋模型Bag-of-Words将句子分词后作为特征 */ private void trainAndSaveModel() throws IOException { // 模拟训练数据每行格式为 意图标签\t语句 // 实际项目中应从数据库或标注平台读取 ObjectStreamString lineStream new CollectionObjectStream(Arrays.asList( balance_query\t我的余额还有多少, balance_query\t查一下卡里多少钱, fund_transfer\t我要转账给张三500元, fund_transfer\t转5000到李四的账户, product_consult\t你们有什么理财产品, product_consult\t推荐个低风险的理财 )); // 将每行数据解析为DocumentSample对象标签文本 ObjectStreamDocumentSample sampleStream new DocumentSampleStream(lineStream); // 配置训练参数 TrainingParameters params TrainingParameters.defaultParams(); params.put(TrainingParameters.ALGORITHM_PARAM, MAXENT); params.put(TrainingParameters.ITERATIONS_PARAM, 100); params.put(TrainingParameters.CUTOFF_PARAM, 2); // 特征出现次数阈值 // 特征生成器使用简单的词元Token作为特征 FeatureGenerator[] featureGenerators { new BagOfWordsFeatureGenerator() }; DoccatFactory factory new DoccatFactory(featureGenerators); // 开始训练 DoccatModel trainedModel DocumentCategorizerME.train(zh, sampleStream, params, factory); // 持久化模型到文件 try (OutputStream modelOut new BufferedOutputStream(new FileOutputStream(MODEL_PATH))) { trainedModel.serialize(modelOut); } this.model trainedModel; System.out.println(意图模型训练并持久化完成。); } /** * 预测用户输入的意图 * param userInput 用户原始输入 * return 最可能的意图标签及其概率 */ public MapString, Double predictIntent(String userInput) { DocumentCategorizerME categorizer new DocumentCategorizerME(model); SimpleTokenizer tokenizer SimpleTokenizer.INSTANCE; // 1. 分词将句子切分成词元Tokens String[] tokens tokenizer.tokenize(userInput); // 2. 分类计算属于各个意图类别的概率 double[] outcomes categorizer.categorize(tokens); String category categorizer.getBestCategory(outcomes); // 3. 获取所有类别及其概率用于置信度判断或后续处理 MapString, Double result new HashMap(); String[] categories categorizer.getCategories(); for (int i 0; i categories.length; i) { result.put(categories[i], outcomes[i]); } // 通常我们会设置一个置信度阈值如0.6低于阈值则转人工或提示澄清 if (result.get(category) 0.6) { result.put(fallback_to_human, 1.0); } return result; } }会话缓存优化Redis管道技术会话状态频繁读写对缓存性能要求高。我们使用Redis存储事件溯源中的事件列表并用管道Pipeline技术批量读写大幅减少网络往返延迟。import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.SessionCallback; import org.springframework.stereotype.Component; import java.util.List; /** * 会话状态服务 - 使用Redis管道优化 */ Component public class SessionStateService { Autowired private RedisTemplateString, String redisTemplate; private static final String SESSION_EVENTS_KEY_PREFIX session:events:; /** * 向指定会话追加多个事件批量操作使用管道 * param sessionId 会话ID * param events 事件列表这里用JSON字符串表示事件对象 */ public void appendEvents(String sessionId, ListString events) { String key SESSION_EVENTS_KEY_PREFIX sessionId; // 使用SessionCallback执行管道操作 ListObject results redisTemplate.executePipelined(new SessionCallbackObject() { Override public K, V Object execute(RedisOperationsK, V operations) throws DataAccessException { // 在管道内连续发送多个命令但不立即获取结果 for (String event : events) { // 使用RPUSH命令将事件追加到列表尾部 operations.opsForList().rightPush((K) key, (V) event); } // 可选设置Key的过期时间例如24小时 operations.expire((K) key, 24, TimeUnit.HOURS); return null; // 管道内无需返回值 } }); // results 包含每个命令的返回结果顺序与命令发送顺序一致 // 对于大量事件追加管道能减少 (N-1) 次RTT网络往返时间 } /** * 获取指定会话的所有事件重建状态 * param sessionId 会话ID * return 事件列表 */ public ListString getAllEvents(String sessionId) { String key SESSION_EVENTS_KEY_PREFIX sessionId; // LRANGE 0 -1 获取列表所有元素 return redisTemplate.opsForList().range(key, 0, -1); } }5. 性能优化与压测结果架构和代码实现后性能是关键。我们使用JMeter进行了全面的压力测试。压测环境与场景机器配置4核8G * 3节点微服务集群中间件Redis集群MySQL读写分离。测试接口智能问答主接口包含意图识别、知识查询、会话更新。压测脚本模拟混合意图查询、转账咨询、产品咨询的请求流。压测报告关键数据500 TPS下百分比 (Percentile)响应时间 (Response Time)50% (中位数)68 ms90%142 ms95%189 ms99%350 ms平均响应时间85 ms错误率0.02%优化措施与效果缓存预热与分级降级解决冷启动预热服务启动时后台线程自动加载高频意图模型、热点知识图谱子图到本地缓存。分级降级当监测到系统负载过高如CPU80%或缓存未命中时启动降级策略。一级降级简化NLU模型使用更快的规则匹配二级降级返回预设的通用话术引导菜单三级降级直接转接人工坐席入口。通过配置中心动态开关降级策略。异步化与事件驱动将日志记录、监控指标上报、非关键的通知发送等操作全部改为异步事件处理不阻塞主应答链路。JVM与GC调优针对NLP模型加载占用大量堆内内存的特点我们调整了G1垃圾回收器的参数增加堆大小并设置合理的Region大小避免Full GC导致的长时间停顿。这些优化使得系统在500 TPS的持续压力下P99响应时间控制在350ms以内完全满足银行场景的体验要求通常期望在1秒内响应。6. 实践中的避坑指南在金融领域做智能体安全和稳定性是生命线。这里分享两个关键问题的解决方案。金融领域敏感词过滤DFA算法所有用户输入和系统输出都必须经过敏感词过滤。我们实现了高效的DFADeterministic Finite Automaton算法。import java.util.*; /** * 基于DFA算法的敏感词过滤器 * 特点一次扫描文本即可检测出所有敏感词效率O(n) */ Component public class SensitiveWordFilter { private MapCharacter, Object sensitiveWordMap new HashMap(); PostConstruct public void init() { // 从数据库或文件加载敏感词库这里用示例数据 SetString wordSet new HashSet(Arrays.asList(信用卡套现, 高利贷, 资金盘, 诈骗)); addSensitiveWordToHashMap(wordSet); } /** * 构建DFA树形结构 * 例如{信: {用: {卡: {套: {现: {isEnd: 1}}}}}} */ private void addSensitiveWordToHashMap(SetString wordSet) { for (String word : wordSet) { MapCharacter, Object nowMap sensitiveWordMap; for (int i 0; i word.length(); i) { char keyChar word.charAt(i); Object tempMap nowMap.get(keyChar); if (tempMap ! null) { nowMap (MapCharacter, Object) tempMap; } else { MapCharacter, Object newMap new HashMap(); newMap.put(isEnd, 0); // 0表示不是终点 nowMap.put(keyChar, newMap); nowMap newMap; } if (i word.length() - 1) { nowMap.put(isEnd, 1); // 最后一个字符标记为终点 } } } } /** * 检查文本中是否包含敏感词 * param text 待检查文本 * return 包含的敏感词集合 */ public SetString getSensitiveWords(String text) { SetString sensitiveWordSet new HashSet(); for (int i 0; i text.length(); i) { int length checkSensitiveWord(text, i); if (length 0) { sensitiveWordSet.add(text.substring(i, i length)); i i length - 1; // 跳过已检测到的词 } } return sensitiveWordSet; } /** * 从指定位置开始检查 * param text 文本 * param beginIndex 开始下标 * return 敏感词长度0表示不是敏感词 */ private int checkSensitiveWord(String text, int beginIndex) { MapCharacter, Object nowMap sensitiveWordMap; int matchFlag 0; // 匹配到的敏感词长度 for (int i beginIndex; i text.length(); i) { char word text.charAt(i); nowMap (MapCharacter, Object) nowMap.get(word); if (nowMap ! null) { matchFlag; if (1.equals(nowMap.get(isEnd).toString())) { return matchFlag; // 找到完整敏感词返回长度 } } else { break; } } return 0; } /** * 替换敏感词为*号 */ public String replaceSensitiveWords(String text) { SetString words getSensitiveWords(text); String result text; for (String word : words) { String replacement *.repeat(word.length()); result result.replaceAll(word, replacement); } return result; } }对话幂等性保障的3种实践方案网络超时重试可能导致重复请求必须保证对话操作的幂等性。Token机制推荐客户端发起请求前先向服务端申请一个唯一会话Token。携带该Token的请求服务端在处理前用Redis的SETNX命令判断是否已处理过。请求唯一ID客户端为每个请求生成唯一ID如UUID服务端在数据库或缓存中建立唯一索引。重复ID的请求直接返回上次的处理结果。业务状态机对于转账咨询等涉及状态变化的业务设计严谨的状态机。只有处于特定状态如“待确认”的请求才会被处理重复请求会因状态不符而被拒绝。我们综合使用了方案1和方案3既保证了通用接口的幂等又满足了具体业务流程的严谨性。7. 延伸思考与RPA结合实现端到端自动化智能体解决了“答”的问题但很多业务还需要“做”。例如用户问“帮我查询最近三年的交易流水并发到我邮箱”。智能体可以理解意图但真正的查询、生成PDF、发送邮件涉及多个后端系统操作。这时RPA机器人流程自动化就可以与智能体无缝结合。我们的架构演进思路是智能体在识别到这类“需要执行”的意图后如export_transaction_history生成一个结构化的任务请求。将任务请求放入消息队列如RabbitMQ。RPA机器人消费队列中的任务自动登录核心系统、执行查询、生成文件、调用邮件服务发送。执行完成后RPA将结果通知回智能体由智能体告知用户“流水已发送至您的邮箱请注意查收。”这样就实现了从“智能问答”到“智能办事”的跨越真正打通了端到端的业务流程自动化这也是银行数字化转型的一个重要方向。写在最后回顾整个项目从梳理业务痛点到技术选型对比再到分层架构设计、核心模块实现、性能调优和安全加固每一步都充满了挑战但也收获颇丰。智能客服不是简单的问答机器人而是一个需要融合自然语言处理、知识工程、软件架构、高性能计算的复杂系统。目前我们的系统已经稳定运行日均处理咨询量提升了数十倍人力成本显著下降客户满意度也有 measurable 的提升。下一步我们计划引入更先进的预训练模型如领域微调的BERT来提升意图和实体的识别精度并探索多模态交互如图片、语音的可能性。希望这篇笔记能为你带来一些启发。如果你也在做类似的项目欢迎一起交流探讨。技术的道路就是在不断踩坑和填坑中前进的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2445944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…