当前位置: 首页 > article >正文

实战:多语言翻译协作 Agent Harness

实战:多语言翻译协作 Agent Harness1. 标题 (Title)从零构建多语言翻译协作系统:Agent Harness 实战指南多 Agent 协作新范式:打造智能多语言翻译 Harness 框架告别单一翻译模型:构建协作式多语言翻译 Agent 系统Agent Harness 实战:如何让多个 AI 代理协同完成专业翻译智能翻译进化之路:构建可扩展的多 Agent 协作翻译系统2. 引言 (Introduction)痛点引入 (Hook)你是否曾经遇到过这样的场景:在处理一份重要的多语言文档时,使用单一的翻译工具总是无法满足所有需求?要么是专业术语翻译不准确,要么是文化背景理解不到位,又或者是不同语言之间的转换质量参差不齐。在全球化的今天,我们经常需要处理来自不同国家和地区的文档、网站和应用。传统的翻译工具虽然不断进步,但仍然存在明显的局限性:单一模型难以兼顾所有语言对的专业性,无法根据具体领域动态调整翻译策略,更不用说处理复杂的多步骤翻译任务了。更重要的是,当我们需要翻译涉及多个专业领域的内容时,没有任何一个单一的翻译系统能够精通所有领域。这就是为什么我们需要一种新的方法——让多个专门化的 AI 代理(Agents)协同工作,各自发挥所长,共同完成高质量的翻译任务。文章内容概述 (What)本文将带你从零开始,构建一个多语言翻译协作 Agent Harness 系统。我们将深入探讨 Agent Harness 的核心概念,设计一个灵活的多代理协作架构,并实现一个功能完整的原型系统。具体来说,我们将:理解 Agent Harness 的基本概念和设计原则设计多语言翻译协作系统的架构实现不同类型的翻译代理(通用翻译、专业领域翻译、质量评估等)构建代理之间的协作机制和通信协议实现任务分配、结果整合和质量控制功能通过实际案例演示系统的运行效果读者收益 (Why)读完本文,你将能够:深入理解多代理系统(Multi-Agent System)的核心概念和设计方法掌握 Agent Harness 框架的设计思路和实现技巧学会如何让多个 AI 代理有效协作完成复杂任务拥有一个可扩展、可定制的多语言翻译协作系统原型获得将多代理技术应用到其他领域的思路和方法无论你是想提升翻译工作的效率和质量,还是对多代理系统的开发感兴趣,本文都将为你提供有价值的参考和实践指导。3. 准备工作 (Prerequisites)在开始我们的实战之前,让我们先确保你已经具备了必要的知识和工具。技术栈/知识为了顺利完成本文的实战内容,你需要具备以下基础知识:Python 编程基础:熟练掌握 Python 语法,了解面向对象编程概念基础的 AI/LLM 概念:了解大语言模型的基本原理和使用方法API 调用经验:熟悉如何使用 Python 调用 RESTful API异步编程基础:了解 Python 的 async/await 概念(这对高效处理多个代理协作很有帮助)基本的系统设计知识:理解模块化设计、接口设计等概念如果你对以上某些知识不太熟悉,也不用担心,我们会在必要的地方提供简要的解释和参考资料。环境/工具在开始编码之前,请确保你的开发环境中已经安装了以下工具和库:Python 3.8+:我们将使用 Python 3.8 或更高版本pip 或 conda:用于管理 Python 包代码编辑器:推荐使用 VS Code、PyCharm 或你喜欢的任何编辑器OpenAI API 密钥(或其他 LLM 服务的 API 密钥):我们将使用 LLM 来驱动我们的代理Git(可选):用于版本控制我们将在实战过程中逐步安装所需的 Python 库,所以你现在不需要提前安装所有依赖。4. 核心内容:手把手实战 (Step-by-Step Tutorial)步骤一:理解 Agent Harness 核心概念与系统设计在开始编码之前,让我们先花一些时间理解 Agent Harness 的核心概念,并设计我们的多语言翻译协作系统。核心概念:什么是 Agent Harness?Agent Harness(代理框架/代理 harness)是一个用于管理和协调多个 AI 代理(Agents)的系统框架。它提供了一套基础设施,让多个专门化的代理能够有效通信、协作完成复杂任务。在我们的上下文中,Agent(代理)是一个具有特定功能的软件实体,它能够感知环境、做出决策并执行行动。每个代理通常专注于某个特定领域或任务类型,具有自己的专业知识和能力。Harness(框架)则是连接和协调这些代理的"基础设施",它负责:任务接收和分解代理选择和调度代理间通信和信息传递结果整合和质量控制错误处理和恢复机制多语言翻译协作系统的设计目标我们的系统需要实现以下核心目标:高质量翻译:通过多代理协作提升翻译质量多语言支持:支持多种语言之间的互译领域适应性:能够根据不同专业领域调整翻译策略可扩展性:方便添加新的代理和功能透明性:用户能够了解翻译过程和决策依据系统架构设计让我们设计一个灵活的多层架构:┌─────────────────────────────────────────────────────────┐ │ 用户接口层 │ │ (API、CLI、Web界面等) │ └────────────────────┬────────────────────────────────────┘ │ ┌────────────────────▼────────────────────────────────────┐ │ 任务协调层 │ │ (Task Orchestrator Harness Core) │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ 任务分解器 │ │ 代理调度器 │ │ 结果整合器 │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ └────────────────────┬────────────────────────────────────┘ │ ┌────────────────────▼────────────────────────────────────┐ │ 代理层 │ │ (Agents Pool) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │通用翻译 │ │专业翻译 │ │质量评估 │ │文化适配 │ │ │ │ 代理 │ │ 代理 │ │ 代理 │ │ 代理 │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │术语管理 │ │格式保持 │ │内容审核 │ │后编辑 │ │ │ │ 代理 │ │ 代理 │ │ 代理 │ │ 代理 │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ └────────────────────┬────────────────────────────────────┘ │ ┌────────────────────▼────────────────────────────────────┐ │ 基础服务层 │ │ (LLM API、知识库、存储等) │ └─────────────────────────────────────────────────────────┘这个架构由四个主要层次组成:用户接口层:负责与用户交互,接收翻译请求,展示翻译结果。任务协调层:这是 Agent Harness 的核心,负责任务分解、代理调度和结果整合。代理层:包含各种专门化的翻译代理,每个代理负责翻译过程中的特定环节。基础服务层:提供底层支持,包括 LLM API、知识库、数据存储等。代理类型设计在我们的系统中,我们将实现以下几种关键代理:通用翻译代理:负责基础的语言转换,适用于通用领域文本。专业领域翻译代理:专注于特定专业领域(如法律、医疗、技术等)的翻译。质量评估代理:评估翻译结果的质量,指出问题和改进建议。文化适配代理:确保翻译结果符合目标语言的文化背景和习惯表达。术语管理代理:维护和应用专业术语表,确保术语翻译的一致性。格式保持代理:确保翻译过程中原始文档的格式和结构得以保持。协作流程设计一个典型的翻译任务协作流程如下:用户提交翻译请求(源文本、源语言、目标语言、领域等)任务协调器接收请求,分析任务需求任务分解器将复杂任务分解为多个子任务代理调度器根据子任务需求选择合适的代理代理执行子任务,生成中间结果结果整合器整合各代理的输出,生成初步翻译结果质量评估代理评估结果质量,如需要则返回改进最终结果返回给用户现在我们对系统有了清晰的设计思路,接下来让我们开始实现这个系统。步骤二:项目初始化与基础框架搭建让我们开始创建项目结构并搭建基础框架。创建项目结构首先,创建一个新的项目目录,并设置基本的项目结构:mkdirtranslation-agent-harnesscdtranslation-agent-harness然后创建以下目录结构:translation-agent-harness/ ├── src/ │ ├── __init__.py │ ├── harness/ │ │ ├── __init__.py │ │ ├── core.py # Harness 核心功能 │ │ ├── task_decomposer.py # 任务分解器 │ │ ├── agent_scheduler.py # 代理调度器 │ │ └── result_integrator.py # 结果整合器 │ ├── agents/ │ │ ├── __init__.py │ │ ├── base.py # 代理基类 │ │ ├── translator.py # 通用翻译代理 │ │ ├── specialist.py # 专业领域翻译代理 │ │ ├── evaluator.py # 质量评估代理 │ │ └── cultural_adapter.py # 文化适配代理 │ ├── models/ │ │ ├── __init__.py │ │ ├── task.py # 任务模型 │ │ └── result.py # 结果模型 │ ├── services/ │ │ ├── __init__.py │ │ └── llm_service.py # LLM 服务 │ └── utils/ │ ├── __init__.py │ └── config.py # 配置工具 ├── examples/ │ └── basic_usage.py # 基础使用示例 ├── tests/ │ └── __init__.py ├── .env.example # 环境变量示例 ├── requirements.txt # 项目依赖 └── README.md # 项目说明创建基础依赖文件创建requirements.txt文件,列出我们需要的 Python 库:# requirements.txt openai=1.0.0 python-dotenv=1.0.0 pydantic=2.0.0 asyncio=3.4.3 tenacity=8.2.0现在,让我们创建一个虚拟环境并安装这些依赖:# 创建虚拟环境(可选但推荐)python-mvenv venv# 激活虚拟环境# Windows:venv\Scripts\activate# macOS/Linux:sourcevenv/bin/activate# 安装依赖pipinstall-rrequirements.txt配置环境变量创建.env.example文件:# .env.example OPENAI_API_KEY=your_openai_api_key_here OPENAI_MODEL=gpt-4 OPENAI_TEMPERATURE=0.7 OPENAI_MAX_TOKENS=2000复制这个文件为.env并填入你的实际 API 密钥:cp.env.example .env然后编辑.env文件,填入你的 OpenAI API 密钥。创建配置工具现在,让我们创建配置工具src/utils/config.py:# src/utils/config.pyimportosfromdotenvimportload_dotenvfromtypingimportOptional# 加载环境变量load_dotenv()classConfig:"""配置管理类"""# OpenAI 配置OPENAI_API_KEY:str=os.getenv("OPENAI_API_KEY","")OPENAI_MODEL:str=os.getenv("OPENAI_MODEL","gpt-4")OPENAI_TEMPERATURE:float=float(os.getenv("OPENAI_TEMPERATURE","0.7"))OPENAI_MAX_TOKENS:int=int(os.getenv("OPENAI_MAX_TOKENS","2000"))# Harness 配置MAX_RETRIES:int=3AGENT_TIMEOUT:int=60# 秒@classmethoddefvalidate(cls)-None:"""验证配置是否有效"""ifnotcls.OPENAI_API_KEY:raiseValueError("OPENAI_API_KEY 必须设置")创建数据模型接下来,让我们定义任务和结果的数据模型。首先是src/models/task.py:# src/models/task.pyfromenumimportEnumfromtypingimportOptional,List,Dict,AnyfrompydanticimportBaseModel,FieldclassTaskStatus(str,Enum):"""任务状态枚举"""PENDING="pending"IN_PROGRESS="in_progress"COMPLETED="completed"FAILED="failed"classTaskPriority(str,Enum):"""任务优先级枚举"""LOW="low"MEDIUM="medium"HIGH="high"URGENT="urgent"classTranslationDomain(str,Enum):"""翻译领域枚举"""GENERAL="general"LEGAL="legal"MEDICAL="medical"TECHNICAL="technical"MARKETING="marketing"ACADEMIC="academic"classSubTask(BaseModel):"""子任务模型"""id:str=Field(...,description="子任务唯一标识")task_type:str=Field(...,description="子任务类型")description:str=Field(...,description="子任务描述")assigned_agent:Optional[str]=Field(None,description="分配的代理ID")status:TaskStatus=Field(TaskStatus.PENDING,description="子任务状态")input_data:Dict[str,Any]=Field(default_factory=dict,description="输入数据")output_data:Optional[Dict[str,Any]]=Field(None,description="输出数据")dependencies:List[str]=Field(default_factory=list,description="依赖的子任务ID列表")classTranslationTask(BaseModel):"""翻译任务模型"""id:str=Field(...,description="任务唯一标识")source_text:str=Field(...,description="源文本")source_lang:str=Field(...,description="源语言")target_lang:str=Field(...,description="目标语言")domain:TranslationDomain=Field(TranslationDomain.GENERAL,description="翻译领域")priority:TaskPriority=Field(TaskPriority.MEDIUM,description="任务优先级")status:TaskStatus=Field(TaskStatus.PENDING,description="任务状态")instructions:Optional[str]=Field(None,description="额外翻译指示")subtasks:List[SubTask]=Field(default_factory=list,description="子任务列表")created_at:Optional[float]=Field(None,description="创建时间戳")updated_at:Optional[float]=Field(None,description="更新时间戳")metadata:Dict[str,Any]=Field(default_factory=dict,

相关文章:

实战:多语言翻译协作 Agent Harness

实战:多语言翻译协作 Agent Harness 1. 标题 (Title) 从零构建多语言翻译协作系统:Agent Harness 实战指南 多 Agent 协作新范式:打造智能多语言翻译 Harness 框架 告别单一翻译模型:构建协作式多语言翻译 Agent 系统 Agent Harness 实战:如何让多个 AI 代理协同完成专业…...

macOS高效配置:OpenClaw与Qwen3.5-9B镜像深度集成指南

macOS高效配置:OpenClaw与Qwen3.5-9B镜像深度集成指南 1. 为什么选择OpenClaw与Qwen3.5-9B组合 去年冬天,当我第一次尝试用AI自动化处理日常工作报告时,发现大多数云端方案要么功能受限,要么隐私性存疑。直到遇见OpenClaw这个能…...

STM32+MATLAB数据采集避坑指南:你的串口丢包、乱码可能和这3个参数有关

STM32与MATLAB串口通信的稳定性优化:从参数配置到实战调试 在嵌入式系统与上位机通信的众多方案中,STM32与MATLAB通过串口进行数据交互是最为经典且广泛应用的组合之一。这种组合充分利用了STM32在实时控制方面的优势以及MATLAB在数据分析与可视化上的强…...

OpenClaw自动化写作:Qwen2.5-VL-7B生成图文并茂技术文档

OpenClaw自动化写作:Qwen2.5-VL-7B生成图文并茂技术文档 1. 为什么需要自动化技术文档写作 作为一个经常需要编写技术文档的开发者,我深知文档写作的痛点。每次完成一个功能模块后,总要花大量时间整理代码片段、截图、编写说明文字。最麻烦的…...

OpenClaw成本控制:Qwen3.5-9B任务拆分与Token节省策略

OpenClaw成本控制:Qwen3.5-9B任务拆分与Token节省策略 1. 为什么需要关注OpenClaw的Token消耗? 去年夏天,当我第一次在本地部署OpenClaw对接Qwen3.5-9B模型时,被一个简单的文件整理任务消耗了将近2000个Token。这让我意识到&…...

开源力量:OpenClaw+gemma-3-12b-it构建低成本个人AI助手

开源力量:OpenClawgemma-3-12b-it构建低成本个人AI助手 1. 为什么选择开源模型OpenClaw组合? 去年我尝试用商业API搭建个人自动化助手时,发现两个致命问题:一是每月Token费用超过预期3倍(主要来自长链条任务的反复调…...

WPS JS宏利用Fetch API实现网页数据抓取与Excel自动化处理

1. 为什么需要网页数据抓取与Excel自动化 在日常办公中,我们经常需要从各种网站获取数据并整理到Excel表格中。比如市场人员需要抓取竞品价格、财务人员需要获取汇率数据、运营人员需要统计社交媒体互动情况。传统做法是手动复制粘贴,不仅效率低下&#…...

STM32F103 OTA升级实战:用bsdiff差分算法把固件包缩小90%(附完整工具链)

STM32F103 OTA升级实战:用bsdiff差分算法把固件包缩小90%(附完整工具链) 在物联网设备快速迭代的今天,OTA(Over-The-Air)升级已成为嵌入式开发的标配功能。但对于资源受限的STM32F103这类Cortex-M3内核MCU来…...

别再死记硬背CAN协议了!用STM32CubeMX+USB-CAN分析仪,5分钟搞定物理层与数据链路层实战

用STM32CubeMXUSB-CAN分析仪5分钟掌握CAN核心原理 当你第一次接触CAN总线时,是否被那些晦涩的术语搞得一头雾水?显性电平、位填充、采样点、仲裁机制...这些概念在纯理论讲解中往往显得抽象难懂。但今天,我要带你用一种全新的方式学习CAN——…...

从Remix到Ganache:一次智能合约部署的完整“后台日志”解读

从Remix到Ganache:智能合约部署的"后台日志"深度解析 当你第一次成功部署智能合约时,看到Ganache和Remix控制台输出的那一大串信息,是不是感觉像在看天书?那些Block Hash、Gas Used、txIndex究竟在说什么?这…...

seo在线分析技巧有哪些

SEO在线分析技巧有哪些? 在当今的数字化时代,搜索引擎优化(SEO)已经成为了每一个网站和在线业务的关键。特别是在百度这样的中文搜索引擎平台上,掌握SEO在线分析技巧对提升网站的可见度和流量至关重要。具体有哪些SEO…...

STM32duino驱动X-NUCLEO-IKS5A1多传感器融合开发指南

1. STM32duino X-NUCLEO-IKS5A1 扩展板底层驱动技术解析1.1 工业级多传感器融合平台的硬件架构X-NUCLEO-IKS5A1 是意法半导体(ST)面向工业运动感知与环境监测场景推出的高集成度 MEMS 传感器扩展板,专为 STM32 Nucleo 开发平台设计。其核心价…...

Android 8.0长时定时关机总延迟?我换了种思路,用系统广播ACTION_TIME_TICK轻松搞定

Android定时任务稳定性优化:从AlarmManager到系统广播的实践之路 在智能硬件和特定应用场景中,定时功能的可靠性往往直接影响用户体验。想象一下,你为孩子设置的学习软件定时关闭功能延迟了几分钟,或者智能家居设备的自动关机未能…...

别再拍脑袋定权重了!多目标规划中权重与ε值确定的3种实战方法(附Python代码)

别再拍脑袋定权重了!多目标规划中权重与ε值确定的3种实战方法(附Python代码) 引言 在资源分配、产品规划等实际业务场景中,我们常常面临需要同时优化多个目标的决策问题。比如既要控制成本,又要提升用户体验&#xff…...

不止是安装:在openEuler 22.03 LTS SP4上快速搭一个可用的开发/测试环境

从裸机到生产力:openEuler 22.03 LTS SP4半小时高效开发环境搭建指南 刚装完openEuler系统,看着空荡荡的终端界面,是不是有种"接下来该干嘛"的迷茫?作为开发者,我们需要的不是一个干净的操作系统&#xff0c…...

Kettle日志组件实战指南:从基础配置到高级调试

1. Kettle日志组件基础入门 第一次接触Kettle的日志功能时,我完全被各种配置选项搞晕了。后来才发现,这个看似简单的组件其实是调试ETL流程的利器。日志组件位于Kettle的核心对象面板中,你可以直接拖拽到右侧工作区,或者双击它自动…...

OpenClaw日志分析:百川2-13B-4bits模型自动化排查系统错误

OpenClaw日志分析:百川2-13B-4bits模型自动化排查系统错误 1. 为什么需要智能日志分析 每次系统半夜报错时,我都会被报警电话惊醒,然后手忙脚乱地登录服务器查日志。那些密密麻麻的报错信息就像天书,经常需要反复搜索、比对历史…...

2026年西安市莲湖区Geo搜索优化排名,专业企业究竟谁能拔得头筹?

在数字化浪潮席卷的今天,Geo搜索优化(地理搜索优化)对于企业的重要性不言而喻。尤其在西安市莲湖区,企业们对于提升自身在Geo搜索中的排名需求愈发迫切。究竟哪家专业企业能够在2026年的竞争中脱颖而出,成为Geo搜索优化…...

从玩具到工具:用Unity Vuforia给老旧产品手册做个‘AR说明书’(实战案例分享)

从玩具到工具:用Unity Vuforia给老旧产品手册做个‘AR说明书’(实战案例分享) 想象一下,当客户翻阅一本印刷精美的工业设备手册时,只需用手机扫描页面上的产品示意图,就能在屏幕上看到设备内部结构的3D拆解…...

VSCode + WSL2开发环境搭建:Windows10下的高效Linux开发体验

VSCode WSL2开发环境搭建:Windows10下的高效Linux开发体验 在Windows系统上进行Linux开发一直是件令人头疼的事情——双系统切换麻烦,虚拟机性能堪忧,远程服务器又受限于网络环境。直到微软推出WSL2(Windows Subsystem for Linux…...

2031年2.9亿美元:全球医用血卡离心机市场增长态势剖析

医用血卡离心机作为实验室关键仪器,在免疫血液学领域发挥着重要作用。它主要用于对凝胶卡或血型卡进行可控、可重复的离心操作,使血浆和红细胞通过凝胶柱或微柱,进而完成血型鉴定、抗体筛查和交叉配血等任务。典型的血卡离心机配备专用转子&a…...

Flet跨平台GUI开发:从入门到实战

1. 为什么选择Flet开发跨平台GUI? 最近几年,Python在GUI开发领域一直缺少一个真正意义上的跨平台解决方案。传统的Tkinter功能有限,PyQt虽然强大但商业授权复杂,Kivy的语法又不够直观。直到我发现了Flet这个宝藏框架,它…...

n8n自动化实战:用AI老师带你6周搞定电商订单处理系统

n8n自动化实战:用AI老师带你6周搞定电商订单处理系统 电商行业的快速发展对订单处理效率提出了更高要求。传统人工操作不仅耗时耗力,还容易出错。n8n作为一款开源自动化工具,能够帮助企业快速搭建高效的订单处理系统。本文将带你用6周时间&am…...

平行泊车和垂直泊车的程序代码(基于MATLAB开发,含代码与说明文档)

平行泊车和垂直泊车的程序代码,基于MATLAB开发,包含代码和说明文档平行与垂直泊车路径规划系统:基于 MATLAB 的自动驾驶辅助功能实现一、背景与目标----------------在 L2/L3 级自动驾驶量产方案中,低速泊车是用户感知最强、使用频…...

保姆级教程:用PCL的SAC_RANSAC算法搞定点云平面分割(附完整C++代码)

从零掌握PCL点云平面分割:RANSAC算法实战与避坑指南 刚接触三维点云处理时,面对杂乱无章的数据点,如何快速准确地提取出平面结构?本文将手把手带你用PCL库中的RANSAC算法实现点云平面分割,从环境搭建到参数调优&#x…...

Pixel Couplet Gen惊艳案例:游戏公司用Pixel Couplet Gen做乙巳年IP联动

Pixel Couplet Gen惊艳案例:游戏公司用Pixel Couplet Gen做乙巳年IP联动 1. 项目背景与创意来源 在数字娱乐产业快速发展的今天,游戏公司越来越注重通过文化元素与用户建立情感连接。某知名游戏公司为了庆祝乙巳年春节,决定打破传统春联的呈…...

网站SEO查询工具可以分析什么

网站SEO查询工具可以分析什么 在当今互联网时代,网站的SEO(搜索引擎优化)已经成为了提高网站流量和用户参与度的关键因素。而SEO查询工具则是让网站运营者在优化过程中扮演重要角色的工具。具体来说,网站SEO查询工具可以分析什么…...

实测对比:图解法和微变等效电路法分析放大电路,到底哪个更准?

实测对比:图解法和微变等效电路法分析放大电路,到底哪个更准? 在模拟电路设计中,共射放大电路的分析是每个电子工程师必须掌握的核心技能。面对同样的电路,工程师们常陷入方法论的选择困境:是采用直观形象的…...

5分钟搞定OpenClaw安装:Phi-3-vision-128k-instruct镜像一键部署指南

5分钟搞定OpenClaw安装:Phi-3-vision-128k-instruct镜像一键部署指南 1. 为什么选择星图平台部署Phi-3模型 上周我在本地尝试部署Phi-3-vision-128k-instruct模型时,被各种依赖冲突折磨得够呛。CUDA版本不匹配、vLLM编译失败、Python环境污染...这些问…...

IDEA集成Tomcat实战:动态Web工程创建与热部署配置

IDEA集成Tomcat实战:动态Web工程创建与热部署配置 在JavaWeb开发领域,IDEA与Tomcat的组合堪称黄金搭档。作为一名长期使用这套技术栈的开发者,我深刻体会到合理配置开发环境对效率提升的重要性。本文将带你从零开始,在IDEA中搭建完…...