基于LangGraph构建上下文感知AI智能体:从Arcads Mark看工作流集成
如果你在 Slack 里和同事讨论一个新产品聊到一半突然需要一张广告图你会怎么做大概率是暂停对话打开设计工具或者去求设计同事描述需求等待再回来继续聊。这个打断不仅消耗时间更打断了协作的“心流”。最近一个叫Arcads Mark的 AI 工具正式入驻 Slack它想解决的就是这个“打断”问题。它不是一个独立的设计平台而是一个直接嵌入在 Slack 对话中的“广告生成智能体”。你不需要离开 Slack在对话的上下文里直接告诉它你的想法它就能生成对应的广告素材。听起来很酷但这件事真的只是“在 Slack 里多了个画图机器人”那么简单吗我认为Arcads Mark 入驻 Slack 的真正价值不在于“生成广告”而在于它首次将“内容创作”无缝融入了“团队协作”的核心工作流。它模糊了“沟通”与“执行”的边界让 AI 智能体从一个需要被“调用”的工具变成了一个随时待命的“协作者”。对于开发者、产品经理和运营同学来说这意味着什么它背后依赖的“对话上下文”理解能力对构建企业级 AI 应用又有哪些启发更重要的是我们能否借鉴其思路在自己的项目中实现类似的“上下文感知”自动化能力本文将深入拆解 Arcads Mark 的技术逻辑并基于其理念手把手带你用主流的 AI 开发框架如 LangChain/LangGraph构建一个简化版的、能理解对话上下文的本地 AI 智能体。你会发现智能体开发的核心已经从“功能实现”转向了“工作流集成”。1. Arcads Mark 解决了什么真问题在讨论技术之前我们必须先厘清痛点。传统的广告素材生产流程存在几个明显的断层需求产生与传递断层创意往往诞生于即时讨论Slack/Teams/飞书。将模糊的讨论语言“我们要一个突出夜间模式省电特性的Banner”转化为精确的设计需求文档PRD本身就有信息损耗。工具切换成本断层从沟通工具切换到设计工具Figma、Canva再到文件传输、审核、修改流程冗长。对于需要快速测试创意的增长团队这种延迟是致命的。上下文丢失断层设计师拿到的是一份孤立的 PRD他看不到之前讨论中的那些“感觉不对”、“类似XX竞品但更活泼”的微妙语境导致成品需要多轮修改。Arcads Mark 的切入点正是这些“断层”。它没有试图取代专业设计师或复杂的 Figma而是瞄准了“快速原型”、“即时可视化”和“共识达成”这个场景。它的目标用户不是设计师而是产品经理、运营、市场和开发者——那些需要快速把想法变成可视物来推动讨论的人。它的核心判断是最高效的需求传递不是文档而是基于当前对话语境即时生成的、可交互的视觉草案。这本质上是一种“对话式设计”Conversational Design。2. 核心概念什么是“对话上下文”驱动的 AI 智能体要理解 Arcads Mark必须理解两个关键概念AI 智能体和对话上下文。2.1 AI 智能体从工具到协作者AI 智能体AI Agent不是简单的聊天机器人。你可以把它理解为一个具备一定自主性的数字员工。它通常包含几个核心模块感知理解用户的输入文本、文件等。规划分析目标拆解为一系列可执行的步骤。执行调用各种工具Tools/Skills来完成步骤比如调用图像生成 API、搜索网络、读写数据库。记忆保存对话历史和执行结果用于后续决策。传统的 AI 工具是“你问我答”而智能体是“你提需求我负责搞定全过程”。Arcads Mark 就是一个专精于广告生成的垂直领域智能体。2.2 对话上下文智能体的“工作记忆”“对话上下文”是智能体理解当前任务背景的关键。在 Slack 中上下文不仅仅是当前的一句话而是当前消息用户的直接指令。历史消息这个频道或私聊中之前的对话。提及的文件/链接用户可能上传了参考图或产品文档。线程回复智能体可能在一个复杂的讨论线程中被。例如在长达 50 条消息的产品讨论中有人 Arcads Mark 说“基于我们刚才说的做一个强调‘极速启动’的广告图。” 智能体需要回溯之前的 49 条消息理解“刚才说的”具体指什么可能是关于新版 App 启动速度优化了 200%以及“极速启动”这个关键词应该如何视觉化。技术上的挑战在于“上下文长度”和“信息提取”。大模型LLM有上下文窗口限制不能无脑把全部历史对话都塞进去。这就需要“上下文压缩”或“摘要”技术只提取与当前任务最相关的片段。这正是网络热词中提到的deepseek harness 上下文压缩:长对话管理所涉及的技术。3. 环境准备构建本地 AI 智能体的技术栈在深入 Arcads Mark 的仿建之前我们先搭建一个可以实验的本地环境。我们将使用LangGraph来构建智能体的工作流用Ollama本地运行开源大模型用Chainlit或Gradio构建一个简单的聊天界面来模拟 Slack 的交互。为什么选这个技术栈LangGraph来自 LangChain 团队专门用于构建有状态、多步骤的智能体工作流比单纯的 LangChain Expression Language 更适合复杂逻辑。Ollama轻松在本地运行 Llama 3、Mistral 等开源模型隐私安全成本可控适合学习和原型开发。本地运行完全掌控数据和流程符合企业级安全合规的初始要求呼应了热词中的golang实现企业级ai智能体安全合规自动化检测系统所关注的点。3.1 基础环境与安装确保你的系统已安装 Python (3.9)。# 1. 创建并进入项目目录 mkdir slack-ai-agent-demo cd slack-ai-agent-demo # 2. 创建虚拟环境推荐 python -m venv venv # Windows 激活 venv\Scripts\activate # macOS/Linux 激活 source venv/bin/activate # 3. 安装核心依赖 pip install langgraph langchain langchain-community chainlit ollama # 如果需要图像生成我们使用稳定性AI的SDXL需API Key此处用本地替代方案演示 pip install requests pillow3.2 启动 Ollama 并拉取模型Ollama 需要单独安装并运行在后台。# 前往 Ollama 官网 (https://ollama.com) 下载并安装对应系统的客户端。 # 安装后在终端拉取一个轻量级但能力不错的模型如 Llama 3.1 8B ollama pull llama3.1:8b # 运行模型服务通常安装后会自动运行服务 # 检查服务是否运行 curl http://localhost:11434/api/generate -d { model: llama3.1:8b, prompt: Hello }如果返回一段 JSON 格式的生成文本说明 Ollama 服务运行正常。4. 核心流程拆解构建一个上下文感知的广告生成智能体我们要构建的智能体其核心工作流程如下图所示用文字描述触发在聊天界面中用户输入指令如“为我们的新产品‘闪电笔记’做一个广告图主题是快”。上下文加载智能体不仅读取当前指令还自动加载最近的 N 条历史对话模拟 Slack 上下文。意图分析与规划LLM 分析指令和历史判断用户需要“生成广告图”并提取关键要素产品名、主题、风格要求、可能的尺寸。工具调用智能体调用两个工具search_web如果指令模糊如“做一个像苹果风格那样的”则搜索相关参考信息。generate_image使用图像生成模型结合提炼出的提示词生成图片。响应与记忆将生成的图片返回给用户并将本次交互的关键信息用户指令、生成的图片描述、工具调用记录存入“记忆”中供后续对话使用。4.1 步骤一定义智能体的“记忆” - 对话历史管理这是实现“上下文感知”的基石。我们将使用 LangGraph 的StateGraph和MessagesState来管理状态。# file: agent_memory.py from typing import Annotated, List, Dict, Any from typing_extensions import TypedDict from langgraph.graph.message import add_messages import operator # 定义智能体的状态结构 class AgentState(TypedDict): # 存储完整的对话消息历史 messages: Annotated[List[Dict], add_messages] # 存储从历史中提取的、与当前任务相关的产品/项目信息 project_context: str # 存储本次运行中工具调用的结果 tool_outputs: List[str] # 最终生成的图像 URL 或路径 generated_image_url: str # 这是一个简化版。在实际的 Slack 集成中messages 的初始化需要从 Slack API 获取真实的对话历史。4.2 步骤二定义智能体的“工具”工具是智能体能力的外延。我们先定义两个基础工具。# file: agent_tools.py import requests import json from langchain.tools import tool from langchain_community.utilities import SerpAPIWrapper import os # 工具1网络搜索用于获取最新信息或参考风格 # 注意需要 SERPAPI_API_KEY 环境变量。你也可以替换为其他搜索API。 tool def search_web(query: str) - str: 当用户指令需要实时信息或风格参考时使用此工具搜索网络。 try: search SerpAPIWrapper() result search.run(query) return result[:500] # 限制返回长度 except Exception as e: return f搜索失败: {e}. 请确保已设置 SERPAPI_API_KEY 环境变量。 # 工具2图像生成模拟 Arcads Mark 的核心功能 # 此处为演示我们调用一个免费的、无需KEY的在线API例如 Hugging Face Inference API。 # 生产环境应使用 Stability AI, DALL-E, 或本地部署的 Stable Diffusion。 tool def generate_image(prompt: str, style: str digital art) - str: 根据文本提示词生成广告图像。返回图像的URL或保存路径。 # 这里是模拟代码。实际使用需要替换为真实的图像生成API调用。 # 示例使用 Hugging Face 的 SDXL 模型需要 Token # HF_API_TOKEN os.getenv(HF_TOKEN) # API_URL https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0 # headers {Authorization: fBearer {HF_API_TOKEN}} # response requests.post(API_URL, headersheaders, json{inputs: prompt}) # image_url ... 处理响应上传到图床或保存本地返回可访问URL print(f[模拟] 正在生成图像提示词: {prompt}, 风格: {style}) # 模拟生成返回一个占位图URL placeholder_url fhttps://via.placeholder.com/800x400/4A90E2/FFFFFF?text{prompt.replace( , )} return placeholder_url # 将工具包装成列表供智能体使用 tools [search_web, generate_image]4.3 步骤三构建智能体的“大脑” - LLM 与函数调用我们需要让 LLM 学会在适当的时候选择调用哪个工具。这通过bind_tools和ToolNode实现。# file: agent_brain.py from langchain_community.chat_models import ChatOllama from langchain.tools.render import format_tool_to_openai_function from langchain.agents import AgentExecutor, create_openai_functions_agent from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langgraph.prebuilt import ToolExecutor, ToolInvocation # 1. 连接本地 Ollama 的 LLM llm ChatOllama(modelllama3.1:8b, temperature0.2) # 为 LLM 绑定工具使其知道有哪些工具可用 llm_with_tools llm.bind_tools(tools) # 2. 定义提示词模板这是指导智能体行为的关键 prompt ChatPromptTemplate.from_messages([ (system, 你是一个专业的广告素材生成助手名为“Mark”。 你的核心能力是理解对话上下文并生成符合需求的广告图像。 用户可能在讨论产品的任何细节。你的任务是 1. 仔细分析当前用户指令和最近的对话历史。 2. 提取与广告生成相关的关键信息产品名称、核心卖点、目标受众、视觉风格偏好如“科技感”、“温馨”、“炫酷”、尺寸要求。 3. 如果信息不足比如不知道产品长什么样或不清楚某种风格的具体表现可以谨慎地使用搜索工具查询。 4. 最后调用图像生成工具生成符合要求的广告图。 请用中文与用户交流并保持友好、专业的口吻。 ), MessagesPlaceholder(variable_namemessages), # 这里会自动注入历史消息 ]) # 3. 创建工具执行器 tool_executor ToolExecutor(tools)4.4 步骤四用 LangGraph 编排工作流这是最核心的部分我们将智能体的决策循环用图Graph的形式定义出来。# file: agent_graph.py from langgraph.graph import StateGraph, END from langgraph.prebuilt import tools_condition from .agent_memory import AgentState from .agent_brain import llm_with_tools, prompt, tool_executor from langchain_core.messages import AIMessage, ToolMessage # 定义节点函数 def agent_node(state: AgentState): 智能体决策节点分析状态决定下一步是回复还是调用工具。 # 1. 根据当前状态包含历史消息生成提示词 formatted_prompt prompt.invoke({messages: state[messages]}) # 2. 让绑定了工具的LLM进行预测 response llm_with_tools.invoke(formatted_prompt) # 3. 将LLM的响应可能是普通消息也可能是工具调用请求添加到消息历史中 state[messages].append(response) return {messages: [response]} # 返回更新后的消息部分 def tool_node(state: AgentState): 工具执行节点执行LLM要求的工具调用。 last_message state[messages][-1] tool_calls last_message.tool_calls # 获取LLM想要调用的工具列表 tool_outputs [] for tool_call in tool_calls: # 执行每一个工具调用 result tool_executor.invoke(tool_call) # 将工具执行结果封装成 ToolMessage tool_outputs.append(ToolMessage(contentstr(result), tool_call_idtool_call[id])) # 将工具执行结果也加入消息历史 state[messages].extend(tool_outputs) return {tool_outputs: tool_outputs, messages: tool_outputs} # 构建工作流图 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(agent, agent_node) workflow.add_node(tools, tool_node) # 设置入口点 workflow.set_entry_point(agent) # 定义边根据LLM的输出来决定下一步去哪 # tools_condition 是一个内置函数它会检查最后一个消息是否包含工具调用。 workflow.add_conditional_edges( agent, tools_condition, # 如果调用了工具就去“tools”节点 { tools: tools, # 条件为真去工具节点 end: END # 条件为假直接结束 } ) # 从工具节点执行完后总是回到智能体节点进行下一步决策 workflow.add_edge(tools, agent) # 编译图 app workflow.compile()5. 完整示例运行你的上下文感知广告生成智能体现在我们将所有部分组合起来并模拟一个 Slack 中的多轮对话场景。# file: main.py from agent_graph import app from agent_memory import AgentState from langchain_core.messages import HumanMessage import json def run_agent_conversation(): 模拟一个完整的对话流程 # 初始化状态模拟一些历史对话上下文 initial_state: AgentState { messages: [ HumanMessage(content我们下周要上线的新功能叫‘AI 会议纪要’能自动总结会议要点。), HumanMessage(content对这个功能的目标用户是忙碌的职场人和项目经理。), HumanMessage(content我们需要一些预热宣传素材。), # 最新的用户指令 ], project_context: 产品AI 会议纪要用户职场人/项目经理阶段预热宣传, tool_outputs: [], generated_image_url: } print( 对话历史上下文) for msg in initial_state[messages]: print(f{msg.type}: {msg.content}) # 用户发出新指令这个指令依赖于上文 new_user_input 基于我们刚才讨论的做一个突出‘自动总结、节省时间’这个卖点的广告横幅要有点科技感。 print(f\n 用户新指令 ) print(new_user_input) # 将新指令加入状态 initial_state[messages].append(HumanMessage(contentnew_user_input)) # 运行编译好的智能体工作流 print(\n 智能体开始工作... ) final_state app.invoke(initial_state) print(\n 最终对话记录 ) for msg in final_state[messages]: if hasattr(msg, tool_calls) and msg.tool_calls: print(fAI (工具调用): {msg.tool_calls}) elif msg.type tool: print(f工具结果: {msg.content[:100]}...) # 截断显示 else: print(f{msg.type}: {msg.content}) # 提取生成的图片URL for msg in reversed(final_state[messages]): if msg.type tool and placeholder.com in msg.content: print(f\n✅ 广告图已生成访问链接: {msg.content}) break if __name__ __main__: run_agent_conversation()运行这个脚本python main.py预期输出示例 对话历史上下文 human: 我们下周要上线的新功能叫‘AI 会议纪要’能自动总结会议要点。 human: 对这个功能的目标用户是忙碌的职场人和项目经理。 human: 我们需要一些预热宣传素材。 用户新指令 基于我们刚才讨论的做一个突出‘自动总结、节省时间’这个卖点的广告横幅要有点科技感。 智能体开始工作... [模拟] 正在生成图像提示词: A tech-style advertising banner for AI Meeting Minutes product. The slogan is Auto-Summarize, Save Time. The style is sleek, modern, with blue and white color scheme, targeting busy professionals and project managers. The banner should highlight efficiency and technology., 风格: digital art 最终对话记录 human: 我们下周要上线的新功能叫‘AI 会议纪要’能自动总结会议要点。 human: 对这个功能的目标用户是忙碌的职场人和项目经理。 human: 我们需要一些预热宣传素材。 human: 基于我们刚才讨论的做一个突出‘自动总结、节省时间’这个卖点的广告横幅要有点科技感。 AI (工具调用): [{name: generate_image, args: {prompt: A tech-style advertising banner..., style: digital art}, id: ...}] 工具结果: https://via.placeholder.com/800x400/4A90E2/FFFFFF?textAtech-styleadvertisingbanner... ✅ 广告图已生成访问链接: https://via.placeholder.com/800x400/4A90E2/FFFFFF?textAtech-styleadvertisingbanner...6. 运行结果与效果验证运行上述代码你应该能看到智能体完整的工作流程加载上下文它读取了三条历史消息理解了产品是“AI 会议纪要”用户是“职场人/项目经理”当前阶段是“预热宣传”。理解与规划LLM 分析了新指令“基于刚才讨论的...”成功将“刚才讨论的”关联到历史上下文并提取出关键要素产品名、卖点自动总结、节省时间、风格科技感、格式横幅。工具调用智能体决定直接调用generate_image工具并组合生成了一个非常详细的英文提示词因为底层图像模型对英文理解更好。提示词中包含了从上下文中提炼的所有关键信息。返回结果工具执行后返回了一个图像 URL示例中是占位图真实情况是生成的广告图。如何验证成功上下文理解验证尝试修改历史对话比如把产品名改成“智能笔记”再发出同样的指令。观察生成的提示词是否包含了“智能笔记”。工具选择验证将用户指令改为“科技感具体指什么风格搜一下看看”。观察智能体是否会先调用search_web工具。多轮对话验证在生成图片后继续追加指令“背景换成深色系”看智能体是否能基于之前的对话理解这是对同一张图的修改要求并再次调用图像生成工具。7. 常见问题与排查思路在构建和运行此类智能体时你可能会遇到以下问题问题现象可能原因排查方式解决方案Ollama 服务调用失败连接被拒绝Ollama 服务未启动或端口被占用在终端执行ollama list或curl http://localhost:11434/api/tags1. 启动 Ollama 应用。2. 检查端口11434是否被其他进程占用。LLM 无法理解指令总是回复“我不明白”而不是调用工具1. 提示词System Prompt不够清晰。2. 模型能力不足。3. 工具绑定不正确。1. 检查prompt中的 system message 是否明确赋予了调用工具的职责。2. 尝试在调用bind_tools后打印llm_with_tools.get_tools()查看工具是否绑定成功。3. 换用更强的模型如llama3.1:70b或qwen2.5:72b。1. 优化提示词明确使用“你可以调用XX工具来做XX事”的句式。2. 确保tool装饰器正确使用函数有文档字符串docstring。3. 升级模型或使用 GPT-4 等更强大的模型进行原型验证。智能体陷入死循环不停调用工具图Graph的条件边conditional edges逻辑有误或工具返回的结果无法让LLM结束任务。1. 打印每一轮的状态和消息观察LLM的决策。2. 检查tools_condition的逻辑。1. 在提示词中明确告诉LLM“生成图片后任务就结束了”。2. 自定义条件边逻辑例如检查是否已生成图片URL如果是则直接走向END。生成的图片提示词质量差与上下文无关1. LLM 未能有效提取上下文信息。2. 历史消息传递方式有问题。1. 检查传入prompt的messages是否包含了完整的历史。2. 在agent_node中打印formatted_prompt的内容看历史是否被正确格式化。1. 使用“上下文压缩”技术如果历史太长先让LLM对历史进行摘要再将摘要和当前指令一起处理。2. 在提示词中更强调“请仔细参考之前的对话”。无法处理中文指令或生成中文提示词模型本身对中文支持不佳或提示词引导不够。测试模型纯中文对话能力。1. 使用专门优化过中文的模型如qwen2.5系列。2. 在 system prompt 中明确要求“请用中文思考但为图像生成模型生成英文提示词”。8. 最佳实践与工程建议将这样一个原型智能体升级为可用于生产环境的系统类似 Arcads Mark还需要考虑很多工程问题上下文管理与压缩问题Slack 频道历史可能长达千条无法全部放入 LLM 上下文窗口。方案实现一个“上下文检索器”。将历史对话向量化存储当新消息到来时只检索最相关的若干条片段而非全部历史。这正是deepseek harness等库解决的问题。工具生态与安全性问题智能体能调用哪些工具如何防止滥用方案建立严格的工具权限体系。像golang实现企业级ai智能体安全合规自动化检测系统所关注的需要对工具调用进行审计、鉴权和内容过滤。例如图像生成工具可能需要审核提示词是否合规。状态持久化与多用户会话问题如何为 Slack 上成千上万个不同的对话线程维护独立的状态方案使用数据库如 Redis存储AgentState以(team_id, channel_id, thread_ts)为键。每次交互时加载状态处理后再保存。异步与性能问题图像生成和网络搜索可能是慢操作会阻塞 Slack 的响应。方案采用异步处理。当收到复杂请求时智能体先回复“正在处理...”然后在后台执行任务完成后通过 Slack 的response_url或消息更新功能发送结果。提示词工程与版本管理问题如何优化提示词效果并管理不同版本方案将提示词模板化、外部化如存储在数据库或配置文件中。使用 A/B 测试框架来评估不同提示词版本的效果并实现灰度发布。错误处理与用户体验问题工具调用失败或 LLM 输出混乱时如何优雅降级方案为每个工具调用设置重试机制和超时。在智能体工作流中增加“人工审核”或“默认回复”节点。记录完整的执行日志便于排查。9. 总结与后续学习方向Arcads Mark 入驻 Slack给我们展示的不仅仅是一个新工具而是一种新的软件交互范式AI 智能体深度融入现有工作流成为沉默的、上下文感知的协作者。对于开发者而言构建这样的智能体技术难点已从“如何调 API”转变为“如何设计一个稳定、安全、高效并能理解复杂上下文的工作流系统”。通过本文的实践我们完成了一个最小可行产品MVP理解了AI 智能体的核心组件记忆、规划、工具使用。掌握了使用LangGraph构建有状态工作流的方法。实现了对话上下文的初步利用让智能体基于历史对话做出决策。模拟了工具调用的完整流程。如果你想继续深入可以从以下几个方向探索替换真实的图像生成 API将generate_image工具替换为 Stability AI、OpenAI DALL-E 或 Midjourney 的 API生成真实的广告图。集成真实的 Slack使用 Slack Bolt 框架将你的智能体部署为一个真正的 Slack App处理真实的mention事件。实现高级上下文管理集成向量数据库如 Chroma, Weaviate为智能体配备长期记忆和精准检索能力。开发更多“技能”参考人工智能skills怎么安装到ai智能体上这个思路将智能体能力模块化。除了生成图片还可以开发“写广告文案”、“分析竞品广告”、“生成A/B测试方案”等技能让智能体真正成为一个多面手。智能体开发的浪潮已经到来它正在从演示走向生产。掌握其核心架构与工程实践意味着你不仅能使用像 Arcads Mark 这样的优秀工具更能亲手打造属于自己团队和业务的“数字协作者”。