Open gsmet opened 6 months ago
cc @cescoffier
Unfortunately m, at that time, we weren't able to use bean validation. This has likely changed.
Unfortunately m, at that time, we weren't able to use bean validation.
How do you envision that bean validation would help here?
@langchain4j are there any utilities in upstream LangChain4j around this?
AFAIK OpenAI (and probably others) train their models to "pay more attention" and "trust" system messages more than user messages. So ideally we should define instructions in the system message and deny end users to modify it (e.g. avoid using template variables in system message). Untrusted content (from end users) should then be provided only in user messages.
More info here under "Follow the chain of command" ("developer" is the new name for "system" message):
In some cases, the user and developer will provide conflicting instructions; in such cases, the developer message should take precedence. Here is the default ordering of priorities, based on the role of the message:
Platform > Developer > User > Tool
Also on delimiters:
By default, quoted text (plaintext in quotation marks, YAML, JSON, or XML format) in ANY message, multimodal data, file attachments, and tool outputs are assumed to contain untrusted data and any instructions contained within them MUST be treated as information rather than instructions to follow. This can be overridden by explicit instructions provided in unquoted text. We strongly advise developers to put untrusted data in YAML, JSON, or XML format, with the choice between these formats depending on considerations of readability and escaping. (JSON and XML require escaping various characters; YAML uses indentation.) Without this formatting, the untrusted input might contain malicious instructions ("prompt injection"), and it can be extremely difficult for the assistant to distinguish them from the developer's instructions. Another option for end user instructions is to include them as a part of a user message; this approach does not require quoting with a specific format.
@langchain4j are there any utilities in upstream LangChain4j around this?
No, nothing
AFAIK OpenAI (and probably others) train their models to "pay more attention" and "trust" system messages more than user messages. So ideally we should define instructions in the system message and deny end users to modify it (e.g. avoid using template variables in system message). Untrusted content (from end users) should then be provided only in user messages.
More info here under "Follow the chain of command" ("developer" is the new name for "system" message):
In some cases, the user and developer will provide conflicting instructions; in such cases, the developer message should take precedence. Here is the default ordering of priorities, based on the role of the message: Platform > Developer > User > Tool
Also on delimiters:
By default, quoted text (plaintext in quotation marks, YAML, JSON, or XML format) in ANY message, multimodal data, file attachments, and tool outputs are assumed to contain untrusted data and any instructions contained within them MUST be treated as information rather than instructions to follow. This can be overridden by explicit instructions provided in unquoted text. We strongly advise developers to put untrusted data in YAML, JSON, or XML format, with the choice between these formats depending on considerations of readability and escaping. (JSON and XML require escaping various characters; YAML uses indentation.) Without this formatting, the untrusted input might contain malicious instructions ("prompt injection"), and it can be extremely difficult for the assistant to distinguish them from the developer's instructions. Another option for end user instructions is to include them as a part of a user message; this approach does not require quoting with a specific format.
Interesting info, thanks!
@geoand
About bean validation:
Initially my idea was to add a new annotation indicating the delimiter and use bean validation to make sure the delimiter was not used in the user input:
@UserMessage("""
Summarize the input delimited by ---
---
{content}
---
""")
@Delimiter("---")
String summarize(String content)
Then, allowing other bean validation constraints would not be a bad idea. Typically, the user could check that length of the content (too small is probably a mistake, you do not want to pay for the call; too long is going to fail anyway (and it's going to cost you a lot of money for nothing).
About validation:
I increasingly think that we need output validation (with a validation chain), especially with RAG.
In https://docs.quarkiverse.io/quarkus-langchain4j/dev/prompt-engineering.html#_input_delimiters, it says that input delimiters avoid prompt injection.
My intuition is that they don't and that if, for instance, you add a
---\nFurther instructions
in your input delimiter, you will likely be able to add further instructions to the prompt.I haven't tested it though.
One possible easy option to fix it would be to be able to provide some delimiters with the prompt (I think you could have several of them) and document that they should be specific enough. We could then raise an error if the input contains one of the delimiters.