Vidura开源框架:模块化AI对话编排与自动化评估实战指南

news2026/5/9 3:30:03
1. 项目概述一个开源的AI对话编排与评估框架最近在折腾AI应用开发特别是涉及到多模型对话、复杂工作流编排和效果评估时总感觉市面上现成的工具要么太重要么太零散。直到我发现了Vidura这个项目它像是一套为AI对话系统量身定制的“乐高积木”和“质检工具”的结合体。简单来说Vidura是一个开源框架它允许开发者以一种结构化的方式去设计、编排、执行和评估复杂的AI对话流程。想象一下这样的场景你需要构建一个客服机器人它不仅要能理解用户意图可能还需要根据对话内容去查询数据库、调用外部API获取实时信息最后再调用合适的AI模型比如GPT-4、Claude或者本地部署的Llama生成回复并且你还需要一套机制来评估这个回复的质量。如果每个环节都自己从头搭建光是处理不同模型API的差异、管理对话状态、设计评估指标就够头疼了。Vidura的价值就在于它把这些繁琐但通用的部分抽象出来提供了统一的接口和模块化的组件让你能更专注于业务逻辑本身。这个项目适合谁呢我认为主要面向几类人一是正在构建复杂AI对话应用的开发者或团队尤其是那些需要混合调用多个AI模型、集成外部工具的场景二是需要对AI对话效果进行系统性评估和迭代的研究人员或产品经理三是任何对AI Agent、工作流自动化感兴趣想学习现代AI应用架构的爱好者。即使你只是用一个模型做简单的对话Vidura里关于评估和数据集管理的部分也极具参考价值。2. 核心架构与设计理念拆解2.1 模块化与可插拔的设计哲学Vidura的核心设计思想非常清晰解耦与组合。它没有试图做一个大而全的、封闭的对话系统而是将整个对话生命周期拆解成一系列独立的、功能单一的模块。这种设计带来的最大好处就是灵活性。你可以像搭积木一样根据你的需求选择不同的模块进行组合。整个框架大致可以划分为几个核心层编排层Orchestration Layer这是大脑负责定义对话的流程。比如是先进行意图识别还是先查询知识库判断条件是什么Vidura允许你使用YAML或Python来定义这些工作流工作流由一个个节点Node组成节点之间通过边Edge连接清晰地描述了执行路径和逻辑分支。组件层Component Layer这是执行具体任务的“工人”。每个节点在运行时实际上是在调用一个或多个组件。组件是具体功能的实现例如模型组件封装了对OpenAI、Anthropic、Cohere等云端模型API的调用或者对本地Ollama、vLLM等推理引擎的调用。统一了输入输出格式。工具组件用于执行具体操作比如计算器、网络搜索、数据库查询、调用企业内部API等。这赋予了AI“动手能力”。记忆组件管理对话历史决定哪些历史消息需要被保留并送入模型的上下文窗口这是实现多轮连贯对话的关键。评估组件用于对模型输出或整个对话流程进行打分、分类或分析。评估与数据集层Evaluation Dataset Layer这是Vidura非常出彩的部分。它内置了一套评估系统允许你定义评估标准例如相关性、安全性、事实准确性并使用AI模型甚至是另一个模型或规则来自动化评估。同时它提供了数据集管理功能你可以方便地导入、创建用于测试和评估的对话数据集。这种模块化设计意味着当你需要更换一个AI模型提供商时可能只需要修改配置文件中模型组件的API密钥和端点而无需触动任何业务流程代码。当需要增加一个新功能如情感分析时你只需要开发一个新的组件并将其插入到工作流的合适节点即可。2.2 基于有向无环图DAG的工作流引擎Vidura底层的工作流引擎通常基于有向无环图DAG的概念。这是现代任务编排系统如Apache Airflow的常见模式将其应用于AI对话编排非常贴切。在一个对话DAG中节点Node代表一个原子操作例如“调用GPT-4生成回复”、“使用工具查询天气”、“根据关键词检索知识库”。边Edge代表节点之间的依赖关系和执行顺序。边可以带有条件例如“如果用户情绪为负面则跳转到安抚流程节点”。这种图示化的思维方式让复杂的对话逻辑变得直观且易于维护。你可以清晰地看到用户输入后数据是如何在各个处理单元间流动的最终又是如何汇聚成回复的。对于调试和优化流程来说这比跟踪一堆嵌套的if-else语句要高效得多。实操心得在初期设计工作流时不要急于写YAML或代码。先用纸笔画出一个简单的DAG草图明确每个节点的输入、输出以及分支条件。这能帮你理清思路避免设计出循环依赖或逻辑死角。Vidura的这类设计强迫开发者进行结构化思考这本身就是一个很好的实践。3. 核心组件深度解析与配置要点3.1 模型组件的统一与抽象模型组件是Vidura与AI模型交互的桥梁。它的核心价值在于统一了异构模型的调用接口。不同的模型API在参数命名、请求格式、响应结构上各有不同。Vidura的模型组件抽象层帮你处理了这些差异。一个典型的模型组件配置可能长这样以YAML为例components: - name: gpt-4-turbo-chat type: model provider: openai config: model: gpt-4-turbo api_key: ${env.OPENAI_API_KEY} temperature: 0.7 max_tokens: 1024 system_prompt: “你是一个专业的客服助手回答要简洁、准确、友好。”这里的关键点provider指定了后端服务商如openai、anthropic、cohere、ollama本地等。Vidura需要为每个provider实现对应的适配器。config这里的参数会映射到对应API的实际参数。temperature、max_tokens这些是通用概念适配器会负责将其翻译成目标API的特定字段。system_prompt这是一个非常重要的配置。它定义了模型的“角色”和基础行为准则。好的system prompt能极大提升对话的稳定性和质量。建议将其作为可配置的变量针对不同场景的工作流使用不同的prompt。注意事项对于api_key等敏感信息务必像示例中一样通过环境变量${env.XXX}引用绝对不要硬编码在配置文件中。你可以创建一个.env文件来管理所有密钥并在启动应用时加载。3.2 工具组件的扩展与实践工具组件让AI从“聊天脑”变成了“执行手”。Vidura的工具组件遵循一个通用的模式定义工具的功能描述供AI模型理解并实现具体的执行函数。例如创建一个获取股价的工具# 伪代码示例说明概念 from vidura.sdk import ToolComponent class GetStockPriceTool(ToolComponent): name “get_stock_price” description “获取指定股票代码的当前价格。输入应为股票代码如‘AAPL’。” def execute(self, input_data: str) - str: # input_data 会是 “AAPL” stock_code input_data # 这里调用真实的金融数据API price call_finance_api(stock_code) return f”股票 {stock_code} 的当前价格是 {price} 美元。”在工作流中你可以设计一个节点先让模型判断用户是否在询问股价如果是则提取股票代码然后调用这个GetStockPriceTool组件最后将工具返回的结果再交给模型让其组织成一句人话回复给用户。工具设计的关键描述要清晰准确description字段会被送入模型的上下文帮助模型理解何时该调用此工具。描述应明确说明输入格式和工具功能。输入输出要稳定工具的执行函数应能处理各种边界情况如无效输入并返回结构化的结果。返回纯文本通常是最兼容的方式。安全性工具能访问外部系统或网络必须加入权限控制和输入验证防止被恶意利用。3.3 记忆组件的策略与实现记忆管理是对话系统的核心难题。Vidura的记忆组件通常提供多种策略完整历史保存所有对话轮次。简单但消耗上下文窗口快。滑动窗口只保留最近N轮对话。平衡了记忆和效率。摘要记忆定期或按需将过往对话总结成一段摘要然后将摘要和近期对话一起送入上下文。这是处理长对话的先进策略。向量记忆将对话片段转换成向量存入向量数据库根据当前查询进行语义检索找回相关记忆。这适合知识密集型对话。在Vidura中配置记忆组件你需要关注几个参数memory_type: 选择上述策略之一。window_size: 如果是滑动窗口指定窗口大小。summary_model: 如果使用摘要记忆指定用于生成摘要的模型可以是一个更小、更快的模型。实操心得对于大多数客服或问答场景“滑动窗口关键信息提取”是一个不错的起点。例如在对话中自动提取用户姓名、订单号等实体信息并将其作为独立于对话窗口的“长期记忆”存储在后续对话中显式注入。这比单纯依赖模型的上下文记忆更可靠。4. 从零构建一个客服工作流实操全流程让我们通过一个具体的例子看看如何用Vidura构建一个简单的智能客服工作流处理“查询订单状态”和“产品咨询”两类问题。4.1 环境准备与项目初始化首先确保你的Python环境建议3.9以上并安装Vidura。通常可以通过pip安装其核心包或者从GitHub克隆仓库进行本地开发。# 假设vidura已发布到PyPI pip install vidura-core # 或者从源码安装 git clone https://github.com/narenaryan/Vidura.git cd Vidura pip install -e .接下来创建你的项目目录结构。一个清晰的结构有助于管理my_customer_service/ ├── configs/ │ ├── workflow.yaml # 主工作流定义 │ └── models.yaml # 模型配置 ├── components/ │ ├── custom_tools.py # 自定义工具组件 │ └── __init__.py ├── data/ # 存放测试数据集 ├── .env # 环境变量API密钥等 └── main.py # 应用入口在.env文件中设置你的API密钥OPENAI_API_KEYsk-your-key-here ANTHROPIC_API_KEYyour-claude-key-here4.2 定义工作流与组件配置在configs/workflow.yaml中定义我们的客服DAGname: customer_service_workflow description: 一个处理订单查询和产品咨询的客服工作流。 components: # 定义模型组件 - name: classifier_model type: model provider: openai config: model: gpt-3.5-turbo # 用便宜快速的模型做分类 temperature: 0.1 # 低随机性保证分类稳定 system_prompt: “你是一个意图分类器。请将用户问题分类为‘order_status’查询订单状态、‘product_inquiry’产品咨询或‘other’其他。只输出类别名称。” - name: main_chat_model type: model provider: openai config: model: gpt-4-turbo temperature: 0.7 system_prompt: “你是一家科技公司的专业客服代表态度热情、乐于助人。请根据提供的信息回答用户问题。” # 定义工具组件假设我们已经实现 - name: order_lookup_tool type: tool class_path: “components.custom_tools.OrderLookupTool” # 指向自定义类 - name: product_db_tool type: tool class_path: “components.custom_tools.ProductDatabaseTool” workflow: start_node: classify_intent nodes: - id: classify_intent type: component component: classifier_model inputs: user_input: “{{ user_message }}” outputs: intent: “{{ model_response }}” - id: handle_order_status type: component component: order_lookup_tool inputs: order_id: “{{ extracted_order_id }}” # 假设前面有节点提取了ID outputs: order_info: “{{ tool_result }}” conditions: - when: “{{ parent.classify_intent.outputs.intent }} ‘order_status’” then: proceed - id: handle_product_inquiry type: component component: product_db_tool inputs: product_name: “{{ extracted_product_name }}” outputs: product_details: “{{ tool_result }}” conditions: - when: “{{ parent.classify_intent.outputs.intent }} ‘product_inquiry’” then: proceed - id: generate_final_response type: component component: main_chat_model inputs: # 动态构造输入根据意图组合不同的上下文信息 context: | 用户问题{{ user_message }} {% if intent ‘order_status’ %} 订单信息{{ order_info }} {% elif intent ‘product_inquiry’ %} 产品信息{{ product_details }} {% endif %} 请生成回复。 outputs: final_response: “{{ model_response }}”这个YAML定义了一个清晰的工作流classify_intent节点先用小模型对用户问题进行分类。根据分类结果条件性地执行handle_order_status或handle_product_inquiry节点调用相应的工具获取真实数据。最后generate_final_response节点汇集原始问题、意图和工具查询结果交给主模型GPT-4生成友好、准确的最终回复。4.3 实现自定义工具组件现在我们需要在components/custom_tools.py中实现用到的工具。这里以OrderLookupTool为例import logging from typing import Any, Dict from vidura.sdk import ToolComponent # 模拟一个订单数据库 MOCK_ORDER_DB { “ORD123456”: {“status”: “已发货”, “estimated_delivery”: “2023-10-27”, “items”: [“手机X1”]}, “ORD654321”: {“status”: “处理中”, “estimated_delivery”: “2023-11-05”, “items”: [“耳机Y1”]}, } class OrderLookupTool(ToolComponent): name “order_lookup” description “根据订单号查询订单状态和预计送达时间。输入应为订单号字符串。” def execute(self, input_data: str, **kwargs) - Dict[str, Any]: order_id input_data.strip().upper() logging.info(f”正在查询订单: {order_id}“) if order_id in MOCK_ORDER_DB: order_info MOCK_ORDER_DB[order_id] return { “success”: True, “order_id”: order_id, “status”: order_info[“status”], “estimated_delivery”: order_info[“estimated_delivery”], “items”: order_info[“items”] } else: return {“success”: False, “error”: “未找到该订单号”, “order_id”: order_id} # 可选定义一个后处理函数将返回的字典格式化成给模型看的文本 def format_for_model(self, result: Dict[str, Any]) - str: if result[“success”]: items “, “.join(result[“items”]) return f”订单 {result[‘order_id’]} 状态为‘{result[‘status’]}’预计送达时间 {result[‘estimated_delivery’]}。包含商品{items}。” else: return f”抱歉未找到订单 {result[‘order_id’]}请核对订单号是否正确。”在实际生产中execute方法内部会替换为对真实订单数据库或API的调用。format_for_model方法是一个好实践它确保了工具返回的信息以一种易于模型理解和利用的格式呈现。4.4 运行与测试工作流最后在main.py中编写加载和运行工作流的代码import asyncio import os from dotenv import load_dotenv from vidura import ViduraEngine # 加载环境变量 load_dotenv() async def main(): # 初始化引擎指定配置文件路径 engine ViduraEngine(config_path“./configs/workflow.yaml”) # 测试对话 test_messages [ “我的订单ORD123456到哪里了”, “你们新出的旗舰手机有什么颜色”, “今天天气怎么样” ] for msg in test_messages: print(f”\n 用户输入: {msg} ) # 执行工作流传入初始用户输入 result await engine.execute(initial_input{“user_message”: msg}) # 获取最终响应 final_response result.get(“final_response”, “未生成回复”) print(f”客服回复: {final_response}“) # 你也可以查看中间结果用于调试 # print(f”完整结果: {result}“) if __name__ “__main__”: asyncio.run(main())运行这个脚本你会看到工作流如何根据不同的用户输入走不同的分支路径并生成相应的回复。对于“今天天气怎么样”这种“other”类问题由于我们没有设计处理分支最终回复可能会由main_chat_model根据其系统提示直接生成一个通用回应如“我主要处理订单和产品咨询暂时无法查询天气”。5. 评估系统如何衡量与优化你的对话AI构建了工作流只是第一步如何知道它表现得好不好Vidura的评估系统提供了答案。评估不是一次性的而应是一个持续的迭代循环构建 - 评估 - 分析 - 改进。5.1 定义评估指标与评估器评估始于定义清晰的指标。Vidura通常支持多种评估器EvaluatorAI即评估器使用一个AI模型如GPT-4来评估另一个AI的输出。例如给出问题、参考答案和实际回答让GPT-4从“相关性”、“有帮助性”、“准确性”等维度打分1-5分。这种方法灵活但成本较高且可能不稳定。规则评估器基于正则表达式、关键词匹配或逻辑判断。例如检查回复中是否包含“订单号”等敏感信息不应出现或者回复长度是否在合理范围内。自定义评估器你可以编写任何Python函数作为评估器例如调用一个外部的情感分析API来判断回复语气是否友好。在配置中定义评估指标可能如下所示evaluation: metrics: - name: relevance evaluator: llm_as_judge config: judge_model: gpt-4-turbo criteria: “评估回复是否与用户问题直接相关。完全相关得5分完全不相关得1分。” scoring_range: [1, 5] - name: contains_pii evaluator: regex config: patterns: [“\d{18}“, “\d{4}-\d{4}-\d{4}-\d{4}“] # 匹配身份证、信用卡号等 action: “penalize” # 如果匹配到则扣分 - name: response_length evaluator: custom class_path: “my_evaluators.LengthEvaluator” config: min_words: 5 max_words: 2005.2 创建与管理测试数据集没有数据评估就是无源之水。Vidura鼓励你建立结构化的测试数据集。数据集通常是一个JSON或CSV文件每一行代表一个测试用例。// test_dataset.json [ { “id”: “test_case_1”, “user_input”: “订单ORD123456的状态是什么”, “expected_intent”: “order_status”, “expected_entities”: {“order_id”: “ORD123456”}, “expected_response_contains”: [“已发货”, “预计送达”] // 期望回复包含的关键词 }, { “id”: “test_case_2”, “user_input”: “手机电池能用多久”, “expected_intent”: “product_inquiry”, “expected_response_contains”: [“续航”, “小时”, “电池容量”], “forbidden_words”: [“不知道”, “无法回答”] // 回复中不应出现的词 } ]你可以使用Vidura的命令行工具或API将整个数据集灌入你的工作流进行批量测试并自动收集每个测试用例在所有评估指标上的得分。5.3 执行评估与结果分析运行评估后你会得到一份详细的报告。一份好的评估报告不仅仅是平均分更应该帮你定位问题。报告应包含总体得分各指标的平均分、中位数、分布情况。案例级详情每个测试用例的输入、实际输出、各指标得分。对于得分低的案例要能直接查看。错误归类自动或手动将失败案例归类如“意图识别错误”、“工具调用失败”、“回复不相关”、“包含禁语”等。对比分析如果你调整了系统提示prompt或工作流可以对比新旧版本的评估结果量化改进效果。实操心得不要盲目追求所有指标都得高分。根据你的场景确定核心指标。对于一个客服机器人“准确性”和“安全性”不泄露信息、不说错话的权重应该远高于“创造性”。初期可以设置一个“红线指标”比如“contains_pii”必须为0分任何触发的案例都需要最高优先级修复。评估是一个持续的过程建议将评估脚本集成到你的CI/CD流程中每次代码更新都自动跑一遍核心测试集。6. 部署、监控与性能调优实战6.1 部署模式选择开发完成后你需要将Vidura应用部署出去。根据负载和场景有几种选择脚本/CLI模式最简单的方式就像我们上面的main.py。适合内部工具、一次性任务或评估批处理。使用nohup或systemd即可在服务器后台运行。Web API服务最常用的模式。Vidura通常提供将工作流暴露为HTTP端点的能力。你可以使用FastAPI、Flask等框架快速包装引擎。# 使用FastAPI的简单示例 from fastapi import FastAPI from vidura import ViduraEngine import asyncio app FastAPI() engine None app.on_event(“startup”) async def startup_event(): global engine engine ViduraEngine(config_path“./configs/workflow.yaml”) # 可以在这里进行预加载等操作 app.post(“/chat”) async def chat_endpoint(request: dict): user_message request.get(“message”, “”) session_id request.get(“session_id”, “default”) try: result await engine.execute( initial_input{“user_message”: user_message}, session_idsession_id # 用于关联对话记忆 ) return {“response”: result.get(“final_response”, “”), “status”: “success”} except Exception as e: return {“response”: “”, “status”: “error”, “detail”: str(e)}部署时使用Gunicorn配合Uvicorn for ASGI或Uvicorn直接作为生产服务器。务必使用反向代理如Nginx处理SSL、负载均衡和静态文件。集成到现有应用将Vidura引擎作为你现有Python应用的一个模块导入和调用灵活度最高。6.2 关键监控指标与日志上线后监控至关重要。你需要关注性能指标延迟每个工作流或关键节点的平均响应时间P50 P95 P99。使用Prometheus Grafana进行采集和可视化。吞吐量每秒能处理的请求数QPS。错误率API调用失败、模型调用超时、工具执行异常的比例。业务/质量指标意图分布各类用户意图的比例帮你了解用户主要需求。工具调用成功率外部API或数据库查询的成功率。评估分数趋势定期如每天用测试集跑一次评估观察分数是否下降及时发现模型退化或流程问题。日志实施结构化日志如JSON格式记录每个请求的session_id、user_input、intent、tool_calls、final_response以及latency。这不仅是调试的黄金数据也是后续优化训练数据的来源。确保日志中不记录任何真实的个人身份信息PII。6.3 性能调优与成本控制随着用量增长性能和成本会成为焦点。性能调优方向缓存对频繁且结果不变的查询进行缓存。例如产品信息、常见问答对。可以在工具组件内部实现也可以在Vidura工作流前加一层缓存中间件。异步与非阻塞确保你的自定义工具组件和模型调用是异步的使用async/await避免阻塞事件循环。Vidura的核心引擎通常基于异步框架构建。节点并行化检查你的工作流DAG如果某些节点间没有依赖关系可以配置它们并行执行减少整体延迟。模型降级并非所有任务都需要GPT-4。像意图分类、实体提取这类相对简单的任务完全可以使用GPT-3.5 Turbo甚至更小的开源模型在保证效果的同时大幅降低成本。成本控制策略用量监控与告警密切监控各AI模型的token消耗设置每日或每月预算告警。大多数云服务商都提供此功能。上下文长度管理这是成本大头。积极使用前面提到的摘要记忆或向量检索记忆尽可能减少送入模型的冗余历史token。定期清理对话记忆。设置超时与重试为模型API调用和工具调用设置合理的超时时间。对于可重试的错误如网络抖动实施带退避策略的重试机制避免因临时故障导致不必要的失败和用户体验下降。评估成本自动化评估虽然好但用GPT-4评估GPT-3.5的输出评估成本可能比执行成本还高。考虑使用更便宜的模型如Claude Haiku做初步评估或增加规则评估的比例。7. 常见问题排查与调试技巧实录在实际使用中你肯定会遇到各种问题。以下是一些典型问题及其排查思路来自我个人的踩坑经验。7.1 工作流执行失败或卡住症状请求无响应或日志显示在某个节点后停止。排查步骤检查节点依赖与条件确认DAG中没有形成循环依赖。检查每个条件conditions语句的逻辑是否正确确保至少有一条路径可以到达终点。一个常见的错误是条件设置过于严格导致所有路径都被阻断。检查组件配置确认YAML中component字段引用的名称在components部分有正确定义且class_path指向的Python类可以被正确导入。查看详细日志启用Vidura的调试级别日志查看每个节点开始、结束以及传递的数据。问题往往出在数据的格式上比如某个节点输出的变量名与下游节点期望的输入变量名不匹配。隔离测试单独创建一个只包含可疑节点的小型工作流进行测试验证其输入输出是否符合预期。7.2 模型调用返回意外内容或错误症状回复质量差、胡言乱语或直接返回API错误。排查步骤验证API密钥与网络这是最常见的问题。确保环境变量已正确加载并且服务器可以访问对应的API端点考虑网络代理或防火墙规则。审查System Prompt和用户输入将实际发送给模型的请求内容打印出来注意脱敏。检查system prompt是否清晰定义了角色用户输入是否被意外截断或污染一个混乱的system prompt会导致模型行为异常。检查参数temperature设置是否过高导致随机性太大max_tokens是否足够生成完整回复对于需要严格格式的输出如分类、JSON尝试将temperature设为0或接近0并使用response_format参数如果API支持。处理速率限制如果请求量突然增大可能会触发API的速率限制。实现一个带有指数退避的请求重试逻辑并在日志中明确记录此类错误。7.3 工具组件执行异常症状工具调用失败返回错误或超时。排查步骤输入验证在工具的execute方法开头严格验证输入数据的类型和范围。模型生成的输入可能不符合预期。异常捕获与友好返回用try...except包裹核心逻辑捕获所有可能的异常网络超时、数据库连接失败、第三方API错误等并返回一个结构化的错误信息而不是让异常直接抛出导致整个工作流崩溃。这能让上游节点或模型有机会进行补救例如回复用户“系统暂时繁忙”。超时设置为所有外部调用设置显式的超时。一个慢速的外部API会拖垮整个对话的响应时间。模拟与测试为工具编写单元测试模拟各种正常和异常的输入确保其健壮性。7.4 评估分数不稳定或偏低症状自动化评估分数波动大或始终达不到预期。排查步骤审视评估标准本身你的评估指标criteria描述是否清晰、无歧义让不同的人根据同一标准打分结果是否一致如果“AI即评估器”的评分不稳定可能是评估指令写得太模糊。检查测试数据质量测试用例是否具有代表性expected_response_contains里的关键词是否过于死板导致模型合理的同义表达被误判考虑加入一些基于语义相似度如余弦相似度的评估而非纯粹的关键词匹配。人工审核定期对评估结果进行人工抽样审核。尤其是那些得分高但你觉得不对或得分低但你觉得还行的案例。这能帮你发现评估体系本身的缺陷。评估器的局限性理解你使用的评估器尤其是LLM作为评估器的偏见和局限性。它可能在某些主观维度如“友好度”上评分不准。对于关键指标考虑结合多种评估方法。最后再分享一个小技巧建立一个“问题案例库”。每次遇到一个棘手的、导致对话失败的案例都把它记录下来包括用户输入、完整的工作流日志、错误信息以及最终的修复方法。这个库不仅是团队宝贵的知识积累未来也可以直接作为“反面教材”加入你的测试数据集确保同样的问题不会再次发生。维护好这个库你的对话系统就会像一个有经验的老兵一样越战越强。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2596688.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…