"""会话历史:数据库保存完整对话,每次请求按 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 :]