最近在开发基于 Claude API 的应用时,发现一个挺影响体验的小问题:当用户通过 WebSocket 或流式接口与 Claude 对话时,Claude 有时会在回复中插入一些类似 [thinking] [pause] 的内部标记。这些标记本意是展示模型的“思考过程”,但在实际产品中,它们会直接显示给终端用户,打断对话的流畅性,显得很不专业。

今天我们就来深入聊聊这个“Claude Tag”问题,并手把手教你一套完整的解决方案。无论你是正在集成 Claude API 的后端开发者,还是负责优化对话体验的产品工程师,这篇文章都能帮你彻底解决这个烦人的“小尾巴”。我们将从问题现象、根因分析,一直讲到代码层面的过滤方案和工程最佳实践。

1. 背景与核心概念:什么是 Claude Tag?

在深入解决方案之前,我们首先要搞清楚问题是什么。Claude Tag,并不是一个官方术语,而是开发者社区对 Claude 模型(特别是 Claude 3 系列模型)在流式输出中可能插入的特定文本片段的统称。

1.1 问题现象

当你调用 Claude API 的流式接口(例如 stream=True )时,可能会在正常的对话回复中,看到一些意外的文本片段。例如:

用户:请帮我总结一下这篇文章。
Claude:好的,我来看看。[thinking]这篇文章主要讨论了人工智能的伦理问题...[/thinking] 根据我的阅读,这篇文章的核心观点是...

或者更简单的情况:

用户:今天的天气怎么样?
Claude:[pause] 我无法获取实时天气信息,但可以告诉你...

这些 [thinking] [pause] 或者类似的 [*] 标记,就是所谓的“Claude Tag”。它们并非模型有意生成的对话内容,而是模型在内部推理或组织语言时产生的“副产品”,通过流式接口泄露了出来。

1.2 为什么会出现这些 Tag?

理解其产生原因,有助于我们更精准地处理它。这主要与以下两点有关:

  1. 模型的“链式思考”特性 :像 Claude 这类先进的大语言模型,在生成回复时,内部会进行多步推理。它可能会先“思考”一个草稿,再生成最终答复。在某些配置或提示词下,这种“思考”过程可能会被部分地输出。
  2. API 流式输出的“原始性” :为了提供低延迟的体验,流式接口会尽可能快地将模型生成的 token 发送给客户端。这个过程中,一些在非流式模式下会被最终过滤掉的中间态文本,就有可能被一并发送出来。

1.3 带来的影响

这些 Tag 如果不处理,会直接破坏用户体验:

  • 专业性受损 :用户会觉得产品有 Bug,或者 AI 很“笨”。
  • 对话不连贯 :Tag 打断了回复的完整性,影响阅读。
  • 解析错误 :如果你在后端对回复内容进行 JSON 解析或其他处理,这些意外的标记可能导致解析失败。

因此,在将 Claude 的回复呈现给用户之前,进行 Tag 过滤是一项必要的后处理步骤。

2. 环境准备与版本说明

在开始编写过滤代码前,我们需要明确开发环境。本文的示例将主要使用 Python,因为这是与 OpenAI/Anthropic API 交互最常用的语言之一。

  • 操作系统 :Windows 10/11, macOS, 或 Linux (如 Ubuntu 20.04+) 均可。本文命令以 Linux/macOS 的 bash 为例,Windows 用户可使用 PowerShell 或 WSL。
  • Python 版本 :推荐 Python 3.8 及以上版本。确保你的 pip 是最新的。
  • 关键库
    • anthropic : Anthropic 官方的 Claude API 客户端库。这是核心依赖。
    • openai : 如果你使用 OpenAI 格式的兼容接口,也可能需要。
    • re : Python 标准库,用于正则表达式匹配,是我们过滤方案的核心。
  • IDE 或编辑器 :VS Code, PyCharm, 或任何你熟悉的文本编辑器。
  • Anthropic API 密钥 :你需要一个有效的 API 密钥。请前往 Anthropic 官网注册并获取。

安装依赖 : 在项目根目录下,使用以下命令安装必要的库:

# 创建并激活虚拟环境(推荐)
python -m venv venv
source venv/bin/activate  # Linux/macOS
# venv\Scripts\activate  # Windows

# 安装 anthropic 库
pip install anthropic

# 如果你需要测试流式请求,可以安装 httpx 以支持 SSE (Server-Sent Events)
# pip install httpx

版本说明 : 本文代码基于 anthropic 库版本 0.25.0+ 编写,并兼容 Claude 3 (Haiku, Sonnet, Opus) 模型。API 的行为可能随 Anthropic 的更新而微调,但核心的过滤逻辑是通用的。请根据你的实际环境调整。

3. 核心原理与过滤方案拆解

处理 Claude Tag 的核心思路是: 在将模型返回的文本内容交付给前端或用户之前,对其进行一次“清洗” 。这通常发生在后端服务层。

3.1 识别需要过滤的 Tag 模式

我们需要定义一个需要被移除的 Tag 模式列表。根据社区反馈和实际观察,常见的模式包括:

  1. 成对出现的 XML 式标签 :例如 [thinking]...[/thinking] , [reasoning]...[/reasoning] 。我们需要移除整个标签对及其内部内容,或者只移除标签保留内容。通常,为了回复的简洁,我们选择移除整个部分。
  2. 单个的方括号标签 :例如 [pause] , [*] , [继续] 。这些通常单独出现,需要被直接移除。
  3. 其他变体 :可能包括 (思考中...) , (pause) 等,取决于模型版本和提示词。

重要决策:移除标签还是保留内容? 对于 [thinking]...[/thinking] ,内部内容可能是模型的原始推理,有时包含有用信息(例如,模型自我纠正的过程)。但在绝大多数面向用户的产品场景中,这些内容过于原始且冗长, 直接移除整个标签对是更安全、更通用的选择 。如果你有特殊需求需要保留推理内容,可以只剥离标签字符。

3.2 技术选型:正则表达式 (Regex)

正则表达式是处理这类文本模式匹配和替换任务的绝佳工具。它灵活、高效,并且可以精确地描述我们想要匹配的 Tag 模式。

我们将使用 Python 的 re 模块。主要使用两个函数:

  • re.sub(pattern, repl, string, flags=0) : 将字符串中所有匹配正则表达式 pattern 的部分替换为 repl
  • re.compile(pattern, flags=0) : 将正则表达式字符串编译为一个正则表达式对象,便于重复使用,效率更高。

3.3 基础过滤函数设计

我们将设计一个可复用的函数 clean_claude_response(text: str) -> str 。它的职责是接收原始的 Claude 回复文本,返回清洗后的文本。

这个函数需要做到:

  1. 能够处理多种 Tag 模式。
  2. 能够正确处理嵌套标签(虽然不常见,但需考虑)。
  3. 避免过度匹配(例如,误伤用户输入中合法的方括号内容)。
  4. 性能良好,对单次回复的处理应在毫秒级。

4. 完整实战案例:构建 Claude 响应过滤器

现在,让我们从零开始,构建一个完整的、可投入生产环境的 Claude 响应过滤模块。

4.1 创建项目结构

首先,创建一个清晰的项目目录。

mkdir claude-tag-filter-demo
cd claude-tag-filter-demo
# 创建虚拟环境并激活(如前所述)
# 安装依赖(如前所述)

# 创建项目文件
touch claude_filter.py
touch main.py
touch test_responses.txt

4.2 编写核心过滤模块 ( claude_filter.py )

这是我们的核心工具模块。

# claude_filter.py
import re
from typing import List, Pattern

class ClaudeResponseCleaner:
    """
    Claude 响应清洗器,用于移除流式输出中可能出现的内部标签。
    例如:[thinking], [pause], [/thinking], [*] 等。
    """

    def __init__(self, custom_patterns: List[str] = None):
        """
        初始化清洗器,编译正则表达式模式。

        Args:
            custom_patterns: 用户自定义的正则表达式模式列表,用于扩展过滤规则。
        """
        # 定义默认的 Tag 模式
        # 1. 匹配成对的标签及其内部所有内容,如 [thinking]...[/thinking]
        #    `.*?` 是非贪婪匹配,匹配任意字符直到第一个 `[/thinking]`
        #    `flags=re.DOTALL` 使 `.` 也能匹配换行符
        default_patterns = [
            r'\[thinking\].*?\[/thinking\]',  # 移除整个 thinking 块
            r'\[reasoning\].*?\[/reasoning\]', # 移除整个 reasoning 块
            r'\[internal\].*?\[/internal\]',   # 移除其他可能的内部块
        ]

        # 2. 匹配单独的、需要移除的标签
        #    这些标签通常不包裹内容,单独出现
        single_tags = [
            r'\[pause\]',
            r'\[\*\]',
            r'\[继续\]',
            r'\(思考中\.\.\.\)',
            r'\(pause\)',
            # 可以添加更多观察到的模式
        ]
        # 将单个标签模式合并为一个,匹配任意一个即可
        single_tags_pattern = r'|'.join(f'({tag})' for tag in single_tags)

        # 合并所有模式
        all_patterns = default_patterns + [single_tags_pattern]
        if custom_patterns:
            all_patterns.extend(custom_patterns)

        # 编译正则表达式对象,提高效率
        # re.DOTALL: 使 . 匹配任何字符,包括换行符
        # re.IGNORECASE: 忽略大小写(部分标签可能大小写不敏感)
        self.compiled_patterns = []
        for pattern in all_patterns:
            try:
                compiled = re.compile(pattern, flags=re.DOTALL | re.IGNORECASE)
                self.compiled_patterns.append(compiled)
            except re.error as e:
                print(f"警告:正则表达式模式编译失败 '{pattern}': {e}")

    def clean(self, text: str) -> str:
        """
        清洗输入文本,移除所有匹配的 Claude Tag。

        Args:
            text: 原始的 Claude 响应文本。

        Returns:
            清洗后的文本。
        """
        if not text or not isinstance(text, str):
            return text or ""  # 处理 None 或非字符串输入

        cleaned_text = text
        for pattern in self.compiled_patterns:
            # 将所有匹配到的模式替换为空字符串
            cleaned_text = pattern.sub('', cleaned_text)

        # 额外处理:移除因删除标签而产生的多余空白字符
        # 例如,将两个连续换行符替换为一个,去除行首行尾空格
        cleaned_text = re.sub(r'\n\s*\n', '\n\n', cleaned_text)  # 合并多余空行
        cleaned_text = cleaned_text.strip()

        return cleaned_text

# 提供一个便捷的全局函数
_default_cleaner = ClaudeResponseCleaner()

def clean_claude_response(text: str) -> str:
    """便捷函数,使用默认配置清洗 Claude 响应。"""
    return _default_cleaner.clean(text)

代码解释

  1. 类封装 :我们将功能封装在 ClaudeResponseCleaner 类中,便于管理模式和进行扩展。
  2. 模式定义
    • r'\[thinking\].*?\[/thinking\]' :匹配从 [thinking] 开始,到第一个 [/thinking] 结束的 所有内容(包括换行) ,并将其整体移除。 .*? 是非贪婪匹配,防止匹配过多。
    • r'\[pause\]' 等:直接匹配这些单独的标签并移除。
  3. 标志使用
    • re.DOTALL :至关重要。没有它, . 将无法匹配换行符。如果 [thinking] [/thinking] 跨越多行,清洗就会失败。
    • re.IGNORECASE :处理标签大小写可能不一致的情况(例如 [Thinking] )。
  4. 后处理 :在移除标签后,文本中可能会留下多余的空行或空格。我们使用 re.sub(r'\n\s*\n', '\n\n', cleaned_text) 来将多个连续空行合并为一个,并使用 strip() 清理首尾空格,使输出更整洁。

4.3 编写测试与示例 ( main.py )

现在,让我们编写一个主程序来测试我们的过滤器,并模拟真实的 API 调用场景。

# main.py
import asyncio
from anthropic import AsyncAnthropic
from claude_filter import clean_claude_response, ClaudeResponseCleaner

# 你的 Anthropic API 密钥 (请从环境变量或安全存储中读取,切勿硬编码)
# 示例: export ANTHROPIC_API_KEY='your-api-key-here'
ANTHROPIC_API_KEY = "your_anthropic_api_key_here"  # TODO: 替换为你的密钥或从环境变量获取

async def call_claude_api_streaming():
    """模拟调用 Claude 流式 API 并实时清洗响应。"""
    client = AsyncAnthropic(api_key=ANTHROPIC_API_KEY)

    # 一个可能诱发内部标签的提示词(有时更复杂的任务容易触发)
    prompt = """请详细分析一下莎士比亚的《哈姆雷特》中“生存还是毁灭”这段独白所反映的人物内心矛盾。请一步步思考。"""

    print("用户提问:", prompt)
    print("\n--- 原始流式输出 (模拟) ---")

    # 为了演示,我们同时模拟原始输出和清洗后的输出
    full_raw_response = ""
    full_cleaned_response = ""

    try:
        async with client.messages.stream(
            model="claude-3-haiku-20240307", # 使用一个 Claude 3 模型
            max_tokens=500,
            messages=[{"role": "user", "content": prompt}]
        ) as stream:
            async for event in stream:
                if event.type == "content_block_delta":
                    delta_text = event.delta.text
                    if delta_text:
                        full_raw_response += delta_text
                        # 实时清洗当前片段(注意:对于流式,更佳实践是累积到一定长度或句子边界再清洗,这里为演示简化)
                        # 但为了演示Tag过滤,我们假设收到一个完整块后再清洗。
                        print(f"原始片段: {repr(delta_text)}") # repr 可以显示换行符等

        # 在实际流式处理中,你可能希望每收到一个完整句子或段落就清洗一次。
        # 这里我们收到所有内容后一次性清洗以演示效果。
        print("\n--- 完整原始响应 ---")
        print(full_raw_response)
        print("\n--- 清洗后响应 ---")
        cleaned = clean_claude_response(full_raw_response)
        print(cleaned)
        full_cleaned_response = cleaned

    except Exception as e:
        print(f"调用 API 时出错: {e}")
        return None, None

    return full_raw_response, full_cleaned_response

def test_with_predefined_responses():
    """使用预定义的、包含 Tag 的响应文本来测试过滤器。"""
    print("\n=== 测试预定义响应 ===")

    test_cases = [
        # (测试名称, 原始文本)
        ("简单 thinking 标签", "你好![thinking]用户打了招呼,我需要友好回应。[/thinking] 你好啊,很高兴为你服务!"),
        ("跨行 thinking 标签", "这个问题很有趣。\n[thinking]\n我需要从几个角度分析:首先...其次...\n[/thinking]\n我认为可以从以下两点来看:"),
        ("单独 pause 标签", "请稍等,[pause]我来查一下相关信息。"),
        ("混合标签", "好的。[thinking]用户要求总结,我需要先阅读核心段落。[/thinking] 这篇文章的主旨是[pause]关于人工智能的未来。"),
        ("无标签文本", "这是一个正常的回复,没有任何内部标签。"),
        ("空字符串", ""),
        ("只有标签", "[thinking][/thinking][pause]"),
    ]

    cleaner = ClaudeResponseCleaner()
    for name, raw_text in test_cases:
        print(f"\n测试: {name}")
        print(f"输入: {repr(raw_text)}")
        cleaned = cleaner.clean(raw_text)
        print(f"输出: {repr(cleaned)}")
        print(f"是否改变: {raw_text != cleaned}")

if __name__ == "__main__":
    print("Claude Tag 过滤器演示")
    print("=" * 50)

    # 测试预定义案例
    test_with_predefined_responses()

    # 注意:以下真实 API 调用需要有效的 API 密钥,如果未设置,请注释掉。
    # raw, cleaned = asyncio.run(call_claude_api_streaming())
    # if raw:
    #     print("\n=== 真实 API 调用结果 ===")
    #     print(f"原始长度: {len(raw)} 字符")
    #     print(f"清洗后长度: {len(cleaned)} 字符")
    #     print(f"移除了约 {len(raw)-len(cleaned)} 个字符的 Tag 内容。")

4.4 运行与验证

  1. 运行测试 :确保你已在项目目录下激活了虚拟环境。

    python main.py
    

    你会看到控制台输出预定义测试案例的结果,清晰地展示了过滤器如何移除各种 Tag。

  2. 进行真实 API 测试(可选)

    • main.py 中,将 ANTHROPIC_API_KEY 替换为你自己的密钥( 强烈建议通过环境变量 os.getenv('ANTHROPIC_API_KEY') 设置,而非硬编码 )。
    • 取消注释 main 函数中最后几行关于真实 API 调用的代码。
    • 再次运行 python main.py 。程序会调用 Claude API 并展示流式接收的原始片段、完整原始响应以及清洗后的最终响应。

4.5 结果说明

运行测试后,你将看到类似以下输出:

测试: 简单 thinking 标签
输入: '你好![thinking]用户打了招呼,我需要友好回应。[/thinking] 你好啊,很高兴为你服务!'
输出: '你好! 你好啊,很高兴为你服务!'
是否改变: True

测试: 跨行 thinking 标签
输入: '这个问题很有趣。\n[thinking]\n我需要从几个角度分析:首先...其次...\n[/thinking]\n我认为可以从以下两点来看:'
输出: '这个问题很有趣。\n我认为可以从以下两点来看:'
是否改变: True

测试: 单独 pause 标签
输入: '请稍等,[pause]我来查一下相关信息。'
输出: '请稍等,我来查一下相关信息。'
是否改变: True

测试: 无标签文本
输入: '这是一个正常的回复,没有任何内部标签。'
输出: '这是一个正常的回复,没有任何内部标签。'
是否改变: False

这表明我们的过滤器成功移除了各种格式的 Tag,同时保留了正常文本,并且对无标签文本不做改动。

5. 常见问题与排查思路

在实际集成中,你可能会遇到一些问题。下面是一个排查清单:

问题现象 可能原因 解决思路
Tag 没有被过滤掉 1. 正则表达式模式不匹配实际的 Tag 格式。
2. Tag 跨越多行,但未使用 re.DOTALL 标志。
3. 标签大小写不一致,未使用 re.IGNORECASE
1. 打印出原始响应文本 ( repr(response) ),仔细检查 Tag 的精确格式(包括空格、换行)。
2. 确保正则表达式编译时包含了 flags=re.DOTALL
3. 确保使用了 re.IGNORECASE 或调整模式大小写。
过滤掉了用户正常输入的内容 正则表达式过于宽泛,匹配了用户消息中合法的方括号内容(如 [重要] )。 1. 使模式更精确。例如,只匹配已知的特定标签词 `thinking
流式处理时清洗导致文本碎片化 在流式处理中,每个数据块 ( chunk ) 就进行清洗,可能把一个 Tag 拆散到两个块里,导致无法被完整匹配。 1. 推荐策略 :在流式处理中,累积文本到一个缓冲区,直到遇到一个完整的句子分隔符(如句号、问号、换行)或达到一定长度,再对缓冲区内容进行清洗和发送。
2. 或者,在流式接收完全部内容后,进行一次整体清洗(适用于对实时性要求不极致的场景)。
性能问题 响应文本极长(数万字符),且正则表达式非常复杂,可能导致处理延迟。 1. 预编译 ( re.compile ) 正则表达式对象并复用。
2. 对于超长文本,评估清洗耗时,如果成为瓶颈,考虑优化正则表达式或分块处理。
3. 通常,单次响应的清洗在毫秒级,性能不是主要问题。
新的未知 Tag 出现 Anthropic 更新模型后,可能引入了新的内部标签格式。 1. 建立监控机制,定期抽样检查模型返回的原始响应。
2. 将 Tag 模式列表设计为可配置的(如我们的 ClaudeResponseCleaner 支持 custom_patterns ),便于动态更新。
3. 在过滤后,可以添加一个简单的“安全网”检查,例如查找响应中是否还残留孤立的 [ ] 并记录日志。

6. 最佳实践与工程建议

将 Tag 过滤集成到生产环境时,需要考虑更多工程细节。

6.1 架构位置

过滤器应该放在哪里?

  • 推荐:在 API 网关或后端服务层 。在将 Claude API 的响应返回给前端(Web/App)之前进行过滤。这样保证了所有出口数据的一致性。
  • 前端过滤(备选) :如果后端只是透传流式数据,也可以在前端收到数据后过滤。但这样增加了前端的复杂性和不一致的风险。

6.2 流式处理优化

对于真正的流式应用,我们的简单示例(累积全部再清洗)会引入延迟。更优的方案是:

# 示例:改进的流式清洗器
class StreamingCleaner:
    def __init__(self):
        self.buffer = ""
        self.cleaner = ClaudeResponseCleaner()
        # 定义句子分隔符,用于决定何时清洗并清空缓冲区
        self.sentence_delimiters = {'.', '?', '!', '\n', '。', '?', '!'}

    def process_chunk(self, chunk: str) -> str:
        """处理一个流式数据块,返回可安全发送的文本(可能为空)。"""
        self.buffer += chunk
        output = ""

        # 检查缓冲区末尾是否有句子分隔符
        # 这里用一个简单检查:如果缓冲区最后一个字符是分隔符,则处理
        if self.buffer and self.buffer[-1] in self.sentence_delimiters:
            cleaned = self.cleaner.clean(self.buffer)
            output = cleaned  # 或者计算与之前输出的差值
            self.buffer = ""  # 清空缓冲区
        # 或者,如果缓冲区超过一定长度(如200字符),也强制处理一次,防止缓冲区过大
        elif len(self.buffer) > 200:
            cleaned = self.cleaner.clean(self.buffer)
            output = cleaned
            self.buffer = ""

        return output

    def flush(self) -> str:
        """处理缓冲区中剩余的所有文本。"""
        if self.buffer:
            cleaned = self.cleaner.clean(self.buffer)
            self.buffer = ""
            return cleaned
        return ""

6.3 配置化与监控

  • 模式可配置 :将需要过滤的正则表达式模式存储在配置文件(如 config.yaml )或数据库中,这样无需重启服务即可更新规则。
  • 日志记录 :在过滤器中添加 debug 级别的日志,记录被移除的 Tag 内容和原始文本片段(注意脱敏)。这有助于发现新出现的 Tag 模式。
  • 采样与告警 :定期(例如 1% 的请求)保存原始响应和清洗后响应的对比到日志系统。如果发现大量响应含有未知模式,触发告警。

6.4 安全与边界处理

  • 输入验证 :确保 clean 函数能处理 None 、非字符串输入,避免程序崩溃。
  • 避免递归灾难 :确保你的正则表达式不会导致灾难性回溯(Catastrophic Backtracking)。我们的模式使用了非贪婪 .*? ,并且匹配的是具体标签名,风险较低。
  • 性能测试 :如果你的 QPS 很高,应对过滤函数进行压力测试。

6.5 测试策略

为你的过滤器编写全面的单元测试和集成测试。

# test_claude_filter.py (示例)
import pytest
from claude_filter import clean_claude_response

def test_clean_thinking_tag():
    assert clean_claude_response("a[thinking]b[/thinking]c") == "ac"
    assert clean_claude_response("[thinking]test[/thinking]") == ""

def test_clean_pause_tag():
    assert clean_claude_response("hello[pause]world") == "helloworld"

def test_clean_mixed_tags():
    input_text = "Start.[thinking]Inner[/thinking]Middle[pause]End."
    expected = "Start.MiddleEnd."
    assert clean_claude_response(input_text) == expected

def test_clean_with_newlines():
    input_text = "Line1\n[thinking]\nInner\n[/thinking]\nLine2"
    assert clean_claude_response(input_text) == "Line1\nLine2"

def test_no_change():
    assert clean_claude_response("Normal text [with brackets]") == "Normal text [with brackets]"
    assert clean_claude_response("") == ""
    assert clean_claude_response(None) == ""

# 使用 pytest 运行测试

7. 总结

处理 Claude API 流式输出中的内部标签,是一个提升产品专业性和用户体验的关键细节。通过本文,我们系统地完成了从问题认知、原理分析、方案设计到代码实现的完整闭环。

核心要点回顾

  1. 问题定位 :Claude Tag 是模型内部推理过程在流式输出中的“泄露”,表现为 [thinking] [pause] 等文本片段。
  2. 解决方案核心 :使用 正则表达式 在服务端对模型响应进行后处理过滤。
  3. 关键技术点
    • 使用 re.DOTALL 标志匹配跨行内容。
    • 使用非贪婪匹配 .*? 精确匹配标签对内部。
    • 预编译正则表达式对象以提高性能。
    • 设计可配置、可扩展的过滤类 ( ClaudeResponseCleaner )。
  4. 工程化实践
    • 将过滤器置于后端服务层。
    • 流式场景下采用 缓冲区累积 到句子边界再清洗的策略,平衡实时性与效果。
    • 实现配置化、监控和告警,以应对模型更新带来的新 Tag 模式。
    • 编写完备的单元测试和集成测试。

给你的后续建议

  • 立即行动 :将提供的 claude_filter.py 集成到你的项目中,它开箱即用。
  • 持续观察 :Tag 的出现频率和形式可能与模型版本、提示词(Prompt)有关。保持对原始响应的抽样检查。
  • 灵活调整 :如果业务需要保留 [thinking] 中的某些信息(例如用于调试或高级功能),可以修改过滤器逻辑,只剥离标签字符而非整个块。

通过这套方案,你可以确保交付给用户的对话内容是干净、流畅、专业的,彻底告别 Claude Tag 带来的打扰。

更多推荐