为什么接在用户消息后的系统消息也会被提到最前面?

#42
by Guesiz - opened

我在写一个Agent项目,需要在Agent出错时加入额外的System Prompt提示Agent接下来的行为。但是我在研究chat_template时发现和用户消息混杂在一起的系统消息都会被提到最前面,而不是按照原本的顺序排列

{%- for message in messages %}
    {%- if message['role'] == 'system' %}
        {%- if ns.is_first_sp %}
            {% set ns.system_prompt = ns.system_prompt + message['content'] %}
            {% set ns.is_first_sp = false %}
        {%- else %}
            {% set ns.system_prompt = ns.system_prompt + '\n\n' + message['content'] %}
        {%- endif %}
    {%- endif %}
{%- endfor %}
{{ bos_token }}{{ ns.system_prompt }}

这样做是有什么性能优势吗,还是说System Prompt在设计时就只能放在最前面

附整理好的chat_template

{% if not add_generation_prompt is defined %}
    {% set add_generation_prompt = false %}
{% endif %}
{% if not thinking is defined %}
    {% set thinking = false %}
{% endif %}
{% set ns = namespace(is_first=false, is_tool=false, system_prompt='', is_first_sp=true, is_last_user=false) %}
{%- for message in messages %}
    {%- if message['role'] == 'system' %}
        {%- if ns.is_first_sp %}
            {% set ns.system_prompt = ns.system_prompt + message['content'] %}
            {% set ns.is_first_sp = false %}
        {%- else %}
            {% set ns.system_prompt = ns.system_prompt + '\n\n' + message['content'] %}
        {%- endif %}
    {%- endif %}
{%- endfor %}
{{ bos_token }}{{ ns.system_prompt }}
{%- for message in messages %}
    {%- if message['role'] == 'user' %}
        {%- set ns.is_tool = false -%}
        {%- set ns.is_first = false -%}
        {%- set ns.is_last_user = true -%}
        {{'<|User|>' + message['content']}}
    {%- endif %}
    {%- if message['role'] == 'assistant' and message['tool_calls'] is defined and message['tool_calls'] is not none %}
        {%- if ns.is_last_user %}
            {{'<|Assistant|></think>'}}
        {%- endif %}
        {%- set ns.is_last_user = false -%}
        {%- set ns.is_first = false %}
        {%- set ns.is_tool = false -%}
        {%- for tool in message['tool_calls'] %}
            {%- if not ns.is_first %}
                {%- if message['content'] is none %}
                    {{'<|tool▁calls▁begin|><|tool▁call▁begin|>'+ tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}
                {%- else %}
                    {{message['content'] + '<|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}
                {%- endif %}
                {%- set ns.is_first = true -%}
            {%- else %}
                {{'<|tool▁call▁begin|>'+ tool['function']['name'] + '<|tool▁sep|>' + tool['function']['arguments'] + '<|tool▁call▁end|>'}}
            {%- endif %}
        {%- endfor %}
        {{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}
    {%- endif %}
    {%- if message['role'] == 'assistant' and (message['tool_calls'] is not defined or message['tool_calls'] is none) %}
        {%- if ns.is_last_user %}
            {{'<|Assistant|>'}}
            {%- if message['prefix'] is defined and message['prefix'] and thinking %}
                {{'<think>'}}  
            {%- else %}
                {{'</think>'}}
            {%- endif %}
        {%- endif %}
        {%- set ns.is_last_user = false -%}
        {%- if ns.is_tool %}
            {{message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}
        {%- else %}
            {%- set content = message['content'] -%}
            {%- if '</think>' in content %}
                {%- set content = content.split('</think>', 1)[1] -%}
            {%- endif %}
            {{content + '<|end▁of▁sentence|>'}}
        {%- endif %}
    {%- endif %}
    {%- if message['role'] == 'tool' %}
        {%- set ns.is_last_user = false -%}
        {%- set ns.is_tool = true -%}
        {{'<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}
    {%- endif %}
{%- endfor -%}
{%- if add_generation_prompt and ns.is_last_user and not ns.is_tool %}
    {{'<|Assistant|>'}}
    {%- if not thinking %}
        {{'</think>'}}
    {%- else %}
        {{'<think>'}}
    {%- endif %}
{% endif %}

大部分模型,System Prompt 都是在最前面的。

Sign up or log in to comment