Skip to content

Session & Memo Playbook

适用版本:4.0.8+

场景

多轮对话系统通常同时面对三类需求:

  • 记住用户长期偏好
  • 控制上下文长度与成本
  • 支持会话可恢复(服务重启/跨进程)

需要使用功能(关键特性)

  • activate_session(session_id=...) 会话激活与隔离
  • session.max_length 默认窗口裁剪
  • register_analysis_handler/register_execution_handlers 自定义 memo 更新策略
  • get_json_session/load_json_session 持久化恢复

具体操作

  1. 按用户 id 激活会话
  2. 配置窗口上限(避免上下文膨胀)
  3. 注册“压缩并更新 memo”的策略
  4. 在每轮请求后观察 session.memo
  5. 需要时导出快照

完整代码

python
import json
from agently import Agently

Agently.set_settings(
    "OpenAICompatible",
    {
        "base_url": "http://localhost:11434/v1",
        "model": "qwen2.5:7b",
        "model_type": "chat",
    },
).set_settings("request_options", {"temperature": 0.2}).set_settings("debug", False)

agent = Agently.create_agent()
agent.system("你是产品顾问,回答简短,并持续维护用户画像 memo。")

agent.activate_session(session_id="demo_user_xiaohang")
session = agent.activated_session
assert session is not None

# 控制上下文窗口(默认 simple_cut)
agent.set_settings("session.max_length", 12000)


def analysis_handler(full_context, context_window, memo, session_settings):
    # 超过 6 条时触发压缩
    if len(context_window) > 6:
        return "compress_with_profile"
    return None


async def compress_with_profile(full_context, context_window, memo, session_settings):
    # 保留最近 4 条,压缩更早历史到 memo
    kept = list(context_window[-4:])
    old_messages = context_window[:-4]

    req = agent.create_temp_request()
    (
        req
        .input(
            {
                "old_messages": [m.model_dump() for m in old_messages],
                "old_memo": memo,
            }
        )
        .instruct("基于 old_messages 与 old_memo 更新用户画像,返回结构化 JSON。")
        .output(
            {
                "user_profile": {
                    "name": (str,),
                    "project": (str,),
                    "target_users": [(str,)],
                    "preferences": {
                        "reply_style": (str,),
                        "priority": [(str,)],
                    },
                }
            }
        )
    )

    new_memo = await req.async_start(ensure_keys=["user_profile"])
    return None, kept, new_memo


session.register_analysis_handler(analysis_handler)
session.register_execution_handlers("compress_with_profile", compress_with_profile)

reply_1 = agent.input("我叫小航,正在做一款 AI 写作工具,目标用户是学生。给我 2 条建议。").get_text()
print("TURN1_REPLY:", reply_1)
print("TURN1_MEMO:", json.dumps(session.memo, ensure_ascii=False, indent=2))

reply_2 = agent.input("预算不高,第一期应优先做什么?").get_text()
print("TURN2_REPLY:", reply_2)
print("TURN2_MEMO:", json.dumps(session.memo, ensure_ascii=False, indent=2))

snapshot = session.get_json_session()
print("SNAPSHOT_LEN:", len(snapshot))

验证点

  • 会话切换到其他 session_id 时,历史不串线
  • 窗口超过阈值后,context_window 收敛
  • memo 结构稳定可复用
  • 导出快照可恢复后继续对话