基于LangGraph构建持久化AI智能体:从状态管理到插件化实战
2026/5/8 10:16:52 网站建设 项目流程

1. 项目概述:一个为真实工作而生的持久化AI智能体

如果你和我一样,曾经被那些“演示很酷,一用就废”的AI智能体项目折腾得够呛,那么openShrimp的出现,可能会让你眼前一亮。这不是又一个在干净数据集上跑通就宣告胜利的玩具,而是一个我从实际研究工作中“逼”出来的工具。它的核心目标异常简单:给你一个能真正“干完活”的AI助手,而不是一个需要你不停喂指令、时刻担心它掉线的“半成品”

我最初是OpenClaw的用户,那个项目在理念上非常吸引人——一个能自主上网研究的AI智能体。但在实际使用中,我不断撞墙:任务跑着跑着就没了下文,中间过程像黑盒一样不可见,想让它持续跟踪一个长期项目更是无从谈起。于是,openShrimp诞生了。它本质上是一个基于LangGraph构建的、任务驱动的自主智能体,但其设计哲学完全围绕“生产可用性”展开:持久化的任务状态管理、零配置的Telegram交互界面、模块化的插件系统,以及一个坚如磐石的后端(PostgreSQL + PGVector)。你可以把它理解为一个不知疲倦的远程研究助理,你通过Telegram给它派活,它会在自己的“任务看板”上列出来,然后默默地、持续地工作,直到完成或确实需要你介入为止。

注意:openShrimp的设计强调“自治”而非“全自动”。它会在关键决策点(如需要登录凭证时)主动询问你,但一旦获得授权,就会自主推进,无需你反复催促“继续”。

2. 核心设计理念:为什么选择这样的架构?

在动手搭建或使用openShrimp之前,理解其背后的设计抉择至关重要。这能帮助你在遇到问题时,知道该从哪个层面去思考和解决。

2.1 状态持久化:告别“失忆”的智能体

绝大多数AI智能体项目,包括早期的OpenClaw,其运行状态是 ephemeral(临时的)。一次对话结束,所有中间思考、执行步骤、收集到的资料瞬间清零。这对于严肃的研究或自动化工作流是致命的。

openShrimp的解决方案:将一切核心状态锚定在PostgreSQL数据库中。

  • 任务模型:每个用户请求都会在数据库中创建一条Task记录,包含状态(待处理、进行中、等待人工输入、完成、失败)、创建时间最后心跳关联项目等字段。这意味着即使整个应用重启,未完成的任务依然存在,并能从中断处恢复。
  • 记忆向量化:通过集成PGVector扩展,智能体与工具交互产生的关键信息(如网页摘要、分析结论)可以被存储和检索,形成长期记忆。这使得智能体在后续任务中能“记得”之前了解过的内容。
  • 设计考量:为什么是PostgreSQL而不是更简单的SQLite或内存存储?答案在于并发可靠性与生态。PostgreSQL能更好地处理多用户、多任务并发写入;PGVector是目前最成熟的开源向量数据库方案之一,与LangChain等AI框架集成度极高;同时,它也为未来可能的分布式部署奠定了基础。

2.2 Telegram作为首要交互界面:极致的用户体验与部署便利性

许多AI项目需要你部署一套复杂的前后端Web应用才能交互。openShrimp反其道而行之,将Telegram Bot作为唯一的一线交互界面。

这样做的好处是压倒性的

  1. 零前端成本:你不需要编写任何HTML、CSS或JavaScript。Telegram提供了现成的、跨平台的消息界面、按钮、菜单甚至文件传输功能。
  2. 天然的异步与通知:智能体可以主动向你发送消息(例如,“我需要XX网站的登录密码”),而你可以在方便的时候回复。这种异步通信模型完美契合了长时间运行任务的需求。
  3. 极简部署:用户侧零配置。他们只需要在Telegram中搜索你的Bot,点击“开始”即可。你作为部署者,也只需关心后端服务,无需维护复杂的Web服务器和SSL证书(当然,Dashboard部分仍需Web服务)。
  4. 内置身份与隔离:每个Telegram用户ID天然就是一个唯一的用户标识。openShrimp利用这一点,自动为每个新用户创建独立的数据库记录和文件系统工作空间(workspaces/<user_id>/),实现了开箱即用的多用户隔离。

2.3 插件化架构:如何优雅地扩展智能体的能力

一个智能体的能力边界由其工具集决定。openShrimp采用了一种极其轻量级的插件系统,让你可以像搭积木一样为智能体添加新功能。

插件结构剖析: 每个插件就是一个放置在src/plugins/下的文件夹,例如src/plugins/weather/。其核心只有两个文件:

  • manifest.json: 描述插件元信息,如名称、描述、版本。
  • tool.py: 包含用@tool装饰器定义的函数。这些函数就是智能体可以调用的“工具”。

加载机制:应用启动时,会自动扫描src/plugins/目录,加载所有合法插件中的工具,并将其注入到LangGraph智能体的工具列表中。整个过程对核心代码无侵入。

实操示例:快速创建一个“发送邮件”插件

  1. 新建目录:mkdir -p src/plugins/send_email
  2. 创建manifest.json:
    { "name": "send_email", "description": "Tools for sending emails via SMTP.", "version": "1.0.0" }
  3. 创建tool.py:
    import smtplib from email.mime.text import MIMEText from langchain.tools import tool @tool def send_email(to_address: str, subject: str, body: str) -> str: """ Send an email to a specified address. Args: to_address: Recipient email address. subject: Subject of the email. body: Body content of the email. Returns: A confirmation message. """ # 这里应从环境变量或凭证库读取SMTP配置 # 为示例简化,假设已配置 msg = MIMEText(body) msg['Subject'] = subject msg['From'] = 'your_bot@example.com' msg['To'] = to_address with smtplib.SMTP('smtp.example.com', 587) as server: server.starttls() server.login('your_bot@example.com', 'your_password') server.send_message(msg) return f"Email sent successfully to {to_address}"
  4. 重启openShrimp服务,智能体现在就能在任务中决定是否调用send_email这个工具了。

心得:插件化的关键在于工具函数的描述文档(Docstring)。LangGraph的LLM通过阅读这些描述来决定何时调用工具。因此,务必用清晰、准确的语言描述工具的功能、参数和返回值。

3. 从零开始部署与深度配置指南

理解了“为什么”之后,我们来动手“怎么做”。这里将详细拆解自托管openShrimp的每一步,并解释每个配置项背后的意义。

3.1 基础环境搭建与数据库初始化

系统准备:建议使用Linux服务器(Ubuntu 22.04 LTS或类似版本)。确保已安装Dockerdocker-compose,这是运行openShrimp所有组件的最简单方式。

克隆与配置

git clone https://github.com/JustinGuese/openshrimp.git cd openshrimp cp .env.example .env

接下来是配置.env文件,这是整个项目的控制中枢。我们逐一分析关键变量:

核心服务配置

# 数据库配置 DATABASE_URL=postgresql://postgres:your_strong_password@db:5432/openshrimp # 这是Docker Compose网络内的地址。`db`是数据库服务的容器名,`5432`是PostgreSQL默认端口。 # 请务必修改`your_strong_password`为一个高强度的随机密码。 # PGVector扩展:确保向量搜索功能正常。 PGVECTOR_DRIVER=psycopg2

AI模型与OpenRouter配置

# OpenRouter API密钥(获取地址:https://openrouter.ai/keys) OPENROUTER_API_KEY=sk-or-v1-... # 默认模型路由策略 OPENROUTER_MODEL=deepseek/deepseek-v3.2 # 全局后备模型 OPENROUTER_MODEL_QUICK=openai/gpt-oss-120b # “快速”任务模型 OPENROUTER_MODEL_NORMAL=deepseek/deepseek-v3.2 # “普通”任务模型 OPENROUTER_MODEL_DEEP=z-ai/glm-5 # “深度”研究任务模型
  • 模型选择逻辑:智能体会根据你消息中的关键词自动选择模型。例如,你说“快速总结一下”,它会使用更便宜、更快的gpt-oss-120b,并限制工具调用次数为5次。你说“做一个深度市场分析”,则会启用能力更强的glm-5,并给予25次工具调用的预算。这是一种在成本与效果间的智能权衡。

Telegram Bot配置

# 从 @BotFather 获取 TELEGRAM_BOT_TOKEN=1234567890:AAHx7b4z3cD_ExampleToken_5rLk8JmN2oPq DEFAULT_AGENT_USER_ID=1 # 通常留空,系统会自动创建 DASHBOARD_BASE_URL=http://localhost:8000 # 开发时用本地地址,生产环境需改为公网URL

重要提示:DASHBOARD_BASE_URL是Bot生成Dashboard链接的基础。如果你通过docker-compose在本地运行,并想通过Telegram手机App访问Dashboard,你需要使用内网穿透工具(如ngrok、localtunnel)将本地的8000端口暴露为一个公网HTTPS地址,并在此处填写该地址。

3.2 使用Docker Compose一键启动

配置好.env后,启动所有服务变得非常简单:

docker-compose up -d

这个命令会启动定义在docker-compose.yml中的所有服务:

  1. db: 运行PostgreSQL + PGVector的数据库。
  2. browserless: 一个无头Chrome远程服务,供browser插件调用,执行网页交互。
  3. frontend: 提供API和Web Dashboard的FastAPI服务。
  4. agent: 运行LangGraph智能体并与Telegram通信的核心服务。
  5. worker: 处理后台任务(如定时任务、重试)的Celery工作进程。

验证服务是否健康

docker-compose logs --tail=50 agent # 查看智能体服务日志,关注有无报错 curl http://localhost:8000/health # 检查前端API是否就绪

如果一切正常,你现在可以打开Telegram,找到你创建的Bot,发送/start或任何一条消息。你应该能立即收到回复,并且任务系统开始运作。

3.3 核心插件详解与实战配置

openShrimp的强大能力来源于其插件。我们来深入看看几个核心插件如何工作及如何配置。

3.3.1 Browser插件:对抗反爬的智能浏览器

这是智能体的“眼睛和手”。它不仅仅是获取网页HTML,而是能进行点击、输入、提交表单等交互。

# .env 中关于Browserless的配置 BROWSERLESS_ENDPOINT=http://browserless:3000 BROWSERLESS_STEALTH_MODE=true CAPSOLVER_API_KEY=your_capsolver_key_optional
  • pyppeteer-stealth:该库通过一系列技术(如覆盖WebDriver属性、修改插件列表、伪装硬件指纹)让Puppeteer驱动的浏览器看起来更像真人用户。BROWSERLESS_STEALTH_MODE=true即启用此模式。
  • CapSolver集成:对于更顽固的验证码(如Cloudflare Turnstile, reCAPTCHA v2),可以配置CAPSOLVER_API_KEY。当浏览器插件检测到验证码时,会自动调用CapSolver服务进行AI求解。这是一个付费服务,但对于需要登录高防护网站的任务至关重要。
  • 实操技巧:在测试阶段,你可以在Telegram中发送/debug命令开启调试模式。此后,智能体的每一个工具调用(包括浏览器访问的URL、执行的点击操作)都会实时流式发送到你的聊天窗口,极大方便了调试。

3.3.2 凭证保险库与任务调度:实现真正自动化

这是让智能体从“执行单次任务”升级到“管理长期工作流”的关键。

凭证保险库 (credential_vault)

  1. 生成加密密钥
    python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
    将输出的一长串字符设置为环境变量:
    OPENSHRIMP_VAULT_KEY=your_generated_fernet_key_here
  2. 在任务中使用:智能体可以调用get_credential(name)获取存储的密码。一个典型的登录流程是:
    • 智能体尝试访问一个需要登录的网站。
    • 它首先调用get_credential("twitter_login")
    • 如果返回空(即首次使用),则调用ask_human工具向你询问账号密码。
    • 获得你的回复后,立即调用store_credential("twitter_login", "username:password")将其加密存储。
    • 下次执行同类任务时,它就能直接获取凭证登录,无需再打扰你。

任务调度 (task_tracking): 智能体可以在完成任务A之后,自动创建一个未来执行的任务B。例如:

  • “发布这篇博客后,在4小时后检查一下评论和转发量。”
  • “每天上午9点,收集竞争对手官网的新闻动态。” 这是通过在工具函数中调用task_tracking.schedule_followup_task来实现的,底层依赖于数据库中的scheduled_atrepeat_interval_seconds字段,并由后台的worker服务轮询执行。

4. 运维、监控与故障排查实战

将系统跑起来只是第一步,稳定运行才是关键。openShrimp内置了多种机制来保障可靠性,但作为运维者,你需要知道如何观察和干预。

4.1 利用Dashboard进行任务监控

Dashboard是你最重要的运维界面。通过Telegram发送/dashboard获取你的个人链接(格式如http://your-domain/dashboard?token=your_secret_token)。

看板视图:以Trello式的列展示不同状态(待处理、进行中、等待中、完成、失败)的任务卡片。你可以直接拖拽卡片来改变任务状态(例如,将一个失败的任务拖回“待处理”列让其重试)。表格视图:提供所有任务的搜索、筛选和排序。你可以查看每个任务的详细日志、创建时间、最后心跳时间、使用的模型、工具调用次数等。

注意:Dashboard默认是权限隔离的。普通用户只能看到自己的任务。如果你需要管理员视图(查看所有用户任务),需要在.env中设置DASHBOARD_ADMIN_TOKEN为一个强密码,然后在访问Dashboard时使用?token=你的管理员令牌

4.2 理解并处理任务生命周期与异常

一个任务在数据库中的状态流转是理解系统健康度的核心。

正常流程PENDING->IN_PROGRESS->COMPLETED异常情况

  1. 任务卡在IN_PROGRESS

    • 原因:执行任务的agent进程可能意外崩溃(如OOM被杀),未能更新任务状态。
    • 处理:系统有一个“看门狗”机制,由HEARTBEAT_WATCHDOG_MINUTES(默认10分钟)控制。任何IN_PROGRESS的任务,如果超过此时间未收到来自智能体的“心跳”更新,会被自动重置为PENDING,等待其他空闲的工作线程拾取。
    • 排查:在Dashboard中检查该任务的“最后心跳”时间。如果远早于当前时间,说明智能体执行线程已僵死。查看docker-compose logs agent寻找可能的错误(如网络超时、模型API异常)。
  2. 任务进入WAITING_FOR_HUMAN状态

    • 原因:智能体调用了ask_human工具,正在等待你的回复。
    • 处理:直接在Telegram对话中回复即可。智能体线程被阻塞并等待,一旦收到回复,任务会继续执行。
    • 设计保护:为了防止智能体过度询问,有两个限制:a) 一个轻量级LLM评估器会先过滤掉那些明显可以自己搜索到答案的琐碎问题;b) 每个任务有MAX_ASKS_PER_TASK(默认2次)的硬性上限。
  3. 任务失败进入FAILED状态

    • 原因:可能是不可恢复的错误(如访问的网页不存在、API密钥无效、工具函数内部异常)。
    • 处理:Dashboard的表格视图可以点击查看失败任务的详细日志,其中通常包含Python的错误回溯信息,这是排查的第一手资料。
    • 自动重试:对于网络超时、5xx服务器错误等瞬时故障,系统会根据AGENT_MAX_RETRIES(默认2次)进行自动重试,并伴有指数退避延迟,避免加重对方服务器负担。

4.3 日志分析与性能调优

集中查看日志

# 查看所有服务的实时日志 docker-compose logs -f # 仅查看智能体服务的日志,并过滤错误 docker-compose logs agent | grep -i error

关键性能指标

  1. 工具调用延迟:在日志中观察每次工具调用(特别是browser访问网页)的耗时。如果browserless服务响应缓慢,考虑在docker-compose.yml中为其增加CPU和内存资源限制。
  2. LLM API消耗与成本:关注不同“努力程度”任务所使用的模型和调用次数。如果“快速”任务也频繁调用昂贵模型,可以调整.envOPENROUTER_MODEL_QUICK的配置,或优化提示词以减少不必要的思考步骤。
  3. 数据库连接:长时间运行后,检查数据库连接数是否正常。可以在docker-compose.ymldb服务中设置POSTGRES_MAX_CONNECTIONS,并确保应用端有正确的连接池配置。

5. 高级应用场景与定制化开发

当基础功能稳定运行后,你可以根据自身需求,将openShrimp定制成更强大的专属自动化助手。

5.1 构建垂直领域的研究助手

假设你是一个风险投资分析师,需要每天追踪数十家初创公司的动态。

  1. 创建专用插件:开发一个src/plugins/vc_research/插件,其中包含fetch_crunchbase(company_name),monitor_news(keywords),analyze_funding_trends(industry)等工具。
  2. 配置定时任务:在项目初始化时,或通过一个管理命令,创建一系列定时任务。例如,每天上午10点执行“监控我投资组合中所有公司的新闻”任务。
  3. 优化记忆与输出:配置memory_rag插件,让它将每天抓取到的新闻摘要存入向量库。当你下周问“某公司最近有什么技术突破?”时,智能体会先检索长期记忆,再结合实时搜索给出答案。你还可以定制输出格式,让它最终生成一份结构化的Word或PDF日报,并通过filesystem插件保存,甚至通过send_email插件发送给你。

5.2 集成外部系统与API

openShrimp的智能体可以成为你企业工作流的“胶水”。

  • 与项目管理工具集成:创建一个jiralinear插件,让智能体能够根据对话内容自动创建工单、更新状态或添加评论。
  • 与数据仓库交互:创建一个bigquery插件,赋予智能体编写SQL查询、获取业务数据并进行分析的能力。
  • 触发外部自动化:通过调用webhook工具,在任务完成时触发一个Zapier或Make的流程,从而连接起成千上万的其他SaaS服务。

开发外部API插件的要点

  1. 安全性:API密钥务必通过credential_vault管理,切勿硬编码在插件中。
  2. 错误处理:在tool.py的函数中做好全面的异常捕获和日志记录,返回清晰的错误信息给智能体,以便它决定重试或转为ask_human
  3. 速率限制:对于有调用限制的外部API,需要在插件内部实现简单的限流逻辑,或利用任务调度将密集操作分散到不同时间执行。

5.3 模型路由与提示词工程优化

openShrimp默认的“努力程度”路由是基于关键词的简单启发式方法。你可以根据你的使用模式进行优化。

自定义路由规则:你可以修改agent服务中检测努力程度的逻辑。例如,对于来自特定用户或特定项目的所有任务,都默认使用“深度”模型。或者,根据消息的长度来判断复杂度。

优化系统提示词:系统提示词定义了智能体的“性格”和任务边界。它位于LangGraph智能体的构建代码中。你可以调整它来:

  • 强调领域知识:“你是一名专业的网络安全分析师,你的回答应聚焦于漏洞、攻击向量和缓解措施...”
  • 约束输出格式:“请始终以Markdown表格的形式总结你的发现,包含‘来源’、‘关键点’、‘置信度’三列。”
  • 控制工具使用偏好:“在尝试使用browser插件登录网站前,务必先检查credential_vault中是否已有保存的凭证。”

经过这些深度定制,openShrimp将从一个通用的研究助手,蜕变为嵌入到你日常工作流中的、高度专业化的智能协作伙伴。它的价值不再仅仅是“回答问题”,而是持续、可靠、自主地帮你完成那些繁琐、重复但需要一定智能判断的数字化工作。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询