如果你已经跑通了一个RAG的Demo大概率会在第二步撞上一堵墙数据灌进去了向量库也连上了问什么都像是“驴唇不对马嘴”。我自己踩过好几次这样的坑之后几乎可以断定——项目效果扑街八成不是向量库或Embedding模型的问题而是Chunking这个环节从一开始就没被认真对待。这篇内容我会把分块从原理到企业级落地完整拆一遍为什么它决定了RAG效果的天花板、五种主流策略各自的适用边界、参数怎么调才靠谱、企业级管线里元数据和增量更新怎么设计以及我自己实测过程中踩过的那些坑。适合正在从Demo往生产环境推进的RAG项目组也适合那些“检索结果总是差一点”的团队拿来对照排查。1. 分块为什么是RAG的命门先想清楚再动手1.1 一次翻车现场让我重新审视分块印象最深的一次是给一个制度问答机器人调参。文档是几百页的企业规章制度我当时的做法看起来很“标准”直接用递归字符分块器chunk_size设400overlap设50然后把所有块丢进向量库。对话测试的时候发现明明检索出来的top5块看起来和问题“沾边”但模型给出的答案总是不完整甚至把不相干的两个制度条款捏在一起。最后我把返回的块打印出来才发现问题根源很多块是从段落中间被硬生生切断的有的把上一段的结尾和下一段的开头拼在了一起语义早就乱了。后来我又试了几种不同的chunk_size发现只要切分位置不对换再好的Embedding模型都救不回来。从那一刻起我意识到分块不是一个“选个参数跑一下”的过场而是决定RAG检索质量上限的环节。1.2 分块的本质是给embedding划定语义边界把RAG的链路拆开看文档解析 - 分块 - Embedding向量化 - 向量检索 - 重排 - 生成。大部分人的注意力集中在Embedding模型选型和向量库选型上分块这个环节往往被一带而过。我习惯用一个比喻来理解Embedding它像一个“语义压缩器”把一段连续文本压缩成一个稠密向量。压缩的前提是这段文本本身有一个相对一致的语义主题。分块的任务就是在喂给压缩器之前把同一主题的文本圈到一起。如果你给它的是“半句话加另一段的开头”向量再优秀压缩出来的也是混合语义的模糊向量。这也是为什么分块是RAG的命门——向量检索这一步的错误是后续生成环节无法修正的。生成模型只能在召回结果里找答案召回的内容本身就是残缺的那后面的Rerank和Prompt再优化也救不回来。这就是垃圾进、垃圾出的底层逻辑。1.3 块大小的本质是信息粒度与噪声的博弈分块的核心矛盾说到底就是两个方向拉扯块太大一个块里包含的主题太多Embedding向量会被“平均化”和查询的相似度变得飘忽不定。更麻烦的是召回后成本会上升——喂给生成模型的token变多响应变慢。块太小每个块的上下文太薄一个因果逻辑链被拦腰截断模型拿到手的信息根本不足以还原一个完整结论。我用做寿司来类比每一块寿司都应该是一口能吃掉、不散架同时又有独立风味的存在。分块也一样既要有独立的语义完整度又不能大得失去重点。另一个容易忽略的点是分块不是“一刀切”。同一个知识库里可能有制度文件、产品说明书、FAQ问答、合同条款它们的天然粒度完全不一样。企业级RAG和Demo阶段最大的区别之一就是必须承认这一点然后针对性地设计不同的分块策略。2. 主流分块策略拆解从固定大小到语义与结构感知2.1 固定大小分块简单但只在有限场景下够用固定大小分块是所有方案里最朴素的一种按固定的字符数或token数切可以指定overlap。def fixed_size_chunk(text, size500, overlap50): if len(text) size: return [text] chunks [] start 0 while start len(text): chunks.append(text[start:start size]) start size - overlap return chunks这种方案的优点是实现极简、性能稳定、切分路径完全可预测适合内容非常规整的文本。比如批量日志、流水记录、格式统一的短新闻。它的缺点是完全没有语义感知可能在句子中间切断可能把两个业务主题混进同一块。实测下来如果文档像制度文件、产品手册这种长文居多固定大小分块很容易翻车。我的建议是除非你非常确定语料结构足够均匀否则不要拿它当默认方案。2.2 递归字符分块工程默认选择的理性递归字符分块是目前最常用的方案LangChain里的RecursiveCharacterTextSplitter、LlamaIndex里的NodeParser、Java生态里LangChain4j Easy RAG的默认分块逻辑基本都是这个思路。它的核心机制是按照一组分隔符的优先级递归切分。先尝试用最大的分隔符切如果切出来的块还是超过chunk_size就换下一个小的分隔符继续切。from langchain.text_splitter import RecursiveCharacterTextSplitter splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap50, separators[\n\n, \n, 。, , , , , , ] ) chunks splitter.split_text(document)这里有一个特别容易踩的细节默认分隔符以英文标点为主处理中文文档时如果不手动加上中文句号、问号、感叹号和分号你会发现切分位置经常落在毫不相干的地方甚至整段被腰斩。递归字符分块的优势是在实现简单和效果可用之间取得了不错的平衡是大多数RAG项目的合理起点。但它仍然不是按语义切分——块和块之间的边界依赖标点和换行而不依赖内容主题。2.3 语义分块用向量相似度找主题边界如果想更进一步可以在分句之后计算相邻句子的语义相似度相似度明显下降的位置往往就是主题切换的边界。这就是语义分块的基本思路。用代码实现一个最小可用的版本大概是这样的import numpy as np from sentence_transformers import SentenceTransformer model SentenceTransformer(BAAI/bge-small-zh-v1.5) def semantic_chunk(sentences, threshold0.7): embs model.encode(sentences) chunks [] current [sentences[0]] for i in range(1, len(sentences)): sim np.dot(embs[i], embs[i - 1]) / ( np.linalg.norm(embs[i]) * np.linalg.norm(embs[i - 1]) ) if sim threshold: chunks.append(.join(current)) current [] current.append(sentences[i]) if current: chunks.append(.join(current)) return chunks这个简化版用相邻句子相似度作为突变信号思路直观。实际生产环境里还要处理句子边界识别、阈值动态调整、块长上下限约束等细节。语义分块的效果上限比固定大小和递归分块更高尤其是面对主题多变的长文。代价是计算成本明显上升分块本身就需要一次embedding对大规模文档库来说意味着额外的算力和延迟。阈值也比较敏感不同领域的语料需要拿真实样本重新校准。我的经验是如果业务对检索精度要求高、文本主题变化频繁而且离线分块管道能承受额外成本语义分块值得上如果追求稳定和速度递归分块更稳妥。2.4 文档结构感知分块尊重文档自己的层级很多企业级文档本身就有清晰的层级结构Markdown的标题层级、PDF的章节、Word的heading样式、合同里的“第X条”。如果无视这些结构只按字符数去切等于把作者已经划好的语义边界全部打乱。文档结构感知分块的核心思想就是把“标题-正文”作为最小单元并且让每个块带上它在文档树中的路径信息。LangChain的MarkdownHeaderTextSplitter就是一个典型例子from langchain.text_splitter import MarkdownHeaderTextSplitter headers_to_split_on [ (#, H1), (##, H2), (###, H3), ] splitter MarkdownHeaderTextSplitter(headers_to_split_onheaders_to_split_on) chunks_with_metadata splitter.split_text(markdown_doc)切出来的每个块不仅包含正文内容还带着完整的标题链信息。这些元数据在检索阶段极其有用可以按章节过滤也可以在回答时告诉模型“这个答案来自第三章考勤管理”。结构感知分块在制度问答、产品手册、技术文档这些场景里竞争力非常明显。它牺牲了一部分灵活性但大幅提升了块内容与人类认知边界的对齐程度。2.5 特殊格式的处理代码、表格与多模态普通文本之外还有一批让默认分块器“当场社死”的特殊格式。代码文件按字符或句子切代码是灾难最好的做法是解析语法树按函数、类、方法天然边界切这样检索到的代码片段才是完整可用的。表格表格一旦被切成几块检索到的上下文就变得不可读。常见的做法是整表作为一块保留或者按列、按行做结构化提取再单独索引。图片与多模态图文混排的文档最好把图片的描述信息和正文绑定在分块阶段就保留“图-文”对应关系否则检索时图文关联会断掉。这些特殊格式在企业文档里出现的频率并不低技术团队尤其容易在“代码说明文档”混排的Markdown上吃亏。处理这类内容我会在解析管道里单独分配逻辑而不是让通用分块器去硬切。另外代码仓库类知识库如果数据量很大建议先按文件类型分流文档和代码走不同管道避免预处理阶段就被拖垮。3. 分块参数调优与embedding模型的配合3.1 chunk_size到底怎么定很多人上来就问chunk_size设多少合适这是一个只有测试才能回答的问题。不过有几个硬约束可以先定下来Embedding模型的最大输入长度。比如OpenAI text-embedding-3-small支持8191 token但并不意味着每个块都要拉到上限。超过模型最优输入长度太多向量语义会被稀释。检索目标粒度。你是希望召回“章节级”还是“段落级”条款合同可能需要600-800FAQ可能300就够。生成模型的上下文预算。块越大召回后喂给生成模型的token越多成本和延迟都受影响。我自己的常用起点是400-600 token然后以50 token为步长上下扫描。下面是我在某个制度文档库上做过的一组粗略对比参数组合问题集命中率答案完整率平均检索耗时chunk300, overlap3078%72%185mschunk500, overlap5086%83%210mschunk800, overlap8081%76%246ms语义分块无固定长度89%85%390ms可以看到500 token那组在效果与成本的平衡点上表现最稳。但这组数字只对当时的语料成立换个领域结果可能完全不同——所以一定要带着自己的种子问题集去做对比实验不要照搬网上的参数。3.2 overlap不是越大越好overlap块与块之间的重叠部分是为了止损避免一个语义内容恰好被边界切断。它的本质是让边界附近的上下文再多活一段。建议默认从10%-20%开始也就是chunk_size500时overlap取50-100。但overlap有一个隐蔽的副作用相邻块之间大量重复内容会让向量索引的存储体积明显膨胀也会引入检索噪声。如果你把overlap拉到80%同一段文字会出现在无数个块里检索时同一个内容被反复召回看起来命中很多实际信息量没有增加反而干扰了重排序。更关键的是overlap无法替代合理的切分策略。如果块边界本身就落在语义转折点上overlap再多也补不回来。我见过有的团队为了保险把overlap设到50%结果索引大小翻了将近一倍Rerank分数也被重复内容拉低。真正合适的做法是先用小overlap试如果发现边界处的重要信息连续丢失再慢慢往上加。3.3 embedding模型和分块的相互约束Embedding模型决定了一个块在向量空间里“以多长的语义范围”被表达。两者是强耦合关系分块参数必须跟着模型调整。以本地知识库场景为例很多人用ollama跑一个简易本地RAGEmbedding模型选的是nomic-embed-text或者bge-m3。这类本地模型的输入长度上限通常在512-8192不等并且在长度接近上限时检索效果会明显下滑。我在本地测试里发现用nomic-embed-text时把块控制在300-500 token召回质量比拉到800要好不少原因就是长文本向量被“稀释”了。另外一个容易被忽略的点向量检索时查询文本的embedding和索引时文档块的embedding通常用的是同一个模型。如果文档块平均300 token但用户查询只有20-50 token两者在向量空间中的表达尺度会有偏差。这不完全是分块能解决的但需要你有预期必要时增加Rerank环节来弥补。3.4 不同领域的参数差异最后给一份针对不同文本类型的经验值仅供参考还是要拿自己的语料验证文本类型推荐策略参数建议法律合同结构感知 整条切割chunk600-800overlap80-100产品技术手册结构感知 递归chunk400-500overlap40-60客服FAQ固定大小 / 语义chunk300-400overlap20-40代码仓库AST / 函数边界按函数、类切不设固定chunk中英混排文档递归 语言切换点chunk400overlap60-80法律条款往往“一条就是一个完整语义”硬切成200 token的小块会导致同一个法条被拆到多个块里。FAQ则天然是一个问题一个答案块大了反而混入无关内容。这就是为什么企业级分块必须“因物制宜”。4. 企业级落地把分块从脚本升级成可治理的管线4.1 多格式文档解析与分块管道的设计企业级RAG和Demo最大的区别是输入不只有一种格式。从PDF、Word、Markdown到扫描件OCR、Excel表格、PPT都可能出现在同一个知识库里。我的建议是把整个过程当成一条流水线解析 - 清理 - 分块 - 向量化 - 入库。每种文件类型走独立的子管道而不是一个函数通吃。比如PDF需要先处理多栏布局和水印扫描件要先过OCRMarkdown直接走结构感知分块表格走结构化提取。解析质量直接决定分块质量。这一条在踩过足够多的坑之后你会深有体会——很多分块问题其实是上游解析问题比如PDF解析把段落顺序打乱后面的分块策略再优秀也无济于事。4.2 元数据设计企业级分块的“身份证”分块之后产生的每个chunk都应该有一张自己的“身份证”这就是元数据。一个相对完整的设计会包含文档ID、标题路径、页码、章节号、权限标签、更新时间、内容哈希等。一个chunk的典型结构大概是{ chunk_id: 6f18a3c0-9b72-4e6c-9f30-1c2d8e4a7b5f, doc_id: policy_2024_081, title_path: [员工管理制度, 第三章 考勤管理, 第八条 迟到与早退], page: 12, content: 员工迟到超过30分钟按旷工半日处理……, permission_tag: internal, content_hash: sha256: a3f2..., updated_at: 2024-06-30T10:00:00Z }元数据的价值主要体现在三个方面一是检索时可以实现过滤比如只查客户合同的第三章节二是权限控制——分块不能越过文档的权限边界绝不能把高敏感内容和公开内容混在同一个块里三是溯源回答文本可以明确标注来自哪份文档、哪个章节、哪一页这在企业审计场景里几乎是硬性要求。4.3 多粒度分块与agentic RAG的方向传统RAG的路径是“一次检索一次回答”但这两年agentic RAG的方向明显起来了。它的检索不再是单轮而是多轮、多路径、带规划agent先定位到文档再精确到段落再判断是否需要更多上下文。这种情况下单一粒度的分块索引往往不够用。比较务实的做法是建立多粒度索引粗粒度块负责定位文档和章节细粒度块负责提取答案检索时先用粗粒度缩小范围再用细粒度命中细节。RAG也正在走向服务化RAG as Service分块策略开始从代码里的硬编码参数变成可配置的服务参数。上层应用可以指定按结构感知切还是按语义阈值切服务端按需执行。这是一个值得关注的演进方向Java生态里LangChain4j Easy RAG这类项目已经在往这个方向贴近。4.4 增量更新、去重与版本管理企业知识库不是静态的文档会改版。这是分块管线最容易崩的地方。我自己的做法是入库前先计算整个文档的哈希指纹如果哈希没变直接跳过如果变了只对变更段落关联的块做重新切分和向量化而不是把整个知识库推倒重来。块的元数据里要带上content_hash和更新时间这样清理无效向量时也有明确依据。还要关注文档级去重。同一份文件被不同部门反复上传是知识库里的常见情况。分块前先按全文哈希去重可以省下大量embedding调用和存储成本。这个环节看起来不起眼但在几十万级文档的规模下省下的成本非常可观。5. 实测复盘分块最常见的坑和效果评估方法5.1 表格被切断检索结果瞬间变成天书表格几乎可以说是通用分块器的天敌。我在早期项目里就吃过亏一个产品对比表被切成三块模型检索到其中一块时表头和关键的对比列全都不在了回答出来的内容完全不可信。处理方式我在2.5里提过表格要整块保留或者在解析阶段就做结构化抽取。如果你用的是PDF解析先把页面里的表格区域识别出来单独走表格管线再和其他文本块一起入库。这是目前我认为最稳定的处理方式。5.2 标题与正文分离答案“无家可归”另一个高频问题是标题和正文被切到了不同的块里。比如“第三章 考勤管理”这个标题落在上一个块的末尾正文“第八条 迟到与早退”落在下一个块的开头。检索时模型拿到了正文却不知道这是哪一章哪一条回答的上下文自然残缺。解决办法是结构感知分块时把上层标题链注入每个正文块的开头。这样即使正文被单独召回模型也知道自己的坐标在哪里。这也体现了元数据设计的价值title_path不是冗余信息而是检索质量的一部分。5.3 中英混排与代码截断分块器的“语言盲区”中英混排的文档对按字符切分非常不友好。尤其是技术文档里经常出现的“英文术语 中文解释”如果切分点落在英文单词中间检索时一个单词被拆成两半召回质量立刻下滑。我的经验是给分块器增加“语言切换点”作为额外分隔符并在递归字符分块里设置足够细的分隔符优先级。代码和说明混排的Markdown则要利用代码块边界先把代码块识别出来整体保留再对文字部分递归切分。5.4 如何评估分块质量不要只看召回率最后聊聊怎么判断分块策略到底行不行。很多人只看召回率、命中率但一个更容易操作的双指标组合是问题集命中率 答案完整率。做法是自己准备一批种子问题每个问题标注预期答案分布在哪份文档、哪个章节。然后跑检索看top3块是否包含完整答案。如果命中率高但答案不完整说明分块粒度太细上下文不够如果命中率低但答案都在说明分块粒度太大噪声把有效信息淹没了。有条件的团队可以让一个更强的模型当裁判自动打分但初始阶段我强烈建议人工抽检至少200条。因为机器评分容易把“看起来沾边”误判为“正确”而分块质量问题恰恰常常表现为“上下文差一点就完整”。以我个人的体会分块这个环节的调试不像写代码那么有确定性——它不是改一下就好了而是改一下然后去测再去感受误差。每次调参之后我都会把召回结果打印出来一行行看过再决定下一步是调整chunk_size、换分块策略、还是改元数据。这个过程很磨人但它是RAG项目从Demo走向可用的必经之路。如果后续想进一步突破可以在分块质量稳定之后叠加GraphRAG用实体关系解决多跳问题或者尝试让LLM动态决定块边界。但前提仍然是先把分块这个地基打扎实否则上层再花哨也很难立得住。
企业数字化 ERP 产品动态
相关推荐
云南本地云服务市场分析与选型指南 1. 云南本地云服务市场现状分析云南作为西南地区数字经济发展的重要节点,近年来云计算基础设施需求呈现爆发式增长。根据行业调研数据显示,2022年云南企业上云率同比提升37%,其中中小企业占比达到68%。这种增长态势催生了一批立足本地的云服务… · 2026/11/3 23:52:13
arXiv每日论文分析系统:轻量级学术信息流处理方案 1. 这不是“订阅推送”,而是一套可复用的学术信息流处理系统你有没有过这样的经历:每天早上打开 arXiv,面对 200 新提交的论文标题,手指划到发酸,却连摘要都没点开几篇?更别说筛选出真正和自己研究方向相关… · 2026/11/3 23:52:13
3天用AI将Ghostty终端从Linux移植到Windows的实践 1. 项目缘起:为什么非要碰 Ghostty 这块硬骨头1.1 我所理解的 Ghostty 与 Windows 用户的“怨念”先交代一下背景。Ghostty 这个终端模拟器,在 2024 年底一亮相就把热度拉满,作者是 Hashimoto,对,就是搞 Vagrant、Terr… · 2026/11/3 23:52:13
uniapp海外游戏分发工程:PG电子集成与Switch卡带区域适配 简介:这是一套面向海外游戏业务开发者的全栈前端解决方案,基于UniApp框架实现跨平台兼容,专为构建海外游戏交易平台、手游下载站及Switch游戏卡带销售系统设计。资源包含完整可二次开发的前端源码(非编译后产物)&#… · 2026/11/4 0:00:17
Qoder NEXT:智能代码补全工具的技术解析与应用 1. 项目概述Qoder NEXT作为新一代智能编程辅助工具,其核心突破在于通过深度优化代码补全算法,将AI生成代码的开发者采纳率提升了65%。这个数字背后代表着编程效率的实质性飞跃——开发者不再需要花费大量时间在重复性代码编写和机械性调试上,… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46