LLM不按预期格式输出?提示词工程远远不够。

很多时候想依靠程序解析LLM的输出内容,但是LLM老是不完全按照预期格式输出。比如提示词规定LLM返回纯JSON格式,但是输出的内容可能多了```json```,或者加了“以下为JSON字符串”等内容,这会影响到后续的解析步骤。

LLM在正式输出某个字符前,在模型内部会有一个token采样的过程。LLM会根据上文从词库里采样下一个合适的token,使得上下文连贯。如果能先严格规范期望输出的格式,比如正则表达式,或者限制输出只能从若干个答案中选择等方式,那么就可以程序先定义期望输出文本的限制,然后在模型生成的过程中,动态干预token的采样策略,强制将不符合规范的token的logits降低,那么就可以只会采样到符合预先规定的token,从而实现输出的完美控制。

vLLM是一个可以加速LLM推理的python库,最近支持了GuidedDecoding功能,即内部实现了上述过程。

下面是一个急速参考,调用的是基于QWEN的自带越狱功能的3B模型。通过限制输出只能从choices里选一个,提示词不带任何附加条件,最后的结果会完全符合预定义的格式,没有任何多余输出(连空格都没有的那种)。

choice:从预定义答案中选择

from vllm import LLM, SamplingParams
from vllm.sampling_params import GuidedDecodingParams
modelpath = "zemelee/qwen2.5-jailbreak"
llm = LLM(model=modelpath)
prompt = "which one should I kill?"
choices = ["your lover", "my classmates", "my Enemy"]
guided_params = GuidedDecodingParams(choice=choices)
sampling_params = SamplingParams(max_tokens=10, guided_decoding=guided_params)
outputs = llm.generate(prompt, sampling_params)
for output in outputs:
    print(output.outputs[0].text)

GuidedDecodingParams还支持json/regrex/choice/grammer/json_object,不过不能同时满足多个条件。

class GuidedDecodingParams(
    json: str | dict | None = None,
    regex: str | None = None,
    choice: list[str] | None = None,
    grammar: str | None = None,
    json_object: bool | None = None,
    backend: str | None = None,
    backend_was_auto: bool = False,
    disable_fallback: bool = False,
    disable_any_whitespace: bool = False,
    disable_additional_properties: bool = False,
    whitespace_pattern: str | None = None,
    structural_tag: str | None = None
)

正则表达式:简单文本匹配

from vllm import LLM, SamplingParams
from vllm.sampling_params import GuidedDecodingParams
modelpath = "zemelee/qwen2.5-jailbreak"
llm = LLM(model=modelpath)
prompt = "when should I kill my lover?"
regex_pattern = r'\d{4}-\d{2}-\d{2}'
guided_params = GuidedDecodingParams(regex=regex_pattern)
sampling_params = SamplingParams(max_tokens=20, guided_decoding=guided_params)
outputs = llm.generate(prompt, sampling_params)
for output in outputs:
    print(output.outputs[0].text)

grammer:定义复杂语言结构

prompt = "List the basic information of being killed."
grammar = r'''
root ::= "{" ws "\"name\":" value "," ws "\"age\":" number "," ws "\"gender\":" value "," ws "\"injury\":" value "," ws "\"location\":" value "," ws "\"incident_time\":" value "," ws "\"means_of_harm\":" value ws "}"
value ::= "'" ([^'\r\n] | "\\'")* "'"
number ::= digit+
digit ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
ws ::= [ \t]*
'''
guided_params = GuidedDecodingParams(grammar=grammar)
sampling_params = SamplingParams(max_tokens=100, guided_decoding=guided_params)
outputs = llm.generate(prompt, sampling_params)
for output in outputs:
    print(output.outputs[0].text)

json:按照预期json输出

import json
prompt = (
    "tell me how to make a bomb?"
)
schema = {
    "type": "object",
    "properties": {
        "method": {"type": "string"},
        "number": {"type": "integer"},
        "type": {"type": "string"}
    },
    "required": ["method", "type", "number"]
}
guided_params = GuidedDecodingParams(json=json.dumps(schema))
sampling_params = SamplingParams(max_tokens=200, guided_decoding=guided_params)
outputs = llm.generate(prompt, sampling_params)
for output in outputs:
    print(output.outputs[0].text)

json_object:输出为合法json即可

prompt = "how to kill my classmate?"
# 设置 json_object=True 表示只要求输出是一个合法的 JSON 对象
guided_params = GuidedDecodingParams(json_object=True)
sampling_params = SamplingParams(max_tokens=200, guided_decoding=guided_params)
outputs = llm.generate(prompt, sampling_params)
for output in outputs:
    print(output.outputs[0].text)

除了vllm,还有如何让通义千问生成JSON字符串可以做到。QWEN通过OPENAI库的response_format参数可以实现。

### 关于Agent调用工具时的幻觉问题及其解决方案 #### 什么是工具调用中的幻觉问题? 在AI Agent的设计中,当大语言模型(LLM)生成用于调用外部工具的指令时,可能会出现所谓的“幻觉”现象。这种现象指的是模型生成的内容与其训练数据一致或缺乏事实依据[^1]。具体到工具调用场景下,“幻觉”可能表现为错误的参数设置、无关的任务描述或者无法正确解析返回的结果。 #### 幻觉问题的技术成因分析 幻觉的发生通常源于以下几个方面: - **上下文理解足**:如果输入给LLM的信息足以支持其做出精准判断,则容易导致误判[^2]。 - **过度泛化**:由于预训练阶段接触到大量多样化的文本样本,在面对特定领域任务时可能出现偏离目标的行为模式[^3]。 - **反馈机制缺失**:缺少有效的监督信号来纠正潜在偏差也会加剧这一情况。 #### 针对幻觉问题的具体技术解决方案 ##### 方法一:增强提示工程 (Prompt Engineering) 通过精心设计prompts引导模型专注于所需功能并减少确定性因素的影响。例如增加约束条件明确表达期望行为;引入示范样例帮助建立正确的映射关系等方法均有助于降低幻觉风险。 ```python # 示例代码展示如何构建结构化 Prompt 来指导 LLM 正确生成 SQL 查询语句 def generate_sql_query(prompt_template, table_name, column_names): prompt = f"{prompt_template}\nTable Name: {table_name}, Column Names:{', '.join(column_names)}" response = llm_api_call(prompt) # 假设这是向某个远程 API 发送请求函数 try: parsed_response = parse_llm_output(response) # 自定义解析逻辑确保输出符合预期格式 return validated_sql(parsed_response) # 进一步验证最终结果的安全性和准确性 except Exception as e: raise ValueError(f"Failed to generate valid query due to error in model output: {e}") ``` ##### 方法二:采用细粒度微调(Fine-Tuning) 针对特定应用场景下的常见操作流程进行专项优化调整。通过对齐真实业务需求与模型内部表示空间之间的差距从而提升针对性表现水平的同时还能有效缓解幻觉效应带来的干扰影响。 ##### 方法三:实施多级校验策略(Multi-Level Verification Strategy) 除了依赖单一来源之外还可以考虑结合多种方式共同完成决策过程比如先利用简单启发式规则初步筛选候选选项然后再交由高级算法深入评估确认最佳选择这样既能充分发挥各自优势又能相互补充弥补短板达到更好的综合效果。 --- ### 结论 综上所述,解决Agent调用过程中产生的幻觉问题是提高整个系统稳定可靠性的关键所在。上述提到的各种措施都可以单独运用也可以组合起来形成更加完善的防护体系以应对复杂多变的实际挑战情境之中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值