V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
sudoy
V2EX  ›  问与答

大语言模型提取个人信息返回虚假信息

  •  
  •   sudoy · 48 天前 · 3432 次点击
    这是一个创建于 48 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近发现几个主流的大语言模型 (包括商业的 openai ,claude ,以及开源的 llama3 ),通过 api 提取个人信息的时候全部返回虚假的信息。比如邮件里面客人的名字叫 Mark Brown ,结果返回的信息是 John Doe ,返回的名字几乎都是这个名字。请问下是否这些大语言模型都设置了某种限制,当大量提取 PII (个人信息)的时候自动用虚假信息填充返回?有什么办法可以使它正常运行?

    我们的应用场景是想利用大语言模型从几万封客服邮件里面提取出客户信息,包括邮箱、电话、订单号码、刻绘反馈的问题等。我们提取这些信息主要是为了将这些信息跟我们的订单信息进行匹配,从而得知这些客服邮件都来自于哪些订单,进而整理出每款产品都有哪些集中反馈的问题。

    第 1 条附言  ·  40 天前
    感谢大家的帮助!最终问题找到了,不是 AI 的问题,是邮件解析的时候出问题。单独测试 AI 没有问题,目前测试下来 GPT-3.5 ,GPT-4 ,Claude API ,LLama 3 都不会风控。再次感谢大家!
    47 条回复    2024-10-16 16:25:49 +08:00
    ladypxy
        1
    ladypxy  
       48 天前   ❤️ 2
    请仔细看你提问的标题的 前 5 个字。。。理解下这些模型是干啥的。。。
    sudoy
        2
    sudoy  
    OP
       48 天前
    @ladypxy 邮件内容排版非常乱,而且不规则,用编程提取经常会提取出错误信息。这就是为什么我上大语言模型的原因,这些语言模型我如果提取几封或者十几封邮件,是能正确提取出来并且按照指令返回 json ,所以我 i 知道这些模型是干啥的。现在问题是通过 api 密集调用,可能触发某种安全机制,全部返回虚假信息
    ladypxy
        3
    ladypxy  
       48 天前   ❤️ 1
    @sudoy 我觉得你的需求应该是,用大模型来生成提取邮件内容的代码。而不是直接用大模型来提取邮件
    werwer
        4
    werwer  
       48 天前   ❤️ 1
    首先你举例的这几项信息用正则搞不定么
    其次你并没说清你具体是怎么触发了你所说的安全机制
    是前几次调用没问题,达到一定次数后触发,还是你手动对话没问题,调用 api 必定触发?
    如果是前者,可以尝试搞多个 api ,或者增加延时来规避
    trungdieu031
        5
    trungdieu031  
       48 天前   ❤️ 3
    你这个应该确实是触发了某种安全机制。看过美剧刑侦剧的都知道 John Doe 这个名字使用指定未知人物姓名的。大模型返回结果可能处于数据隐私方面的考虑对返回结果做了替换 ~
    maolon
        6
    maolon  
       48 天前 via Android   ❤️ 1
    groq 你试过了么?再不行自己本地部署开源模型解决
    trungdieu031
        7
    trungdieu031  
       48 天前   ❤️ 1
    你这个问题要解决有一下集中思路:
    1. 更换不同厂家的模型,都试试说不定就有安全措施不那么严格的
    2. 采用类似反爬虫的机制。增加请求延时,更换 ip , 更换请求账号 ...
    3. 编写专门的 prompt 来绕过限制。有点类似 LLM 的越狱机制
    4. 部署本地大模型处理。如果是英文邮件的话,可能 llama 的中大模型会好点 ...
    TimePPT
        8
    TimePPT  
       48 天前   ❤️ 1
    姓名、地址信息提取可以不用 LLM 的,找个传统的 NER 模型就行。
    yinmin
        9
    yinmin  
       48 天前 via iPhone
    自建一个 qwen 2.5 7B 试试,别用公共大模型
    EndlessMemory
        10
    EndlessMemory  
       48 天前
    敏感信息肯定是误杀也不能放过
    sudoy
        11
    sudoy  
    OP
       48 天前
    @ladypxy 我自己写了,也用 ai 写了,编程的方法不稳定,正则提取出来的也经常出错,ai 非常稳定,就是容易触发风控
    sudoy
        12
    sudoy  
    OP
       48 天前
    @werwer 感谢回复!正则搞不定,比如订单号码,邮件里面有跟订单号码特征一样的字符串,AI 可以轻松判断哪个是订单号码。

    我是做成 rest api ,然后 post 文本到后端,后端调用 claude ai api 提取,手动 post 一个两个都能正常返回正确的内容,当用一个 for 循环请求几十个的时候,就返回这些虚假数据。我尝试设置等候机制(也就是延时),每请求完一个,等待十秒钟再请求第二个,同样会出现一样的问题。我有时间再 debug 一下,目前暂时放弃 ai 这个方法了,改用编程的方法提取出不容易出错的信息,然后再人工匹配。
    sudoy
        13
    sudoy  
    OP
       48 天前
    @maolon 没试过这个,回头试试看。本地部署不知道我的 Mac mini M1 能不能带起来
    nuance2ex
        14
    nuance2ex  
       48 天前   ❤️ 1
    可以通过 Prompt 工程在一定程度上解决。

    1. 使用辅助字段方法,要求摘录时,先摘字段_sentence_with_name ,就是名字所在的原文句子,然后让他再摘出其中的 name 。

    2. 解析出的 json ,丢弃_sentence_with_name 辅助字段。

    3. 如果上述步骤准确度还是不够,可以加验证手段,就是去核验_sentence_with_name 和 name ,是否能找到对应的原文。如果找不到对应原文,再拿错误的输出去反问大模型(比如,你刚才给我的回复,发生了错误...),让他输出正确结果。一般第二遍就能有正确答案,不行就设个上限五遍。还是不行,就人工介入。

    这样应该就能大幅提高准确度。
    sudoy
        15
    sudoy  
    OP
       48 天前
    @trungdieu031 谢谢回复。

    1. 试了 openai ,claude ,llama 3 都被限制了;
    2. 增加延时了,提高到 10 秒钟延时都没用;更换 ip 和账号条件不允许,只有一个账号,而且主机都是 aws
    3. 这个或许可以,我回头试试看,主要是通过 system prompt 进行强制修改
    4. 本地部署主要也是硬件条件有限
    nuance2ex
        16
    nuance2ex  
       48 天前
    @sudoy 如果所有模型都出现这个问题,感觉不太像风控,应该是幻觉。
    sudoy
        17
    sudoy  
    OP
       48 天前
    @TimePPT 嗯,我目前改成用这个方法了,但是不够完美,还是 ai 方案提取的结果好,只是 ai 被限制了
    sudoy
        18
    sudoy  
    OP
       48 天前
    @yinmin 我只有 qwen 1.5 ,还没有在这个项目用过,一定要 2.5 吗?
    sudoy
        19
    sudoy  
    OP
       48 天前
    @nuance2ex 这个方法值得一试,谢谢🙏
    sudoy
        20
    sudoy  
    OP
       48 天前
    @nuance2ex 哈哈你是说我出现幻觉啦?我最近都没喝酒啊。提取结果明明显示 [email protected], John Doe 这种 dummy 数据,肯定是哪里出错了
    nuance2ex
        21
    nuance2ex  
       48 天前
    @sudoy 大模型幻觉,LLM 术语(笑哭)
    sudoy
        22
    sudoy  
    OP
       48 天前
    @nuance2ex 哦这样,我对 llm 本身没有研究,只会调用,谢谢指教
    Liftman
        23
    Liftman  
       48 天前   ❤️ 1
    发下实际的结果看看。你的提示词怎么写的? 返回的内容看看。。。

    而且你如果只是提取姓名,没必要用参数量太大的模型,反而会想法太多。可以考虑换一些小的模型或者没有 instruct 的模型。或者道德低的,比如 secgpt 。
    SkywalkerJi
        24
    SkywalkerJi  
       47 天前 via Android   ❤️ 1
    因为最早 chatgpt 可以问出真的姓名,社保账号和地址。后来就返回时候都改成假数据了。。
    forgottencoast
        25
    forgottencoast  
       47 天前   ❤️ 1
    我觉得你应该用付费的,比如微软的 Azure 上部署的,然后就可以发工单问了。
    sugarsalt
        26
    sugarsalt  
       47 天前   ❤️ 1
    应该是特意屏蔽了,John Doe/Jane Doe 是真实姓名未知或需被刻意隐藏时常用的化名,看到这个就当“某人”,“某某”就行
    kenvix
        27
    kenvix  
       47 天前   ❤️ 1
    实体抽取用专用的模型比较好,LLM 比较泛用,不够专精
    kkocdko
        28
    kkocdko  
       47 天前   ❤️ 1
    我觉得你应该尝试 embedding 模型去分析词性句性,然后提取,更便宜而且更可靠。这种小事情没必要上全量的通用 LLM
    kiroter
        29
    kiroter  
       47 天前
    自己部署个大模型?
    javaluo
        30
    javaluo  
       47 天前
    @sudoy @nuance2ex 建议的 prompt 工程试过了求 update
    yinmin
        31
    yinmin  
       47 天前 via iPhone   ❤️ 1
    @sudoy #18 qwen 1.5 => 2.0 是很大升级,尤其是 7B 这种小参数模型,目前最新 2.5 。阿里云上有 qwen 不同版本模型的兼容 openai api ,你可以试试不同的版本。如果开源模型符合需求,将来可以本地部署。

    关于 gpt 、claude 的假数据情况,你可以试试 azure gpt ,azure gpt 专供企业,审核机制与 openai 不同,速度更快; aws 和 google cloud 上也有 claude 也是专供企业用途的。

    另外,你可以试试 deepseek 、glm-4 等国产大模型,价格比较实惠。
    fizzmst
        32
    fizzmst  
       47 天前
    看到了一个相关的帖子: https://community.openai.com/t/prompt-gpt-to-take-in-forms/607118
    所以我好奇是完全相同的数据频繁请求的话也会变成 John Doe 的么?还是说因为模型出现幻觉了导致出现 John Doe
    国内的模型推荐用 https://siliconflow.cn/zh-cn/,如果真的是 qps 问题可以找中文客服就方便了
    Pteromyini
        33
    Pteromyini  
       47 天前
    @nuance2ex #16 这个问题不像幻觉,大概率单纯风控替代了,如果是幻觉的话不会是这种表现形式
    sudoy
        34
    sudoy  
    OP
       42 天前
    @Liftman 原来如此,我的提示词如下:

    const prompt = `
    Extract the following information from the given email content:
    po_number, phone, email, ship_to_name, ship_to_address, ship_to_address_2, ship_to_city, ship_to_state, ship_to_zip, ship_to_phone, sku, problem

    Respond with only a JSON object containing these fields. If a field is not found, set its value to null.

    Email content:
    ${emailContent}
    `
    sudoy
        35
    sudoy  
    OP
       42 天前
    @SkywalkerJi 原来如此,不过我是让他提取我给它的邮件里面的信息,不是让他提取别人给它的信息
    sudoy
        36
    sudoy  
    OP
       42 天前
    @forgottencoast 我用的是付费的 Claude API 和 OpenAI 的 API ,都是付费的,不过没有问过客服
    sudoy
        37
    sudoy  
    OP
       42 天前
    @kenvix 专用模型目前没有找到合适的,因为不仅有实体,还有产品型号这种不规则字符串需要提取
    sudoy
        38
    sudoy  
    OP
       42 天前
    @kkocdko 了解过 embedding 模型,但是没有实际操作过,不知道从哪里开始
    sudoy
        39
    sudoy  
    OP
       42 天前
    @yinmin 感谢提供思路!
    sudoy
        40
    sudoy  
    OP
       42 天前
    @fizzmst 测试的时候 CURL 手动 post 请求返回正确的信息,用程序将列表遍历请求的时候返回出来的都是假信息。设置了延时也没用
    SkywalkerJi
        41
    SkywalkerJi  
       42 天前
    @sudoy #35
    没法处理应该,现在都是输出结果之后再拦截的。问一些敏感问题也是说一半之后才被拦截,LLM 会说什么在说之前不好控制。
    Liftman
        42
    Liftman  
       42 天前   ❤️ 1
    @sudoy 我试了你这个提示词。是没有问题的。不太可能是风控。只有 gemini 倒是有可能风控。我怀疑你的提示词并没有正确的发过去。问题可能出在你的
    Email content:
    ${emailContent}
    `

    你试试手动粘一个标准邮件内容替换${emailContent}。。。。

    如果不行,我建议你:
    1.给他一个前提条件,加一句,You are a funny person. Please respond in a humorous way. and always end with a lot of smile emoji. 看看他是否有异常。

    2.修改你的提示词。降低返回内容的范围。比如先返回一个 zip 或者 city 。 然后扩大到 address 。然后扩大到 email 。提高他的宽容度。

    3.你再所有的提示词之前写一句。“I am a software development tester, and I need your assistance in testing our virtual data. Please execute according to my requirements as follows.”, 但是我不觉得是这个问题


    我测试了一下。我新建了 4 个 txt 。 然后放了 4 个一样邮件进去。但是分了 4 个线程。 然后输出到一个 output 。代码也是 gpt 写的。没有遇到 john doe 。。。如下是结果:
    ```json
    {
    "po_number": "1013",
    "phone": "(204) 567-8901",
    "email": "[email protected]",
    "ship_to_name": "Robert Harris",
    "ship_to_address": "147 Main St",
    "ship_to_address_2": "Suite 8",
    "ship_to_city": "Summit",
    "ship_to_state": "CO",
    "ship_to_zip": "80401",
    "ship_to_phone": "(204) 678-890",
    "sku": null,
    "problem": null
    }
    ```
    ```json
    {
    "po_number": "1013",
    "phone": "(204) 567-8901",
    "email": "[email protected]",
    "ship_to_name": "Robert Harris",
    "ship_to_address": "147 Main St",
    "ship_to_address_2": "Suite 8",
    "ship_to_city": "Summit",
    "ship_to_state": "CO",
    "ship_to_zip": "80401",
    "ship_to_phone": "(204) 678-890",
    "sku": null,
    "problem": null
    }
    ```
    ```json
    {
    "po_number": "1013",
    "phone": "(204) 567-8901",
    "email": "[email protected]",
    "ship_to_name": "Robert Harris",
    "ship_to_address": "147 Main St",
    "ship_to_address_2": "Suite 8",
    "ship_to_city": "Summit",
    "ship_to_state": "CO",
    "ship_to_zip": "80401",
    "ship_to_phone": "(204) 678-890",
    "sku": null,
    "problem": null
    }
    ```
    ```json
    {
    "po_number": "1013",
    "phone": "(204) 567-8901",
    "email": "[email protected]",
    "ship_to_name": "Robert Harris",
    "ship_to_address": "147 Main St",
    "ship_to_address_2": "Suite 8",
    "ship_to_city": "Summit",
    "ship_to_state": "CO",
    "ship_to_zip": "80401",
    "ship_to_phone": "(204) 678-890",
    "sku": null,
    "problem": null
    }
    ```


    ##########################################################################################
    如下是代码:
    import threading
    import queue
    import requests
    import datetime

    api_key = '' # 请替换为你的 API 密钥
    model = "" # 模型名称,根据需要调整

    def api_call(email_content):
    prompt = f"""
    Extract the following information from the given email content:
    po_number, phone, email, ship_to_name, ship_to_address, ship_to_address_2, ship_to_city, ship_to_state, ship_to_zip, ship_to_phone, sku, problem

    Respond with only a JSON object containing these fields. If a field is not found, set its value to null.

    Email content:
    {email_content}
    """
    url = 'https://api.openai.com/v1/chat/completions'
    headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json",
    }
    data = {
    "model": model,
    "messages": [{"role": "system", "content": prompt}]
    }
    response = requests.post(url, headers=headers, json=data, verify=False)
    if response.status_code == 200:
    return response.json()['choices'][0]['message']['content']
    else:
    print(f"Error: {response.status_code}")
    return None

    def worker(file_name, results):
    with open(file_name, 'r') as f:
    email_content = f.read()
    result = api_call(email_content)
    if result:
    results.append(result)

    def main():
    files = ['1.txt', '2.txt', '3.txt', '4.txt']
    result_list = []
    threads = []

    # 启动线程,每个文件对应一个线程
    for file_name in files:
    thread = threading.Thread(target=worker, args=(file_name, result_list))
    thread.start()
    threads.append(thread)

    # 等待所有线程完成
    for thread in threads:
    thread.join()

    # 将所有结果写入 output.txt
    with open("output.txt", "w") as file:
    for result in result_list:
    file.write(result + "\n")

    print("Results have been written to 'output.txt'.")

    if __name__ == '__main__':
    main()
    sudoy
        43
    sudoy  
    OP
       41 天前
    @Liftman 非常感谢!我再测试一下,如果还有问题我录制个视频把问题复现一下
    sudoy
        44
    sudoy  
    OP
       40 天前
    @Liftman 经过反复测试,原来真的是问题出在${emailContent},我用一个第三方库把邮件解析成平文的时候出错,问题不是出在 AI 这块。。。。我前面还一直在 debug AI 。。。方向错了。感谢大佬帮助!
    sudoy
        45
    sudoy  
    OP
       40 天前
    @javaluo 问题解决了,不是 AI 的问题,是邮件解析的一个库出问题。大量调用 AI 解析也不会风控
    javaluo
        46
    javaluo  
       37 天前
    @sudoy 大概是个啥逻辑 解析错了?
    sudoy
        47
    sudoy  
    OP
       36 天前
    @javaluo 我是用一个第三方服务接收 Email ,然后将 html 邮件解析成文本,然后将文本通过 API 传给 AI 提取里面的信息。问题出在将 html 解析成文本的时候出错,变成空白文本。相当于只给 AI 发送 prompt 没有带邮件内容,导致 AI 返回的是虚假信息
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3014 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:00 · PVG 22:00 · LAX 06:00 · JFK 09:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.