通过配置注入+生命周期钩子实现记忆组件的无侵入式集成:
chain = my_chain.configure({"configurable": {"memory": chat_history}})
将 Memory 实例通过 configurable 字段注入运行时上下文
2. 执行时获取
在 invoke/stream
执行方法中通过第二个参数访问上下文:
def invoke(input, config):
memory = config.get("configurable", {}).get("memory")
# 获取历史对话记录
print(memory.get_history())
on_end
钩子自动持久化对话记录:chain.with_listeners(on_end=lambda output:
memory.save(input=output["input"], response=output["output"]))
@classmethod
def _load_memory_variables(cls, input: Dict[str, Any], config: RunnableConfig) -> Dict[str, Any]:
"""加载记忆变量"""
configurable = config.get("configurable", {})
configurable_memory = configurable.get("memory", None)
if configurable_memory is not None and isinstance(configurable_memory, BaseMemory):
return configurable_memory.load_memory_variables(input)
return {"history": []}
@classmethod
def _save_context(cls, run: Run, config: RunnableConfig) -> None:
configurable = config.get("configurable", {})
configurable_memory = configurable.get("memory", None)
if configurable_memory is not None and isinstance(configurable_memory, BaseMemory):
configurable_memory.save_context(run.inputs, run.outputs)
def debug(self, app_id: UUID):
"""聊天接口"""
...
chain = (
(RunnablePassthrough.assign(
history=RunnableLambda(self._load_memory_variables) | itemgetter("history")
) | prompt | llm | StrOutputParser()).
with_listeners(on_end=self._save_context)
)
# 5.调用链生成内容
chain_input = {"query": req.query.data}
content = chain.invoke(chain_input, config={"configurable": {"memory": memory}})
...