提示词注入
提示词注入 (Prompt Injection) 是 Nekro Agent 插件影响 AI 行为、提供上下文信息或定制其角色的关键机制之一。通过向 AI 的主提示词(System Prompt)中动态添加内容,插件可以引导 AI 的思考方向和响应风格。
什么是提示词注入?
在 AI 与用户交互之前,系统通常会构建一个包含指令、上下文信息、角色定义等内容的主提示词。提示词注入允许插件在这个构建过程中,将会话相关的、插件特定的信息动态地"注入"到主提示词中。
这样做的目的是:
- 提供上下文:告知 AI 当前会话的特定状态、用户的历史偏好、插件已收集到的相关信息等。
- 赋予能力/角色:指示 AI 使用插件提供的特定工具,或者扮演某个特定角色(例如,"你现在是一个乐于助人的天气预报员")。
- 设定规则/约束:为 AI 的行为设定一些指导原则或限制条件。
注册提示词注入方法
插件通过 @plugin.mount_prompt_inject_method()
装饰器注册一个异步函数,该函数负责生成需要注入的提示词内容。
python
from nekro_agent.api.schemas import AgentCtx
from nekro_agent.api import core
@plugin.mount_prompt_inject_method(
name="status_awareness_prompt", # 注入方法的名称,用于调试和识别
description="向 AI 注入当前会话的状态信息和可用工具提示。"
)
async def inject_status_prompt(_ctx: AgentCtx) -> str:
"""生成并返回需要注入到主提示词中的字符串。
Returns:
str: 需要注入的提示词文本。
"""
# 示例:从插件存储中获取当前会话的状态信息
current_status = await plugin.store.get(chat_key=_ctx.from_chat_key, store_key="current_channel_status")
prompt_parts = []
if current_status:
prompt_parts.append(f"当前状态提示:会话状态目前是 '{current_status}'。")
else:
prompt_parts.append("当前状态提示:会话状态未知或为默认状态。")
# 示例:提醒 AI 可以使用的插件工具 (更复杂的工具描述应通过沙盒方法文档提供)
prompt_parts.append("你可以使用 'get_weather(city)' 工具查询天气。")
prompt_parts.append("你可以使用 'set_reminder(time_desc,message)' 工具设置提醒。")
# 最终注入的提示词
injected_prompt = "\n".join(prompt_parts)
core.logger.debug(f"为会话 {_ctx.from_chat_key} 注入提示: \n{injected_prompt}")
return injected_prompt
关键点:
- 注入方法必须是异步函数 (
async def
)。 - 它接收一个
AgentCtx
对象作为参数,可以从中获取会话信息。 - 它必须返回一个字符串,这个字符串将被拼接到 AI 的主提示词中。
name
和description
参数用于标识这个注入方法。
何时执行?
提示词注入方法通常在以下情况被调用:
- 每次用户与 AI 交互前
设计有效的注入提示词
一个好的注入提示词能够显著提升插件的效用和 AI 的表现。以下是一些初步的设计原则:
- 简洁明了:注入的内容应尽可能简短、清晰、易于 AI 理解。避免冗长和不必要的复杂性。
- 高度相关:只注入与当前会话、当前用户或插件核心功能紧密相关的信息。无关信息会增加 AI 的处理负担,甚至产生误导。
- 结构化:如果注入多条信息,尽量使用一致的格式,例如使用特定的前缀、换行符或项目符号,帮助 AI 区分不同的信息片段。
- 动态生成:充分利用
AgentCtx
和插件存储中的信息,动态生成与当前情境最匹配的提示词内容。 - 明确指示 (如果需要):如果希望 AI 使用特定工具或遵循特定行为,可以在提示词中给出明确的指示。但更复杂的工具使用说明应放在沙盒方法的文档字符串中。
- 避免冲突:注意你的注入提示词是否可能与其他插件或系统级提示词产生冲突或歧义。
- 迭代与测试:提示词工程往往是一个需要不断尝试和优化的过程。通过实际测试来检验注入提示词的效果,并根据 AI 的反馈进行调整。
示例:简单的角色扮演提示
python
@plugin.mount_prompt_inject_method(name="role_play_prompt")
async def inject_role_prompt(_ctx: AgentCtx) -> str:
# 假设插件配置中有一个角色定义
role_description = plugin.config.ROLE_PLAY_CHARACTER
if role_description:
return f"请你扮演以下角色:{role_description}。在与用户交流时,请保持这个角色的特点和语气。"
return "" # 如果没有配置角色,则不注入任何内容
通过精心设计的提示词注入,你可以让插件更智能地与 AI 协作,为用户提供更流畅、更个性化的体验。