40 lines
1.4 KiB
Python
40 lines
1.4 KiB
Python
"""会话历史:数据库保存完整对话,每次请求按 token 预算只带最近的完整轮次
|
|
|
|
裁剪在服务层组装请求时做一次,意图判断、问答和 screen agent 看到的是同一段历史
|
|
"""
|
|
|
|
from langchain_core.messages import (
|
|
AIMessage,
|
|
BaseMessage,
|
|
HumanMessage,
|
|
trim_messages,
|
|
)
|
|
from langchain_core.messages.utils import count_tokens_approximately
|
|
|
|
from app.schemas.base import JsonObject
|
|
|
|
|
|
def history_messages(history: list[JsonObject]) -> list[BaseMessage]:
|
|
"""每轮转成一条用户消息和一条助手消息,按时间从早到晚排列"""
|
|
messages: list[BaseMessage] = []
|
|
for turn in history:
|
|
messages.append(HumanMessage(content=turn["user"]))
|
|
messages.append(AIMessage(content=turn["assistant"]))
|
|
return messages
|
|
|
|
|
|
def trim_history(history: list[JsonObject], max_tokens: int) -> list[JsonObject]:
|
|
"""从最近一轮往前保留,总量不超过 max_tokens;只保留完整的轮次,不从一段回复中间截断
|
|
|
|
单独一轮就超过预算时这一轮也不保留
|
|
"""
|
|
kept = trim_messages(
|
|
history_messages(history),
|
|
max_tokens=max_tokens,
|
|
token_counter=count_tokens_approximately,
|
|
strategy="last",
|
|
# 从用户消息开始,助手回复放不下时连同它的用户消息一起去掉
|
|
start_on="human",
|
|
)
|
|
return history[len(history) - len(kept) // 2 :]
|