20260813

今天琢磨了琢磨langchain的流式输出,理解了updates和messages两种输出模式,一开始用messages的时候只能流式输出文本但不能方便地输出工具调用链,用updates的时候能一段一段地输出工具调用链但不能流式输出文本,主要是一开始没搞明白混合模式输出,以为混合模式输出靠框架给模型输出内容分辨并打标签。后来花了点时间才明白updates和messages两种模式互相独立互不干扰,每种模式都能单独输出完整内容,只不过是各取所需所长,比如updates输出工具调用,message输出思考内容和正文内容。
测试代码如下

from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage
from langchain_core.tools import tool


@tool
def get_student_infos(name: str) -> str:
    """
    用来根据学生名字查找学生信息
    Args:
        name:学生名字
    """
    infos = [
        {"姓名": "李明", "班级": "九年级一班", "成绩": "A"},
        {"姓名": "王丽", "班级": "九年级二班", "成绩": "A"}
    ]
    for info in infos:
        if info["姓名"] == name:
            return str(info)
    return f"未找到{name},已有的姓名有{[info['姓名'] for info in infos]}"


model = init_chat_model("deepseek:deepseek-v4-flash")
agent = create_agent(model=model, tools=[get_student_infos])


res = agent.stream(
    {"messages": [HumanMessage(content="帮我查找一下李明的相关信息")]},
    stream_mode=["messages", "updates"]
)

for mode, data in res:
    if mode == "messages":
        # messages模式
        chunk, meta = data
        # 输出正文
        if chunk.content:
            print(chunk.content, end="", flush=True)
        # 思考内容
        reasoning_content = chunk.additional_kwargs.get("reasoning_content", "")
        if reasoning_content:
            print(f"{reasoning_content}", end="", flush=True)

    elif mode == "updates":
        # updates模式
        print("\n")
        for key, value in data.items():
            for msg in value["messages"]:
                # 工具名称
                if hasattr(msg, "tool_calls") and msg.tool_calls:
                    print(f"[{msg.type}] {msg.tool_calls[0]["name"]}")
                # 工具返回内容
                if msg.type == "tool":
                    print(f"[{msg.type}]{msg.content}")


posted @ 2026-08-13 20:24  Leeszz  阅读(4)  评论(0)    收藏  举报