知识库接 TaoToken 后,文档问答的 Token 消耗在哪几步
1. 从一次“检索到了但答错”的现场开始把腾讯开源的文档知识库问答项目跑起来后最容易被忽略的不是 PDF 解析而是知识库服务里的LLM_BASE_URL和LLM_API_KEY。我这次遇到的现场很典型上传一份 120 页的产品手册问“质保期内更换运费谁承担”系统明明检索到了相关段落生成答案却引用了另一章。查日志发现检索 top-k 命中了 3 个片段但context_tokens只有 900而生成模型看到的 prompt 里混入了上一轮对话。最后定位到两个问题一是.env里 API 地址填成了带/v1的路径导致部分请求 404 后回退到空上下文二是 embedding 模型中途换过旧索引维度对不上。这里建议直接去 TaoToken 官网拿 Keyhttps://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentkb_token_intro Base URL 用https://taotoken.net/api。本文按知识库链路排障工程师的视角把文档解析、嵌入、检索、生成四阶段的 Token 消耗拆开并给出可复现日志字段和 Token 消耗表。先说明适用对象如果你的知识库问答服务支持 OpenAI 兼容接口或者支持自定义 API Base就可以把供应商切到 TaoToken。关键不是“换个 Key”这么简单而是要知道 Token 花在哪一步否则你只会看到总账单涨了却不知道是嵌入重复计算、检索 rerank 调用过多还是生成阶段把太多片段塞进上下文。2. 四阶段拆账Token 到底在哪几步被消耗文档知识库问答一般拆成四段文档解析、嵌入、检索、生成。很多人以为“问答”才耗 Token其实嵌入阶段在首次建库时可能一次性消耗大量 Token生成阶段则每次提问都会消耗并且和 top-k、历史对话、引用模板强相关。阶段是否消耗 LLM/Embedding Token主要计费对象常见日志字段优化重点文档解析普通文本解析通常不耗OCR、视觉模型解析会耗页数、图片数、OCR 字符数doc_id、page_count、ocr_pages、parse_tokens只对扫描件启用 OCR表格转 Markdown 后缓存嵌入消耗 Embedding Token所有 chunk 的输入 Token查询向量也耗少量chunk_count、embedding_input_tokens、embedding_model增量索引合理分块避免重复重建检索向量检索不耗生成 Tokenrerank、query rewrite 可能耗rerank 输入/输出 Token改写后的查询 Tokentop_k、retrieved_ids、rerank_tokens先召回后精排低分片段不送生成生成消耗 Chat Token系统提示、检索上下文、历史对话、用户问题、输出答案prompt_tokens、completion_tokens、context_tokens控制上下文长度去重按问题复杂度选模型把公式写清楚总 Token ≈ 解析 Token 嵌入 Token 检索附加 Token 生成 Token 嵌入 Token ≈ 文档 chunk 总 Token 查询向量 Token × 提问次数 生成 Token ≈ (系统提示 历史对话 检索上下文 用户问题 输出答案) × 提问次数如果你只统计prompt_tokens和completion_tokens会漏掉嵌入阶段。尤其是首次建库时嵌入可能比一次问答的生成消耗更大。反过来如果知识库已经建好日常问答的主要波动来自生成阶段top-k 从 3 调到 8上下文可能翻倍历史对话保留 5 轮prompt 里就会多出几千 Token。3. 可复现日志把解析、嵌入、检索、生成拆成四段 JSON排障不能靠猜。建议在知识库服务里给四个阶段分别打日志字段统一成 JSON至少记录trace_id、stage、model、input_tokens、output_tokens、latency_ms、knowledge_base_id、doc_id、chunk_count、top_k、retrieved_ids、context_tokens。这样你才能把一次问答的 Token 消耗按阶段归因。下面是一个可运行的 Python logging 配置示例输出结构化 JSONimport json import logging import sys from datetime import datetime class JsonFormatter(logging.Formatter): def format(self, record): payload { ts: datetime.utcnow().isoformat(), level: record.levelname, stage: getattr(record, stage, None), trace_id: getattr(record, trace_id, None), knowledge_base_id: getattr(record, knowledge_base_id, None), doc_id: getattr(record, doc_id, None), model: getattr(record, model, None), input_tokens: getattr(record, input_tokens, 0), output_tokens: getattr(record, output_tokens, 0), context_tokens: getattr(record, context_tokens, 0), top_k: getattr(record, top_k, None), retrieved_ids: getattr(record, retrieved_ids, []), latency_ms: getattr(record, latency_ms, 0), message: record.getMessage(), } return json.dumps(payload, ensure_asciiFalse) logger logging.getLogger(kb) logger.setLevel(logging.INFO) handler logging.StreamHandler(sys.stdout) handler.setFormatter(JsonFormatter()) logger.addHandler(handler) logger.info( embedding done, extra{ stage: embedding, trace_id: req-20250101-001, knowledge_base_id: kb_product_manual, doc_id: manual_v3.pdf, model: YOUR_EMBEDDING_MODEL, input_tokens: 153600, output_tokens: 0, latency_ms: 8420, }, ) logger.info( retrieval done, extra{ stage: retrieval, trace_id: req-20250101-001, knowledge_base_id: kb_product_manual, top_k: 6, retrieved_ids: [chunk_18, chunk_22, chunk_41], context_tokens: 2700, latency_ms: 126, }, ) logger.info( generation done, extra{ stage: generation, trace_id: req-20250101-001, knowledge_base_id: kb_product_manual, model: YOUR_CHAT_MODEL, input_tokens: 3660, output_tokens: 600, context_tokens: 2700, latency_ms: 3150, }, )一份典型日志展开后像这样{stage:parse,doc_id:manual_v3.pdf,message:parse done,input_tokens:0,output_tokens:0,latency_ms:2310} {stage:embedding,doc_id:manual_v3.pdf,model:YOUR_EMBEDDING_MODEL,input_tokens:153600,output_tokens:0,latency_ms:8420} {stage:retrieval,trace_id:req-20250101-001,top_k:6,retrieved_ids:[chunk_18,chunk_22,chunk_41],context_tokens:2700,latency_ms:126} {stage:generation,trace_id:req-20250101-001,model:YOUR_CHAT_MODEL,input_tokens:3660,output_tokens:600,context_tokens:2700,latency_ms:3150}有了这些字段你可以回答三个问题第一首次建库的嵌入到底花了多少第二每次问答的检索是否召回为空第三生成阶段的上下文是不是被历史对话撑爆。没有日志时排障只能靠感觉有日志后Token 消耗表才可复现。4. 接入 TaoToken给知识库服务填 Key、Base URL 与模型名知识库问答服务通常会在.env、config.yaml或控制台里要求填 LLM API Key 和 API 地址。这里统一去 TaoToken 官网获取https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentkb_token_config 。Base URL 填https://taotoken.net/api不要在后面随手加/v1或/chat/completions路径交给框架或 SDK 拼接。Key 用占位符YOUR_API_KEY表示。一个通用的.env配置示例LLM_PROVIDERopenai_compatible LLM_BASE_URLhttps://taotoken.net/api LLM_API_KEYYOUR_API_KEY CHAT_MODELYOUR_CHAT_MODEL EMBEDDING_BASE_URLhttps://taotoken.net/api EMBEDDING_API_KEYYOUR_API_KEY EMBEDDING_MODELYOUR_EMBEDDING_MODEL KB_CHUNK_SIZE800 KB_CHUNK_OVERLAP120 KB_TOP_K6 KB_MAX_CONTEXT_TOKENS6000 KB_HISTORY_ROUNDS2如果你的框架把聊天模型和嵌入模型分开配置就分别填两套如果只允许填一个 Base URL就都填https://taotoken.net/api。注意更换嵌入模型后旧向量索引不能直接复用。向量维度、归一化方式、语料切分方式都可能变化。正确做法是新建索引、重新嵌入、验证检索命中再切换线上流量。常见报错和定位方向现象可能原因检查点401 UnauthorizedKey 为空、写错、请求头没带 Bearer检查LLM_API_KEY、Authorization头404 Not FoundBase URL 多了/v1或框架拼接路径重复Base URL 改为https://taotoken.net/api429 Too Many Requests并发过高、批量嵌入未限流降低并发、增加重试退避、分批嵌入400 model not found模型名填错或账户未开通该模型在 TaoToken 控制台确认模型名维度不匹配索引 embedding 与当前 embedding 不一致重建索引不要混用旧向量上下文超限top-k 过大、历史对话过长降KB_TOP_K压缩上下文截断历史这里再强调一次不要在代码里写死 Key。用环境变量或密钥管理服务。日志里也不要打印完整 Key只打印前 6 位和后 4 位即可。5. Token 消耗表一次 120 页 PDF 问答的可复现模板下面给一份示例模板数字用于说明统计方法你需要在本地用真实日志替换。假设一份 120 页产品手册解析后得到 320 个 chunk平均每个 chunk 480 Token用户问了 20 个问题检索 top-k6每次生成输入约 3600 Token输出约 600 Token。阶段次数/规模输入 Token输出 Token备注文档解析120 页00普通文本 PDF未启用 OCR文档嵌入320 chunks1536000仅首次建库增量更新只算新增 chunk查询嵌入20 次提问12000每次问题向量约 60 Token检索向量20 次00本地向量库检索不计生成 Tokenrerank20 次160001000若启用 LLM rerank 才计入生成20 次7320012000每次约 3660 输入 600 输出合计-24400013000未启用 rerank 时合计约 228000 输入把公式套进去首次建库总 Token 解析 Token 嵌入 Token 每次问答增量 Token 查询嵌入 Token 检索附加 Token 生成输入 Token 生成输出 Token 20 次问答增量 Token 20 × (60 0 3660 600) ≈ 86400很多团队只盯生成 Token结果发现嵌入阶段才是首次建库大头。也有团队反过来建库后不清理旧 chunk文档每次更新都全量重嵌导致嵌入 Token 持续浪费。正确做法是给每个 chunk 记录doc_id、doc_version、content_hash、embedding_model文档更新时只重嵌内容变化的 chunk。建议你在自己的知识库服务里落一张token_usage表或日志表字段至少包括CREATE TABLE token_usage ( id BIGINT PRIMARY KEY, trace_id VARCHAR(64), stage VARCHAR(32), knowledge_base_id VARCHAR(64), doc_id VARCHAR(128), model VARCHAR(128), input_tokens INT, output_tokens INT, context_tokens INT, top_k INT, latency_ms INT, created_at TIMESTAMP );SQL 由你在本地数据库执行不要直连生产库跑实验。先在小库或本地库验证统计口径再接入线上。6. 排障优先级先看检索日志再看生成日志文档问答答错时不要第一反应就调 prompt。先按这个顺序查用户问题是否被正确改写。如果 query rewrite 把“运费谁承担”改成了“退换货政策”检索可能跑偏。检索是否命中。看retrieved_ids是否包含人工标注的相关 chunk。命中片段是否被送进生成。看context_tokens和实际拼接的上下文有些框架会因为长度限制截断后面的片段。生成模型是否被错误上下文干扰。看 prompt 模板里是否把低分片段放在前面。输出是否引用了不存在的片段。看引用 ID 是否在retrieved_ids里。如果检索为空优先调分块和嵌入而不是生成模型。分块太大一个 chunk 混入多个主题向量语义被稀释分块太小上下文不完整生成阶段即使拿到片段也无法回答。可以从 800 Token、重叠 120 开始再根据文档类型调整。技术手册可以按标题层级切合同可以按条款切FAQ 可以按问答对切。如果检索命中但回答错重点看生成阶段的上下文组织。下面是一份可复现的 YAML 参数示例knowledge_base: chunk_size: 800 chunk_overlap: 120 embedding_model: YOUR_EMBEDDING_MODEL embedding_batch_size: 32 index_type: vector incremental_index: true retrieval: top_k: 6 score_threshold: 0.35 rerank: true rerank_top_n: 3 max_context_tokens: 6000 generation: model: YOUR_CHAT_MODEL temperature: 0.2 max_output_tokens: 800 history_rounds: 2 cite_sources: true这份配置里score_threshold能避免低分片段进入生成rerank_top_n能减少上下文长度history_rounds能控制历史对话的 Token。不要小看这几项top-k 从 6 调到 12上下文可能直接翻倍生成 Token 也会跟着涨。7. Claude Code、Codex、CC Switch 的配置别混用知识库服务接 TaoToken 是一套配置本地开发工具接 TaoToken 是另一套配置不要混。Claude Code 用settings.json和ANTHROPIC_*Codex 用config.toml不要把ANTHROPIC_*套到 Codex 上。Claude Code 的settings.json示例{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: YOUR_API_KEY, ANTHROPIC_MODEL: YOUR_CLAUDE_MODEL } }Codex 的config.toml示例model_provider taotoken model YOUR_CODEX_MODEL [model_providers.taotoken] name TaoToken base_url https://taotoken.net/api env_key TAOTOKEN_API_KEY wire_api responsesCodex 对应的环境变量export TAOTOKEN_API_KEYYOUR_API_KEY如果你用 CC Switch 管理供应商三件套要填清楚Provider 名称TaoTokenBase URLhttps://taotoken.net/apiAPI KeyYOUR_API_KEY模型名按你的客户端和 TaoToken 控制台里可用的模型填。CC Switch 的核心是把不同工具的环境变量和配置文件隔离不要在一个 shell 里同时导出多套冲突变量。排障时先env | grep -E ANTHROPIC|TAOTOKEN|OPENAI确认当前终端用的是哪套。8. 把 Token 消耗降下来知识库问答的 8 个参数最后给一份优化清单按收益从高到低排开启增量索引。文档没变就不重嵌content_hash相同的 chunk 直接复用向量。控制分块大小。太大语义混杂太小上下文缺失技术文档从 800/120 起步。设置检索分数阈值。低分片段不送生成比生成阶段截断更省。先召回再精排。向量召回 20 条rerank 取 3 到 5 条不要全部塞进 prompt。压缩历史对话。只保留最近 2 轮或把历史摘要成 200 Token。缓存高频问题。相同问题命中缓存直接返回答案和引用不再调用生成。分级模型。简单事实问答用轻量模型复杂对比总结再换更强模型。记录 Token 消耗表。按阶段、按知识库、按文档版本统计发现异常增长。一份缓存配置示例cache: enabled: true backend: redis ttl_seconds: 86400 key_prefix: kb:qa: include_kb_version: true include_model: true注意include_kb_version和include_model要打开。知识库更新或模型切换后旧缓存必须失效否则会返回过期答案。Token 优化不是一味少用而是把 Token 花在真正影响答案质量的地方嵌入要准检索要召回相关片段生成要看到干净上下文。9. 文末 CTA按这个顺序验证和落地如果你正在给知识库问答服务填 API Key 和 API 地址建议按下面顺序走一遍先到模型对话页验证 Key 和 Base URL 是否可用https://taotoken.net/models/detail/chat?utm_sourcetaotoken_aicg_blog_endutm_contentkb_token_chat如果后续要做代码知识库、文档问答和长上下文任务可以看 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentkb_token_plan然后在控制台创建 API Key填入知识库服务的LLM_API_KEY和EMBEDDING_API_KEYhttps://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentkb_token_key如果你同时使用 Claude Code 做本地排障配置参考https://taotoken.net/doc/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_contentkb_token_claude_code官网入口再放一次方便你从 Key、Base URL 到控制台一次性核对https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentkb_token_final 。记住本文的核心文档解析、嵌入、检索、生成四阶段要分开打日志Base URL 用https://taotoken.net/apiKey 用YOUR_API_KEY占位Token 消耗表按阶段统计。这样下次再遇到“检索到了但答错”你就能从日志里直接看到是嵌入重复、检索跑偏还是生成上下文太长。

相关新闻

大数据数据挖掘算法实战:从Spark集群部署到模型调参

大数据数据挖掘算法实战:从Spark集群部署到模型调参

简介:一份面向大数据、数据挖掘方向本科生及毕业设计撰写者的学位论文PDF,内容围绕数据挖掘算法实现与应用,重点讲解关联规则Apriori算法和神经网络BP算法,并分别用于高校排课优化与政府投资项目投资估算两个真实场景,…

2026/9/22 11:37:53 阅读更多 →
Continue 跑 Agent 模式:Key 用 TaoToken

Continue 跑 Agent 模式:Key 用 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/22 9:47:50 阅读更多 →
DeepSeek兼容OpenAI SDK的跨平台接入指南:只需改配置即可调用

DeepSeek兼容OpenAI SDK的跨平台接入指南:只需改配置即可调用

简介:面向需要同时调用DeepSeek与OpenAI能力的开发者,这份PDF指南系统讲解如何在30分钟内完成跨平台兼容集成。文档共26页,从跨平台集成基础概念切入,逐一对比DeepSeek与OpenAI SDK在架构、功能特性与适用场景上的差异&#xff0c…

2026/9/22 11:37:53 阅读更多 →

最新新闻

华为浏览器下载源码图解原理与实战拆解

华为浏览器下载源码图解原理与实战拆解

华为浏览器下载源码图解原理与实战拆解 学会语法却不知怎么搭项目?这是很多初学者的通病。看着文档里的 download() 方法,心里没底,不知道底层到底发生了什么。今天咱们不聊虚的,直接通过 图解原理…

2026/9/23 20:21:37 阅读更多 →
面试突击:手写实现“头很痛怎么办”背后的算法逻辑

面试突击:手写实现“头很痛怎么办”背后的算法逻辑

面试突击:手写实现“头很痛怎么办”背后的算法逻辑 是不是感觉脑子像浆糊一样,看了一堆教程还是不会写项目?别慌,这其实是大多数开发者的通病。很多兄弟在掘金技术社区发帖吐槽,说面试时遇到“头很痛怎么办”这种看似无厘头的问题,直接懵圈。其实,这根…

2026/9/23 20:21:37 阅读更多 →
意间AI绘画手写实现:3步搞定项目搭建避坑指南

意间AI绘画手写实现:3步搞定项目搭建避坑指南

意间AI绘画手写实现:3步搞定项目搭建避坑指南 刚毕业那会儿,我拿着Python语法书,看着满屏的 def 和 class ,脑子是清醒的,但手是废的。为什么?因为 学会语法却不知怎么搭项目 。你懂 for…

2026/9/23 20:21:37 阅读更多 →
3个步骤搞懂火热的死亡:前端避坑指南

3个步骤搞懂火热的死亡:前端避坑指南

3个步骤搞懂火热的死亡:前端避坑指南 刚学完 if-else 和循环,代码能跑,一搭项目就崩?别慌,这几乎是每个开发者的必经之路。很多新手卡在“语法会写,项目不会搭”的鸿沟里,反复查文档却找不到头绪。这篇避坑指南不讲虚的,直接拆解一个典型故…

2026/9/23 20:21:37 阅读更多 →
逾越节速查手册

逾越节速查手册

逾越节源码图解:3步搞懂版本升级API变更原理 逾越节源码图解:3步搞懂版本升级API变更原理 版本升级后 API 全变了,文档翻烂也找不到对应方法,这是无数开发者踩过的坑。别慌,今天用【图解原理】拆解逾越节核心逻辑,从入口到执行链路逐行剖…

2026/9/23 20:20:35 阅读更多 →
搞懂头层皮和二层皮的区别,从入门到精通的避坑指南

搞懂头层皮和二层皮的区别,从入门到精通的避坑指南

搞懂头层皮和二层皮的区别,从入门到精通的避坑指南 版本升级后 API 全变了,这是无数开发者在技术进阶路上遇到的第一道鬼门关。很多人卡在“头层皮”的表象逻辑里,以为读懂了文档就能上手,结果一跑代码全是报错。真正的 入门到精通…

2026/9/23 20:20:35 阅读更多 →

日新闻

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析

3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A…

2026/9/23 0:00:23 阅读更多 →
2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我

2k显示屏性能优化踩坑:版本升级后API全变了,这份源码解析救了我 刚把开发环境的显示器从1080P换到2K,跑老项目直接报错,版本升级后 API…

2026/9/23 0:01:25 阅读更多 →
3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点

3步搞定美眉图实战项目,告别官方文档抓不住重点 官方文档翻了三遍还是云里雾里?别急,美眉图在实战项目中常被用来做数据可视化,但它的原理比你想的简单。今天咱们直接上手,用一个完整的小项目把美眉图跑通,不再死磕那些冗长的理论说明。…

2026/9/23 0:01:25 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →