LangGraph + LLM + stream_mode


LLM 代码

from dataclasses import dataclass

from langchain.chat_models import init_chat_model
from langgraph.graph import StateGraph, START

from langchain_openai import ChatOpenAI
# 初始化 llm 
model_name = 'glm-4-flash' 
base_url = 'https://open.bigmodel.cn/api/paas/v4'
api_key = '6eeeb21...bPJyrc8e'  

llm = ChatOpenAI(
    openai_api_base=base_url,
    model = model_name,
    api_key = api_key,
    temperature=0.1, 
    # streaming=True,  
)


@dataclass
class MyState:
    topic: str
    joke: str = ""


def call_model(state: MyState):
    """Call the LLM to generate a joke about a topic"""
    llm_response = llm.invoke( # (1)!
        [
            {"role": "user", "content": f"给我讲一个关于 {state.topic} 的笑话"}
        ]
    )
    return {"joke": llm_response.content}

graph = (
    StateGraph(MyState)
    .add_node(call_model)
    .add_edge(START, "call_model")
    .compile()
)

message = {"topic": "冰淇淋"}

values


events = graph.stream(
    message,  
    stream_mode="values",
) 

-- event :  {'topic': '冰淇淋'}
-- event :  {'topic': '冰淇淋', 'joke': '有一天,冰淇淋去参加一个聚会,它走进房间后,看到大家都在聊天,于是它决定找个地方坐下。\n\n冰淇淋走到一个角落,看到一把椅子,它说:“嘿,椅子,我坐这里可以吗?”\n\n椅子回答:“当然可以,不过你得小心,我可是‘冷板凳’。”\n\n冰淇淋一愣,然后笑着说:“哦,原来如此,那我就不客气了,谢谢你的提醒!”'}

messages


for message_chunk, metadata in graph.stream( # (2)!
    {"topic": "ice cream"},
    stream_mode="messages", 
):
    print('\n')
    print('-- message_chunk : ', message_chunk) 
    print('-- metadata : ', metadata) 

    if message_chunk.content:
        print(message_chunk.content, end="|", flush=True)

-- metadata :  
{
	'langgraph_step': 1,
	'langgraph_node': 'call_model',
	'langgraph_triggers': ('branch:to:call_model', ),
	'langgraph_path': ('__pregel_pull', 'call_model'),
	'langgraph_checkpoint_ns': 'call_model:ee4d452e-bd6a-6176-fb64-086b7793dd96',
	'checkpoint_ns': 'call_model:ee4d452e-bd6a-6176-fb64-086b7793dd96',
	'ls_provider': 'openai', 
	'ls_model_name': 'glm-4-flash',
	'ls_model_type': 'chat',
	'ls_temperature': 0.1
}    

-- message_chunk :  content='为什么' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'

为什么|

-- message_chunk :  content='冰淇淋' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'

冰淇淋|

-- message_chunk :  content='总是' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'

总是|

-- message_chunk :  content='那么' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'

那么|

-- message_chunk :  content='开心' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'

开心|

-- message_chunk :  content='?\n\n因为它' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'

?

因为它|

-- message_chunk :  content='总是' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'

总是|

-- message_chunk :  content='笑' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'|

-- message_chunk :  content='得' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'|

-- message_chunk :  content='“' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'|

-- message_chunk :  content='冰' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'|

-- message_chunk :  content='”' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'|

-- message_chunk :  content='裂' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'|

-- message_chunk :  content='!' additional_kwargs={} response_metadata={} id='run--a3723e25-7094-4fad-8339-fdd41da406e4'|

-- message_chunk :  content='😄' additional_kwargs={} response_metadata={'finish_reason': 'stop', 'model_name': 'glm-4-flash'} id='run--a3723e25-7094-4fad-8339-fdd41da406e4' usage_metadata={'input_tokens': 13, 'output_tokens': 20, 'total_tokens': 33, 'input_token_details': {}, 'output_token_details': {}}

😄|%                                   

updates

for chunk in graph.stream(
    message,
    stream_mode="updates"
):
    print(chunk)

{
	'call_model': {
		'joke': '有一天,冰淇淋去参加一个聚会,它走进房间后,看到大家都在聊天,于是它决定找个地方坐下。\n\n冰淇淋走到一个角落,看到一把椅子,它说:“嘿,椅子,我坐这里可以吗?”\n\n椅子回答:“当然可以,不过你得小心,我可是个‘冷’椅子。”\n\n冰淇淋一愣,然后笑着说:“哦,原来您是个‘冷’椅子啊,那我可得小心别融化了。”\n\n大家听了都笑了,椅子也跟着笑了起来,从此,冰淇淋和椅子成了好朋友,每次聚会都会带来欢乐。'
	}
}

messages + updates

for chunk in graph.stream(
    message,
    stream_mode=["messages", "updates"],
):
    print('\n', chunk )   

(
  'messages', 
 		(
      AIMessageChunk(
      content = '有一天', additional_kwargs = {}, response_metadata = {}, 
      id = 'run--8ecc7304-693a-44f5-84ca-7164e02cb8ec'), 
      {
        'langgraph_step': 1,
        'langgraph_node': 'call_model',
        'langgraph_triggers': ('branch:to:call_model', ),
        'langgraph_path': ('__pregel_pull', 'call_model'),
        'langgraph_checkpoint_ns': 'call_model:9ea3643a-d6f7-88c5-c9ea-4e355adb32c9',
        'checkpoint_ns': 'call_model:9ea3643a-d6f7-88c5-c9ea-4e355adb32c9',
        'ls_provider': 'openai',
        'ls_model_name': 'glm-4-flash',
        'ls_model_type': 'chat',
        'ls_temperature': 0.1 
      }
 	 )
)

('messages', (
  AIMessageChunk(
    content = ',', additional_kwargs = {}, response_metadata = {},  
    id = 'run--8ecc7304-693a-44f5-84ca-7164e02cb8ec'), 
    { 
      'langgraph_step': 1,
      'langgraph_node': 'call_model',
      'langgraph_triggers': ('branch:to:call_model', ),
      'langgraph_path': ('__pregel_pull', 'call_model'),
      'langgraph_checkpoint_ns': 'call_model:9ea3643a-d6f7-88c5-c9ea-4e355adb32c9',
      'checkpoint_ns': 'call_model:9ea3643a-d6f7-88c5-c9ea-4e355adb32c9',
      'ls_provider': 'openai',
      'ls_model_name': 'glm-4-flash',
      'ls_model_type': 'chat',
      'ls_temperature': 0.1	
      }
   )
)

('messages', (
	AIMessageChunk(
		content = '冰淇淋', additional_kwargs = {}, response_metadata = {}, 
    id = 'run--8ecc7304-693a-44f5-84ca-7164e02cb8ec'), 
  {
		'langgraph_step': 1,
		'langgraph_node': 'call_model',
		'langgraph_triggers ': ('branch: to: call_model ',), 
		'langgraph_path': ('__pregel_pull', 'call_model'),
		'langgraph_checkpoint_ns': 'call_model:9ea3643a-d6f7-88c5-c9ea-4e355adb32c9',
		'checkpoint_ns': 'call_model:9ea3643a-d6f7-88c5-c9ea-4e355adb32c9',
		'ls_provider': 'openai',
		'ls_model_name': 'glm-4-flash',
		'ls_model_type': 'chat',
		'ls_temperature': 0.1
	}
))


...

('messages', (AIMessageChunk(
	content = '!”', additional_kwargs = {}, response_metadata = {}, 
  id = 'run--4e59a246-6974-4416-a22b-64a0f11605e3'), 
  {
	'langgraph_step': 1,
	'langgraph_node': 'call_model',
	'langgraph_triggers': ('branch:to:call_model', ),
	'langgraph_path': ('__pregel_pull', 'call_model'),
	'langgraph_checkpoint_ns': 'call_model:d2654764-3e30-1059-8493-ec47cc229898',
	'checkpoint_ns': 'call_model:d2654764-3e30-1059-8493-ec47cc229898',
	'ls_provider': 'openai',
	'ls_model_name': 'glm-4-flash',
	'ls_model_type': 'chat',
	'ls_temperature': 0.1
}))

('messages', (AIMessageChunk(
	content = '', additional_kwargs = {}, 
  response_metadata = {
		'finish_reason': 'stop',
		'model_name': 'glm-4-flash'
	}, 
  id = 'run--4e59a246-6974-4416-a22b-64a0f11605e3', 
  usage_metadata = {
		'input_tokens': 14,
		'output_tokens': 130,
		'total_tokens': 144,
		'input_token_details': {},
		'output_token_details': {}
	}), {
	'langgraph_step': 1,
	'langgraph_node': 'call_model',
	'langgraph_triggers': ('branch:to:call_model', ),
	'langgraph_path': ('__pregel_pull', 'call_model'),
	'langgraph_checkpoint_ns': 'call_model:d2654764-3e30-1059-8493-ec47cc229898',
	'checkpoint_ns': 'call_model:d2654764-3e30-1059-8493-ec47cc229898',
	'ls_provider': 'openai',
	'ls_model_name': 'glm-4-flash',
	'ls_model_type': 'chat',
	'ls_temperature': 0.1
}))


('updates', {
	'call_model': {
		'joke': '有一天,冰淇淋去参加一个聚会,它走进房间后,看到大家都在聊天,于是它决定找个地方坐下。它走到一个角落,看到一把椅子,就坐了下来。\n\n冰淇淋刚坐下,突然椅子开始颤动,然后椅子上的一个按钮亮了起来。冰淇淋好奇地按了按钮,结果椅子上突然冒出一句话:“你坐得有点重,小心我融化了!”\n\n大家听了都哈哈大笑,冰淇淋也尴尬地笑了。这时,一个朋友走过来,拍了拍冰淇淋的肩膀说:“别担心,我们这里都是‘融融’的气氛,大家都很欢迎你!”'
	}
})

messages + updates 2

# updates 会打印出错 
for msg_type, (message_chunk, metadata) in graph.stream(
    message,
    stream_mode=["messages", "updates"],
):

    print('\n-- msg_type : ', msg_type ) 
    print('-- message_chunk : ', message_chunk) 
    print('-- metadata : ', metadata) 


-- metadata 2:  
{
	'langgraph_step': 1,
	'langgraph_node': 'call_model',
	'langgraph_triggers': ('branch:to:call_model', ),
	'langgraph_path': ('__pregel_pull', 'call_model'),
	'langgraph_checkpoint_ns': 'call_model:a3f28959-0172-a7a9-797f-3ada4609cdc1',
	'checkpoint_ns': 'call_model:a3f28959-0172-a7a9-797f-3ada4609cdc1',
	'ls_provider': 'openai',
	'ls_model_name': 'glm-4-flash',
	'ls_model_type': 'chat',
	'ls_temperature': 0.1
}

**************************

-- msg_type :  messages
-- message_chunk :  content='有一天' additional_kwargs={} response_metadata={} id='run--d0984020-e413-44f0-bacb-ba4667ee10c3'

-- msg_type :  messages
-- message_chunk :  content=',' additional_kwargs={} response_metadata={} id='run--d0984020-e413-44f0-bacb-ba4667ee10c3'

-- msg_type :  messages
-- message_chunk :  content='冰淇淋' additional_kwargs={} response_metadata={} id='run--d0984020-e413-44f0-bacb-ba4667ee10c3'

...

-- msg_type :  messages
-- message_chunk :  content='了' additional_kwargs={} response_metadata={} id='run--d0984020-e413-44f0-bacb-ba4667ee10c3'

-- msg_type :  messages
-- message_chunk :  content='!”' additional_kwargs={} response_metadata={} id='run--d0984020-e413-44f0-bacb-ba4667ee10c3'

-- msg_type :  messages
-- message_chunk :  content='' additional_kwargs={} response_metadata={'finish_reason': 'stop', 'model_name': 'glm-4-flash'} id='run--d0984020-e413-44f0-bacb-ba4667ee10c3' usage_metadata={'input_tokens': 14, 'output_tokens': 144, 'total_tokens': 158, 'input_token_details': {}, 'output_token_details': {}}


*****

('updates', {
	'call_model': {
		'joke': '有一天,冰淇淋去参加一个聚会,它走进房间后,看到大家都在聊天,于是它决定找个地方坐下。它走到一个角落,看到一把椅子,就坐了下来。\n\n冰淇淋刚坐下,突然椅子开始颤动,然后椅子上的一个按钮亮了起来。冰淇淋好奇地按了按钮,结果椅子上突然冒出一句话:“你坐得有点重,小心我融化了!”\n\n大家听了都哈哈大笑,冰淇淋也尴尬地笑了。这时,一个朋友走过来,拍了拍冰淇淋的肩膀说:“别担心,我们这里都是‘融融’的气氛,大家都很欢迎你!”'
	}
})


2025-05-27(二)

### 使用 LangGraph 和大模型开发数据分析助理智能体 #### 背景与目标 LangGraph 是一种强大的工具,能够用于构建复杂的多智能体系统。它不仅提供了灵活的工作流设计能力,还允许开发者轻松集成多种模块化的功能组件[^1]。结合大模型的强大自然语言处理能力和数据分析能力,可以创建一个高效的数据分析助理智能体。 这种智能体的主要目标是帮助企业或个人快速完成数据清洗、探索性数据分析(EDA)、统计建模以及可视化展示等工作。以下是关于如何利用 LangGraph 和大模型技术来开发这样一个系统的详细介绍。 --- #### 工作流概述 为了实现数据分析助理的功能,整个工作流通常分为以下几个部分: 1. **用户交互接口** 用户可以通过自然语言提问的方式向系统发起请求,例如:“请帮我分析销售数据的趋势。” 这一阶段主要依赖于前端界面或者 API 接口接收输入,并将其传递给后端逻辑层进行解析和执行[^4]。 2. **任务分解与调度** 利用 LangGraph 提供的任务编排机制,将复杂的大规模问题拆解成多个子任务分别交给不同的 Agents 来解决。比如某些特定类型的计算可能更适合由擅长数值运算的小型专用模型负责;而对于涉及高层次理解的内容,则交予大型预训练语言模型去处理[^3]。 3. **数据获取与预处理** 数据源可能是本地文件上传、数据库查询结果或者是外部API调取得到的信息集合。无论哪种形式,在正式进入下一步之前都需要经过必要的清理操作——去除噪声项、填补缺失值等等。这部分也可以自动化地设置为独立节点运行在图结构当中[^2]。 4. **核心算法应用** 针对具体业务场景选用合适的机器学习方法论实施预测/分类等高级别决策制定过程。同时还可以引入解释性的图表生成服务以便让最终呈现出来的结论更加直观易懂[^1]。 5. **结果反馈** 最后一步就是把所有中间环节产生的有用信息汇总起来形成一份完整的报告文档返回给原始询问者查看。这期间同样需要用到一些模板渲染引擎配合自定义样式表单共同作用才能达到最佳视觉效果体验标准[^3]。 --- #### 技术栈推荐 - **编程语言**: Python (因其拥有丰富的库支持) - **框架**: LangChain / HuggingFace Transformers 等作为基础支撑平台 - **云服务平台选项**: AWS SageMaker, Google Cloud Vertex AI 或 Azure Machine Learning Services 可以为大规模分布式训练提供必要资源保障[^2] --- #### 实践案例分享 假设我们需要打造一款专注于电商领域的产品销量趋势洞察助手。那么按照前述提到的整体思路规划如下步骤即可达成目的: 1. 定义清晰的目标范围; 2. 收集相关历史交易记录明细资料; 3. 设计合理的特征工程方案提取有意义指标变量; 4. 训练回归类监督学习模型捕捉潜在规律模式; 5. 将所得成果封装进图形界面上线发布供实际使用者便捷访问查阅[^4]. --- ```python from langchain import PromptTemplate, LLMChain from langchain.llms import OpenAI def create_data_analysis_agent(): template = """You are a data analysis assistant. Given the following context about user's request and dataset information, generate an appropriate response that includes insights from exploratory data analysis. Context: {context} Dataset Info: {dataset_info} Response:""" prompt = PromptTemplate(template=template, input_variables=["context", "dataset_info"]) llm_chain = LLMChain(prompt=prompt, llm=OpenAI()) return llm_chain agent = create_data_analysis_agent() response = agent.run({"context": "Analyze sales trends.", "dataset_info": "Monthly revenue figures over past year."}) print(response) ``` --- ### 结语 通过以上描述可以看出,借助像 LangGraph 这样的先进工具和技术手段完全可以打造出满足不同行业需求特点的数据驱动型解决方案。希望这些指导能对你有所帮助! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EAI工程笔记

请我喝杯伯爵奶茶~!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值