dspy icon indicating copy to clipboard operation
dspy copied to clipboard

[Bug] History is incorrectly included in the System message.

Open marwood-p opened this issue 7 months ago • 1 comments

What happened?

The example from the DSPy History page produces an incorrect System message. It indicates that the input fields include history but, in fact, the user message doesn't include history.

Steps to reproduce

import dspy

dspy.settings.configure(lm=dspy.LM("openai/gpt-4o-mini"))

class MySignature(dspy.Signature):
    question: str = dspy.InputField()
    history: dspy.History = dspy.InputField()
    answer: str = dspy.OutputField()

history = dspy.History(
    messages=[
        {"question": "What is the capital of France?", "answer": "Paris"},
        {"question": "What is the capital of Germany?", "answer": "Berlin"},
    ]
)

predict = dspy.Predict(MySignature)
outputs = predict(question="What is the capital of France?", history=history)

print('System message:')
print(dspy.settings.lm.history[-1]['messages'][0]['content'])
print('User message:')
print(dspy.settings.lm.history[-1]['messages'][1]['content'])
System message:
Your input fields are:
1. `question` (str)
2. `history` (History)
Your output fields are:
1. `answer` (str)
All interactions will be structured in the following way, with the appropriate values filled in.

[[ ## question ## ]]
{question}

[[ ## history ## ]]
{history}

[[ ## answer ## ]]
{answer}

[[ ## completed ## ]]
In adhering to this structure, your objective is: 
        Given the fields `question`, `history`, produce the fields `answer`.
User message:
[[ ## question ## ]]
What is the capital of France?

I believe the System message should not include history as an input field.

DSPy version

2.6.23

marwood-p avatar May 22 '25 21:05 marwood-p

@marwood-p Thanks for reporting the issue! This is actually by intention in order to handles cases where few-shot examples have the history field. For example:

System message:

Your input fields are:
1. `question` (str): 
2. `history` (History):
Your output fields are:
1. `answer` (str):
All interactions will be structured in the following way, with the appropriate values filled in.

[[ ## question ## ]]
{question}

[[ ## history ## ]]
{history}

[[ ## answer ## ]]
{answer}

[[ ## completed ## ]]
In adhering to this structure, your objective is: 
        Given the fields `question`, `history`, produce the fields `answer`.


User message:

[[ ## question ## ]]
What is the capital of Belgium?

[[ ## history ## ]]
{"messages": [{"question": "What is the caaital of France?", "answer": "Paris"}, {"question": "What is the capital of Germany?", "answer": "Berlin"}]}


Assistant message:

[[ ## answer ## ]]
Brussels


User message:

[[ ## question ## ]]
What is the capital of Japan?

Respond with the corresponding output fields, starting with the field `[[ ## answer ## ]]`, and then ending with the marker for `[[ ## completed ## ]]`.


Response:

[[ ## answer ## ]]
Tokyo

[[ ## completed ## ]]

The missing HIstory field doesn't really affect the LLM response from our experiments.

We are not formatting the history in fewshot examples into multiturn messages because it is sort of misleading.

chenmoneygithub avatar Jun 07 '25 22:06 chenmoneygithub