diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
index 36409c154..d8c849932 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
@@ -38,12 +38,10 @@ import kotlin.reflect.KProperty
  * - [asMessageChain] 将 [Iterable], 等类型消息
  * - [messageChainOf] 类似 [listOf], 将多个 [Message] 构造为 [MessageChain]
  *
- * ### 消息链如何工作
- * - [SingleMessageChainImpl] 将 [单个消息][SingleMessage] 委托为一个 [MessageChain]
- *
  * @see get 获取消息链中一个类型的元素, 不存在时返回 `null`
  * @see getOrFail 获取消息链中一个类型的元素, 不存在时抛出异常 [NoSuchElementException]
- * @see quote 引用这条消息.
+ * @see quote 引用这条消息
+ * @see recall 撤回这条消息 (
  *
  * @see buildMessageChain 构造一个 [MessageChain]
  * @see asMessageChain 将单个 [Message] 转换为 [MessageChain]
diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt
index 66a7c0094..7bda88ce6 100644
--- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt
+++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt
@@ -16,6 +16,7 @@ package net.mamoe.mirai.message.data
 import kotlinx.coroutines.Job
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
+import net.mamoe.mirai.utils.PlannedRemoval
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.jvm.JvmMultifileClass
@@ -59,48 +60,6 @@ class QuoteReply(val source: MessageSource) : Message, MessageMetadata, Constrai
     override fun hashCode(): Int = source.hashCode()
 }
 
-/**
- * @see MessageSource.id
- */
-@get:JvmSynthetic
-inline val QuoteReply.id: Int
-    get() = source.id
-
-/**
- * @see MessageSource.internalId
- */
-@get:JvmSynthetic
-inline val QuoteReply.internalId: Int
-    get() = source.internalId
-
-/**
- * @see MessageSource.fromId
- */
-@get:JvmSynthetic
-inline val QuoteReply.fromId: Long
-    get() = source.fromId
-
-/**
- * @see MessageSource.targetId
- */
-@get:JvmSynthetic
-inline val QuoteReply.targetId: Long
-    get() = source.targetId
-
-/**
- * @see MessageSource.originalMessage
- */
-@get:JvmSynthetic
-inline val QuoteReply.originalMessage: MessageChain
-    get() = source.originalMessage
-
-/**
- * @see MessageSource.time
- */
-@get:JvmSynthetic
-inline val QuoteReply.time: Int
-    get() = source.time
-
 /**
  * @see MessageSource.bot
  */
@@ -108,15 +67,69 @@ inline val QuoteReply.time: Int
 inline val QuoteReply.bot: Bot
     get() = source.bot
 
-
+/**
+ * 撤回引用的源消息
+ */
 @JvmSynthetic
-suspend inline fun QuoteReply.recall() = this.source.recall()
+suspend inline fun QuoteReply.recallSource() = this.source.recall()
 
 /**
- * 在一段时间后撤回这条消息.
+ * 在一段时间后撤回引用的源消息
  */
 @JvmOverloads
+inline fun QuoteReply.recallSourceIn(
+    millis: Long,
+    coroutineContext: CoroutineContext = EmptyCoroutineContext
+): Job = this.source.recallIn(millis, coroutineContext)
+
+
+//// 因语义不明而弃用的 API, 兼容到 1.3.0
+
+@PlannedRemoval("1.3.0")
+@get:JvmSynthetic
+@Deprecated("use source.id for clearer semantics", ReplaceWith("source.id"))
+inline val QuoteReply.id: Int
+    get() = source.id
+
+@PlannedRemoval("1.3.0")
+@get:JvmSynthetic
+@Deprecated("use source.internalId for clearer semantics", ReplaceWith("source.internalId"))
+inline val QuoteReply.internalId: Int
+    get() = source.internalId
+
+@PlannedRemoval("1.3.0")
+@get:JvmSynthetic
+@Deprecated("use source.fromId for clearer semantics", ReplaceWith("source.fromId"))
+inline val QuoteReply.fromId: Long
+    get() = source.fromId
+
+@PlannedRemoval("1.3.0")
+@get:JvmSynthetic
+@Deprecated("use source.targetId for clearer semantics", ReplaceWith("source.targetId"))
+inline val QuoteReply.targetId: Long
+    get() = source.targetId
+
+@PlannedRemoval("1.3.0")
+@get:JvmSynthetic
+@Deprecated("use source.originalMessage for clearer semantics", ReplaceWith("source.originalMessage"))
+inline val QuoteReply.originalMessage: MessageChain
+    get() = source.originalMessage
+
+@PlannedRemoval("1.3.0")
+@get:JvmSynthetic
+@Deprecated("use source.time for clearer semantics", ReplaceWith("source.time"))
+inline val QuoteReply.time: Int
+    get() = source.time
+
+@PlannedRemoval("1.3.0")
+@Deprecated("use recallSourceIn for clearer semantics", ReplaceWith("recallSourceIn(millis, coroutineContext)"))
+@JvmOverloads
 inline fun QuoteReply.recallIn(
     millis: Long,
     coroutineContext: CoroutineContext = EmptyCoroutineContext
-): Job = this.source.recallIn(millis, coroutineContext)
\ No newline at end of file
+): Job = recallSourceIn(millis, coroutineContext)
+
+@PlannedRemoval("1.3.0")
+@Deprecated("use recallSource for clearer semantics", ReplaceWith("this.recallSource()"))
+@JvmSynthetic
+suspend inline fun QuoteReply.recall() = recallSource()