实现消息引用回复

0 阅读2分钟

本次功能

消息引用回复

效果:

  • 点击某条消息的“引用”
  • 输入框上方出现“正在引用这条消息”
  • 发送时把引用内容一起带给模型
  • 但不会污染原始消息列表结构

1)改 web/src/App.vue

新增状态

const quotedMessage = ref(null)

新增方法

const handleQuoteMessage = (item, index) => {
  quotedMessage.value = {
    index,
    role: item.role,
    content: item.content,
  }
}

const clearQuotedMessage = () => {
  quotedMessage.value = null
}

新增一个构造发送消息的方法

const buildMessagesForRequest = (messages = []) => {
  if (!quotedMessage.value) return messages

  const quoteRole =
    quotedMessage.value.role === 'user'
      ? '用户'
      : quotedMessage.value.role === 'assistant'
      ? 'AI'
      : quotedMessage.value.role

  const quotePrompt = [
    '以下是用户本次特别引用的一段历史消息,请你在回答时重点参考:',
    '',
    `引用角色:${quoteRole}`,
    `引用内容:${quotedMessage.value.content}`,
  ].join('\n')

  const nextMessages = [...messages]
  const systemIndex = nextMessages.findIndex(item => item.role === 'system')

  if (systemIndex > -1) {
    nextMessages[systemIndex] = {
      ...nextMessages[systemIndex],
      content: `${nextMessages[systemIndex].content}\n\n${quotePrompt}`,
    }
  } else {
    nextMessages.unshift({
      role: 'system',
      content: quotePrompt,
    })
  }

  return nextMessages
}

sendMessage

  try {
    const requestMessages = buildMessagesForRequest(currentSession.value.messages)
    await sendMessageStream(requestMessages)
    clearQuotedMessage()
  } catch (error) {

给消息操作栏增加“引用”

<div v-if="item.role !== 'system'" class="msg-actions">
  <span class="msg-action-btn" @click="handleQuoteMessage(item, index)">引用</span>
  <span class="msg-action-btn" @click="copyMessage(item.content)">复制</span>
  <span class="msg-action-btn delete" @click="handleDeleteMessage(index)">删除</span>
  <span
    v-if="item.role === 'assistant'"
    class="msg-action-btn"
    @click="handleRegenerate(index)"
  >
    重新生成
  </span>
</div>

在输入框上方增加引用条

<div v-if="quotedMessage" class="quote-bar">
  <div class="quote-content">
    <span class="quote-label">
      正在引用 {{ quotedMessage.role === 'user' ? '用户' : 'AI' }} 消息:
    </span>
    <span class="quote-text">{{ quotedMessage.content }}</span>
  </div>
  <span class="quote-close" @click="clearQuotedMessage">取消</span>
</div>

新增样式

.quote-bar {
  margin-top: 8px;
  margin-bottom: 12px;
  padding: 10px 12px;
  border: 1px solid #dbeafe;
  background: #eff6ff;
  border-radius: 12px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.quote-content {
  min-width: 0;
  flex: 1;
}

.quote-label {
  font-size: 12px;
  color: #1d4ed8;
  margin-right: 6px;
}

.quote-text {
  font-size: 13px;
  color: #1f2937;
  word-break: break-word;
}

.quote-close {
  flex-shrink: 0;
  font-size: 12px;
  color: #6b7280;
  cursor: pointer;
}

.quote-close:hover {
  color: #111827;
}

2)验证

基础验证

  1. 找一条历史消息,点 引用

  2. 输入框上方出现引用条

  3. 再提问一句 可以基于这个进行

  4. AI 回复应该会明显参考被引用内容

取消验证

取消 后,引用条消失,后续发送恢复普通模式。

image.png

image.png

image.png

取消

image.png

nice !

本次提交仓库

github.com/fhj414/ai-c…