ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

基于DeepSeek构建多轮法律咨询对话系统:状态管理与上下文压缩实战

基于DeepSeek构建多轮法律咨询对话系统:状态管理与上下文压缩实战 简介这份554页PDF文档围绕DeepSeek对话管理框架系统讲解法律智能助手从技术选型到落地部署的全链路构建方案面向NLP工程师、算法工程师、法律科技产品经理及对话系统开发者旨在解决多轮法律咨询中的上下文理解与精准应答难题。资源共1个PDF文件压缩包14.38MB内含50个大章节支持目录跳转与书签大纲读者可依据具体章节快速定位技术方案。内容覆盖法律专业词汇库搭建、实体识别与意图识别的数据标注规范、基于DeepSeek框架的模型训练参数设置、微调策略与蒸馏部署等核心环节同时剖析了长对话上下文衰减、法律实体指代消解、模糊意图迁移等实务难点并给出可复用的解决思路。文档结构完整从需求拆解、技术选型、数据工程到模型优化层层递进辅以标注规则、训练流程和参数配置既适合作为项目建设的路线图也可作为技术评审的参考资料。已有108人学习对于正在构建法律智能化应用或希望借鉴垂直领域对话系统完整方案的开发者具有较高的参考价值。 用户问我在工厂干了三年公司一直没签合同现在把我辞了能要赔偿吗——第一轮就把关键信息交代得差不多。但他追问那加班费还能不能算时很多系统已经忘了前面的没签合同和被辞退。DeepSeek法律智能助手对话系统要解决的正是多轮法律咨询场景下的上下文理解与精准应答生成。它的做法是把记住什么、追问什么、怎么回答拆成三层对话管理框架维护案件状态DeepSeek负责抽取事实与生成答复中间垫一层上下文压缩。这套方案适合正在做智能法律咨询、企业法务助手或律所接案预检的团队如果只是让DeepSeek写几句法律文案用不上这套东西但一旦做多轮对话状态管理就绕不过去。2. 对话管理框架选型与状态建模先给DeepSeek装一个案件事实记账本做多轮法律咨询第一个要回答的问题是用户上一轮透露的关键信息这一轮还在不在。有人图省事把每轮聊天记录原样塞给DeepSeek发现上下文窗口装不下之后就开始截断一截断就失忆。所以圈内通行的做法是先搭一个对话管理框架用状态机持续记录对话内容。这个框架本质上是模型外围的调度层它不让DeepSeek自由发挥记什么而是规定好哪些信息必须落盘。2.1 三种对话管理框架的取舍自研状态机、开源DMF与LLM编排引擎我身边做法律助手的团队基本在三条路线里选第一条是自研轻量状态机。把法律咨询流程建模成明确的状态转移每轮由状态机决定下一步追问什么DeepSeek只负责抽取用户回答里的字段并生成话术。优点是控制力极强用户说话再乱系统也不会乱问缺点是状态转移表要自己维护前期工作量大一点。第二条是用Rasa这类开源对话管理框架。槽位、故事、NLU组件都是现成的但接DeepSeek时要把框架内置的意图识别换成外部API调用适配层反而要写不少代码。更麻烦的是法律咨询里事实收集和法律分析混在一起用户不按顺序出牌Rasa的故事模板很难覆盖真实会话标注成本很高。第三条是用LangGraph这类LLM编排引擎把理解和生成全交给模型。灵活是真灵活但法律场景要审计、要可控编排引擎的决策路径是一个黑匣子出了责任问题不好回溯。用户问我的案子能赢吗这类框架很容易顺着话题开始编胜诉率。维度自研状态机RasaLLM编排引擎状态可控性高中高中多轮策略自定义灵活受故事模板约束灵活接入DeepSeek成本低中低出问题可回溯性好一般差适合场景流程固定的法律咨询标准客服任务开放域Agent我一般会选自研轻量状态机原因有三条法律咨询的核心对话流程其实不复杂就是收集事实、澄清诉求、给结论、补追问状态需要能导出和审计自研状态下每个字段的变更来源都清晰DeepSeek的接入成本很低状态机只需要调它的接口做抽取和生成。这套自研的东西说白了就是一个harness把DeepSeek夹在业务规则和输出约束之间不让它脱缰。2.2 法律咨询状态建模槽位、确认标记和事实链状态建模是对话管理框架里最花心思的部分。法律咨询不是填表单用户不会按顺序把入职时间、离职时间、是否签合同一条条报给你。他会先说结果再补背景中间还可能纠正自己。所以状态结构不能是一张死板的表得能承载说了什么、确认了什么、还没收集什么三层信息。from dataclasses import dataclass, field from typing import Dict, List, Optional, Set dataclass class LegalDialogState: dialog_id: str case_type: str # 案件类型劳动仲裁/借贷纠纷/婚姻家事 user_role: str # 用户身份劳动者/用人单位/债权人 counterparty: str # 对方当事人 key_facts: list field(default_factorylist) # 关键事实如未签合同 claims: list field(default_factorylist) # 用户诉求如要赔偿金 timeline: list field(default_factorylist) # 时间线事件按顺序追加 evidence: list field(default_factorylist) # 用户提到的证据 confirmed: Set[str] field(default_factoryset) # 已确认过的字段名逻辑说明这个类是对话管理框架里的案件事实记账本。key_facts和timeline不是单值槽位而是列表——因为法律咨询里同样一个重要事实可能分多次出现比如我签过合同和后来补充的合同是2022年签的应该合并成一条完整记录而不是互相覆盖。confirmed集合是专门为法律咨询设计的保护机制用户经常先说一个信息再纠正没有它模型就会把后轮随口带过的话当成事实覆盖掉前面认真确认过的内容。参数说明case_type、user_role、key_facts、claims是核心必填槽位生成回答前必须齐全timeline用来保留事件时序比如先被辞退、后主张加班费和在职期间提仲裁完全是两种法律路径evidence专门记用户说到的证据这一项在后续RAG检索法条时也会用到。confirmed不是给用户看的槽位它是内部状态机用的。槽位更新也不能无脑覆盖。用户说我是2020年入职的……不对是2021年如果模型直接往后写前面所有判断都会基于错误日期。所以更新逻辑要加一层确认锁def apply_slot_update(state: LegalDialogState, nlu_result: dict) - None: corrected set(nlu_result.get(corrected, [])) for field, value in nlu_result.get(slots, {}).items(): # 已确认字段只有用户明确纠正时才允许覆盖 if field not in state.confirmed or field in corrected: setattr(state, field, value) state.confirmed.add(field)逻辑说明nlu_result是DeepSeek解析完用户本轮发言后输出的结构化结果slots里面是它认为需要更新的事实字段corrected里面是它判断用户正在纠正的旧字段。这里的核心逻辑一句话——没有confirmed保护的字段随便更新已经被确认过的字段必须等用户明确纠正才解锁。参数说明corrected字段非常重要它的判定标准写在NLU提示词里要求解析器只有在用户说出不对其实更正一下这类信号时才返回。宁可漏判也不要误判漏判只是信息更新慢一步误判会把已经坐实的事实推翻后面整段回答跟着乱。2.3 DeepSeek在框架里的分工NLU走JSON抽取不让模型直接改状态状态机搭好之后接下来要解决DeepSeek怎么参与的问题。最忌讳的做法是让大模型直接改状态对象——模型输出不稳定可能编一个不存在的字段名也可能一次输出十个槽位把状态冲乱。我采用的分工方式是DeepSeek做NLU但只输出JSON状态机拿到JSON之后校验合法再落盘。from openai import OpenAI import json, os client OpenAI( api_keyos.getenv(DEEPSEEK_API_KEY), base_urlos.getenv(DEEPSEEK_BASE_URL, https://api.deepseek.com), ) NLU_PROMPT 你是对话状态解析器只做抽取不做法律答复。 从用户输入中提取法律咨询相关的槽位更新。 可选字段case_type, user_role, counterparty, key_facts, claims, evidence, corrected 必须输出 JSON格式 { intent: clarify_fact | answer_question | change_topic | provide_request | ask_followup, slots: {字段名: 更新值}, corrected: [被用户纠正的字段名] } 用户没有提供新信息时slots 返回空对象。 def parse_turn(user_input: str, dialog_id: str) - dict: resp client.chat.completions.create( modeldeepseek-chat, messages[ {role: system, content: NLU_PROMPT}, {role: system, content: f当前对话ID{dialog_id}}, {role: user, content: user_input}, ], temperature0, response_format{type: json_object}, ) return json.loads(resp.choices[0].message.content)逻辑说明parse_turn是状态机与DeepSeek之间的唯一数据出入口。模型只负责理解用户这句话表达了什么意图、更新哪些槽位、纠正了哪些旧信息不负责决定下一步对话走向。状态机拿到返回的JSON后先检查字段名是否在预定义列表里再走apply_slot_update落盘。这样即使模型某次抽取出错也只会错一个字段不会把整个状态搅乱。参数说明temperature必须写死为0NLU阶段任何随机性都不能容忍。response_format指定json_object让模型输出严格JSON省去正则提取的麻烦。intent的取值是封闭集合状态机会按这五种意图分流clarify_fact时进入追问流程answer_question时进入生成流程change_topic时清空本轮临时状态provide_request时更新claimsask_followup时把用户的追问追加为新的需要澄清的事项。这种分工带来的最大收益是可复盘。对话出问题时打开状态机的日志能清楚看到哪一轮、哪个槽位、由哪条用户输入触发更新。DeepSeek在里面只是一个翻译官把口语翻译成结构化的状态变更决策权始终握在自己手里。3. 多轮上下文理解把七零八落的聊天记录整理成一条事实链状态机解决了关键信息不丢但模型要生成好回答还需要看到上下文顺序。用户是先被辞退再主张加班费还是在职期间就提了仲裁这些时序在槽位里看不出来。所以上下文理解要做的事情是在状态机之外维护一条事实链把聊天记录变成可回溯、可压缩的素材而不是一坨越攒越长的流水账。3.1 上下文窗口是硬约束三层记忆而不是一条流水账DeepSeek的上下文窗口虽然不小但法律咨询用户经常贴合同原文、贴仲裁裁决书一贴就是几千字。加上前面十来轮对话一次请求轻松冲破模型的处理预算。更现实的问题是长上下文的注意力会被稀释模型看到第8000个token时早就忘了第200个token里那句我没签合同。所以我在这个项目里用的是三层记忆而不是简单地把所有历史塞进去。记忆层内容上限状态层槽位快照confirmed标记固定约200 token摘要层被挤出窗口的旧轮压缩摘要控制在400 token滚动层最近4~6轮原文原文保留约1500 token状态层每轮必带它是系统记忆的主干滚动层保留最近几轮原文让模型能看到最近的语气和未尽事宜摘要层兜底把更早的历史压成事实链。三层一起拼进请求既控成本又保证关键事实永不被挤出去。只做滚动窗口是很多项目翻车的根源因为用户在第2轮提到的关键信息到第10轮早就被冲走了。3.2 法律口语的指代消解与归一化抽槽时就把他翻译出来法律咨询的口语化程度远超预期。用户不会说用人单位只会说老板公司他们那边不会说相对方只会说对方。如果不做归一化状态里会出现老板和公司两个不同的实体模型在后续判断时会把人搞混。这里的常见做法是在NLU阶段顺带做实体归一化让DeepSeek在抽槽时就把指代展开ENTITY_NORMALIZE_RULES 实体归一化规则 - 老板/公司/单位/他们工作场景→ 用人单位 - 员工/我/本人 → 劳动者当user_role为空时 - 中介/劳务公司/外包 → 第三方用工单位 - 法院/仲裁委 → 裁判机构除非用户特指某一家 def parse_turn(user_input: str, dialog_id: str) - dict: messages [ {role: system, content: NLU_PROMPT ENTITY_NORMALIZE_RULES}, {role: system, content: f当前对话ID{dialog_id}}, {role: user, content: user_input}, ] resp client.chat.completions.create( modeldeepseek-chat, messagesmessages, temperature0, response_format{type: json_object}, ) return json.loads(resp.choices[0].message.content)逻辑说明这版parse_turn在原来的NLU提示词后面拼接了实体归一化规则。关键点在于归一化发生在状态更新之前而不是生成回答的时候。如果拖到生成阶段再改模型输出里就会跟着用户说老板不给我钱整个回答的法言法语风格就垮了。参数说明归一化规则要根据业务领域维护。劳动法场景维护一套映射婚姻家事又是另一套比如老公/老婆/对象要归一成配偶。这类规则不需要穷举抓到出现频率最高的前20个口语称呼就够了剩下的让DeepSeek根据上下文理解后填一个标准名称进槽位。3.3 一个可落地的上下文压缩实现摘要函数压缩这条事实链不能简单地截断截断等于丢失。我的做法是让DeepSeek自己对旧历史做一次摘要再把摘要作为一条system消息拼回上下文。这样旧信息不是被删掉而是被提炼了。def compress_history(history: list, max_rounds: int 6, llm_clientNone) - list: if len(history) max_rounds: return history keep_recent max_rounds // 2 older history[:-keep_recent] recent history[-keep_recent:] compress_prompt ( 你是法律对话摘要器。把下列对话历史压缩成事实链摘要要求\n 1. 只保留用户陈述过的事实、时间和诉求不要推断结论\n 2. 保留对话里的更正信息例如更正入职时间是2020年\n 3. 输出不超过200字的连续文本不要用列表。\n\n 对话历史\n json.dumps(older, ensure_asciiFalse) ) resp llm_client.chat.completions.create( modeldeepseek-chat, messages[{role: user, content: compress_prompt}], temperature0.2, max_tokens400, ) summary resp.choices[0].message.content ctx f对话历史摘要早于近{keep_recent}轮{summary} return [{role: system, content: ctx}] recent逻辑说明这个函数把历史切成两段前半段压缩成摘要后半段保留原文。返回结果里第一条是一条system消息后面是最近几轮原文。放在system位置是因为摘要的优先级最低模型会优先参考后面靠近用户输入的原文摘要只作为背景信息避免摘要里的某句话被模型误当成最新指令。参数说明max_rounds取6比较均衡保留最近3轮原文其余全压。如果业务上需要更强的连贯性可以调到8但要付出更多token成本。摘要的temperature设0.2比NLU稍高一点允许摘要语言有一点变化但绝不能高到0.5以上否则摘要会开始加戏。提示词里那句不要推断结论是防幻觉的关键不加这句模型经常把用户没签合同推断成单位违法摘要就带偏了。4. 精准应答生成用参数、模板和状态把DeepSeek的回答约束在法律边界内上下文理顺了下一步是精准应答生成。这一步的精准有两层意思一是事实准确回答必须基于已确认的槽位不能张冠李戴二是表达合规不能给用户承诺结果不能编造法条。两者单靠模型自觉都做不到得靠参数、提示词和生成后校验一起压。4.1 法律场景的生成参数temperature、top_p和max_tokens怎么设参数推荐值作用反例temperature0.1~0.3控制随机性0.8时同一问题两次给出相反结论top_p0.85~0.95缩小候选词池过高时冒出罕见表达max_tokens800~1200限制回答长度太长时车轱辘话来回说法律咨询场景必须用低温和低top_p原因是用户要的是可复现的答案。同一问题上午问和下午问结论应该一致换一种问法核心判断也不能变。客服场景可以把temperature调到0.8让回复显得更活泼法律场景这么做就是事故。我遇到过真实翻车案例早期接DeepSeek时temperature设了0.7用户同一句我这种情况能要赔偿吗连问两次第一次回答可以主张经济补偿金第二次变成需要看合同约定建议协商解决。用户直接截图投诉说系统胡扯。压到0.2之后这类随机漂移基本消失。调参时还有个实用技巧用开发工具接DeepSeek跑实验。常见做法是在Codex或VS Code里按OpenAI兼容接口配置好DeepSeek的端点改一版prompt跑一版样例比在Web页面里反复手测效率高得多。参数和提示词是配套调的只改参数不改提示词很难看出真实效果。4.2 三段式提示词模板与结构化输出结论、依据、追问提示词模板是精准应答的主战场。法律咨询的回答不能是自由散文我给DeepSeek定的模板是固定三段结论、依据、行动建议。三段都不齐就不算一次合格回答。同时要求缺失关键事实时模型必须先追问不能硬答。SYSTEM_PROMPT 你是法律咨询助手DeepSeek回答必须遵守 1. 结构固定为三段结论、法律依据、行动建议 2. 结论必须基于已确认的案件事实关键事实缺失时不要下结论改为追加提问 3. 法律依据只写法律规定名称记得条文号可以写不确定时必须笼统表述 4. 禁止承诺性表述如肯定能赢胜诉率百分之XX 5. 输出JSON字段为 conclusion, legal_basis, actions, risk, followup_questions。 当前案件事实快照{state_snapshot} 对话历史摘要{history_summary}JSON输出schema固定如下状态机会按这个结构解析{ conclusion: 可以主张经济补偿金, legal_basis: [《劳动合同法》相关条款], actions: [收集工资流水和解除通知, 向劳动仲裁委员会申请仲裁], risk: 仲裁时效可能已过建议尽快启动, followup_questions: [你入职时是否签订过书面合同] }逻辑说明JSON结构不是给用户看的是给工程层用的。前端拿到conclusion渲染成正文拿到legal_basis渲染成引用样式拿到risk弹一个风险提示条。更关键的是它给了生成后校验一个抓手——如果legal_basis是空数组系统就知道模型没找到依据要走人工介入流程如果risk缺失说明模型漏了风险提示直接拒绝渲染。参数说明followup_questions是保证多轮质量的关键字段模型每次回答都要带上下一轮该追问的问题。这样对话不会在用户回一句好的之后就冷场。提示词里不确定时必须笼统表述这句话是防法条幻觉的第一道防线写得越死模型越不敢编条文号。4.3 完整的多轮应答生成实现状态驱动而不是聊天记录驱动把前面的模块串起来就是一个可以直接跑的最小实现。它和把历史聊天记录全丢给DeepSeek的核心区别在于生成用的上下文是状态快照摘要最近对话不是单纯的聊天流水账。def handle_turn(state, history, user_input): # 第一步NLU解析并更新状态 nlu parse_turn(user_input, state.dialog_id) apply_slot_update(state, nlu) # 第二步缺关键事实时优先追问不让模型硬答 if not state.confirmed.issuperset({case_type, user_role, key_facts, claims}): missing [f for f in [case_type, user_role, key_facts, claims] if f not in state.confirmed] return build_clarify_question(missing, state) # 第三步组装三层上下文 messages [ {role: system, content: SYSTEM_PROMPT.format( state_snapshotjson.dumps(state.__dict__, ensure_asciiFalse), history_summarysummarize_or_load(history) )}, {role: user, content: user_input}, ] # 第四步调用DeepSeek生成结构化答案 resp client.chat.completions.create( modeldeepseek-chat, messagesmessages, temperature0.2, top_p0.9, max_tokens1000, response_format{type: json_object}, ) answer json.loads(resp.choices[0].message.content) # 第五步生成后合规校验 answer post_check(answer, state) return answer逻辑说明这个函数把前面的状态机和NLU全部串起来了。第一步让DeepSeek看懂用户这句话并更新记账本第二步是不硬答策略四个必填槽位没集齐就走澄清分支宁可多问一句也不给半吊子结论第三步组装上下文历史摘要和状态快照都在system层第五步的post_check在返回前端之前把答案过一遍合规规则。参数说明temperature和top_p沿用了4.1的推荐值max_tokens设1000是为了给三段式回答留够空间同时避免无限输出。第二步的澄清分支是精准应答的精髓——很多团队把精准理解成答案精准其实在信息不全时精准地追问比精准地瞎猜更重要。post_check内部做三件事检查legal_basis数组是否为空、用正则扫一遍胜诉率肯定能这类词、确认risk字段存在。任何一项不过就追加对应提示后重新生成一次或降级到人工话术。5. 避坑与排查法律对话系统上线前最容易翻车的5个问题这一章写的都是这个类型项目里反复出现的问题每条按现象、原因、解决拆开基本都能在你自己的系统里复现一遍。5.1 第二轮就失忆让模型背历史是偷懒方案现象用户第一轮说我在工地摔伤第二轮问我可以报工伤吗回答里完全不提工地甚至按交通事故给了一通建议。原因实现时只把最近两轮聊天记录塞给模型早期轮次的关键事实已经不在上下文里或者压缩摘要时丢了关键实体。解决关键事实在NLU阶段就必须写进槽位并在每轮system里注入案件事实快照。聊天记录只是参考槽位才是主记忆。血泪经验早期版本只靠滚动窗口用户提到的重要信息一旦被挤出窗口系统就开始胡说。做了状态层之后失忆问题基本绝迹。5.2 法条幻觉模型编出一个不存在的条文号现象回答里出现根据《劳动合同法》第九十八条实际该条是别的主题用户一查就露馅。原因大模型的参数记忆不可靠条文号是最容易被幻觉化的部分训练数据里的法条差异和更新会让模型记串。解决三层兜底。第一层提示词要求不确定时不写条文号第二层生成后做规则校验用正则匹配第.*条在本地法条库里查不到就替换成法律名称第三层有条件时接法条检索接口把命中的候选条文原文送进模型让模型基于原文引用而不是凭记忆。5.3 追问偏航用户说我不是这个意思现象系统像审问一样连问三四个问题用户不回答或者回答一句后系统发现完全理解偏了。原因意图识别是单轮的状态机没有澄清-回退机制槽位更新策略太激进把用户随口带过的话当成新事实覆盖了旧事实。解决在NLU输出里增加一个confusion意图。DeepSeek判断用户回答与问题无关时状态机先触发澄清而不是更新槽位。同时给每个槽位加confirmed确认标记只有用户明确说不对其实才解锁覆盖。confusion意图的prompt写法很简单如果用户没有回答你的问题而是说了其他内容intent返回confusion。5.4 Token成本失控请求体越来越胖现象对话到第15轮时每次请求要带上全部历史响应时间从1秒涨到3秒账单额度肉眼可见地往下掉。原因没有压缩策略历史记录只增不减每轮都送全量上下文。法律场景里用户还会贴长文本翻车更快。解决用第3章的compress_history做分层压缩。我踩过这个坑之后给自己定了一条硬规则——单次生成请求的token预算控制在2000以内超了就把历史交付给摘要层。最近6轮保留原文更早的全部提炼。这样既保住了关键事实又控制住了费用。5.5 合规红线模型承诺了胜诉率现象用户问我能不能赢模型回答胜诉率90%。这在法律行业是严重合规事故律师都不敢这么打包票。原因prompt里没有边界设定产品上也没有免责兜底。模型在生成时顺着用户的话头往下滚越滚越具体最后落到一个本来就不该给的数字上。解决系统提示词显式禁止承诺性表述结构化输出的risk字段做成必填。UI侧固定展示本回答不构成正式法律意见的免责声明。如果接入了RAG要把这条免责声明固化成最高优先级的system约束任何生成前都注入。校验脚本里加一条正则匹配胜诉率|一定能赢|稳赢就拦截重生成。6. 验证与进阶用10个多轮场景评测你的法律助手再向RAG演进多轮对话系统的验证不能靠看几个例子感觉还行。我的做法是维护一套多轮场景评测集每次改完prompt或状态机就跑一遍回归。6.1 十场景评测集与回归验证评测集按业务高频方向建了10组场景劳动争议3个、借贷纠纷2个、婚姻家事2个、劳动报酬2个、侵权1个。每个场景设定一个用户隐藏的真实诉求标注每轮期望的追问方向、最终结论类型和必须被状态机记录的关键事实。跑回归的方式很简单拿这10组对话从头跑一遍对比输出满足度指标计算方式合格线槽位准确率每轮NLU提取槽位与标注一致的比例85%关键事实召回结束时状态机里关键事实占标注的比例95%回答合规率无承诺性表述且结构合法的回答比例100%任务完成率达成场景预设目标的对话比例80%平均轮次完成一个场景需要的对话轮数≤8轮这套评测跑一遍通常只要几分钟但能挡住大多数隐蔽回归。尤其是改提示词后你肉眼看着新版本更好评测集却会告诉你某个场景的追问方向已经偏了。6.2 向RAG与私有化部署演进进阶方向是把这个方案接到RAG上。多轮法律咨询的RAG设计和普通知识问答有个关键区别检索query不能用用户原话要用状态快照生成。用户问赔偿能要多少但状态里记录的是劳动仲裁、未签合同那检索词就应该是未签订劳动合同 经济补偿金 计算标准这样才查得到对症的法条。数据安全方面法律咨询数据敏感能私有化部署就私有化部署。DeepSeek支持本地部署但小参数模型做法律分析能力有限常见的分层方案是本地小模型做槽位抽取和敏感信息脱敏远程大模型做最终生成。这样既守住了数据安全底线又保住了回答质量。做这个方案给我最大的教训是对话系统不能过度相信模型的临场发挥法律咨询尤其如此。每次改完对话策略我第一件事不是看演示例句而是把那10个场景的回归脚本跑一遍看有没有哪个场景因为一句prompt改动就偏了。这个习惯替我挡掉了好几次上线事故。希望帮到你。本文还有配套的精品资源点击获取
返回列表