08-智能体开发实战指南(八):UI 集成与生产部署

Agent 智能体开发实战指南(八):UI 集成与生产部署

系列导读:这是《Agent 智能体开发实战指南》系列的最终篇,将讲解如何将 Agent 集成到用户界面,以及生产环境的部署策略、性能优化和最佳实践。


一、Streamlit 快速入门

1.1 为什么选择 Streamlit?

特性 说明
快速开发 几十行代码就能搭建交互式 UI
Python 原生 无需学习前端技术
自动刷新 状态变化自动重新渲染
内置组件 聊天界面、文件上传、图表等
适合演示 快速原型、内部工具、Demo 展示

1.2 最小可用示例

python 复制代码
# app.py
import streamlit as st

st.title("我的第一个 Streamlit 应用")
name = st.text_input("请输入你的名字")
if name:
    st.write(f"你好,{name}!")
bash 复制代码
# 运行
streamlit run app.py

二、完整的 Agent 聊天界面

2.1 核心代码

python 复制代码
import time
import streamlit as st
from agent.react_agent import ReactAgent

# 页面配置
st.set_page_config(
    page_title="智扫通智能客服",
    page_icon="🤖",
    layout="wide"
)

# 标题
st.title("🤖 智扫通机器人智能客服")
st.divider()

# 初始化 Agent(单例模式)
if "agent" not in st.session_state:
    st.session_state["agent"] = ReactAgent()

# 初始化消息历史
if "messages" not in st.session_state:
    st.session_state["messages"] = []

# 显示历史消息
for message in st.session_state["messages"]:
    with st.chat_message(message["role"]):
        st.write(message["content"])

# 用户输入
prompt = st.chat_input("请问有什么可以帮您?")

if prompt:
    # 显示用户消息
    st.chat_message("user").write(prompt)
    st.session_state["messages"].append({
        "role": "user", 
        "content": prompt
    })
    
    # 生成回复
    response_messages = []
    with st.spinner("智能客服思考中..."):
        res_stream = st.session_state["agent"].execute_stream(prompt)
        
        # 流式显示(打字机效果)
        def capture(generator, cache_list):
            for chunk in generator:
                cache_list.append(chunk)
                # 逐字输出,模拟打字机
                for char in chunk:
                    time.sleep(0.01)
                    yield char
        
        # 显示助手回复
        with st.chat_message("assistant"):
            response = st.write_stream(
                capture(res_stream, response_messages)
            )
        
        # 保存回复到历史
        st.session_state["messages"].append({
            "role": "assistant",
            "content": response_messages[-1] if response_messages else response
        })
        
        # 刷新页面
        st.rerun()

2.2 关键组件说明

组件 作用
st.set_page_config() 页面配置(标题、图标、布局)
st.title() 页面标题
st.divider() 分割线
st.session_state 会话状态存储
st.chat_message() 聊天消息气泡
st.chat_input() 聊天输入框
st.spinner() 加载动画
st.write_stream() 流式输出
st.rerun() 重新渲染页面

2.3 Session State 管理

python 复制代码
# 为什么需要 session_state?
# Streamlit 每次交互都会重新运行整个脚本
# session_state 用于在多次运行之间保持状态

# 初始化(只运行一次)
if "agent" not in st.session_state:
    st.session_state["agent"] = ReactAgent()

# 后续运行会复用已创建的实例
agent = st.session_state["agent"]  # 不会重新创建

# 消息历史同理
if "messages" not in st.session_state:
    st.session_state["messages"] = []

# 添加消息
st.session_state["messages"].append({"role": "user", "content": prompt})

三、Agent 流式执行封装

3.1 ReactAgent 类实现

python 复制代码
# agent/react_agent.py
from langchain.agents import create_agent
from model.factory import chat_model
from utils.prompt_loader import load_system_prompts
from agent.tools.agent_tools import (
    rag_summarize, get_weather, get_user_location, 
    get_user_id, get_current_month, 
    fetch_external_data, fill_context_for_report
)
from agent.tools.middleware import (
    monitor_tool, log_before_model, report_prompt_switch
)

class ReactAgent:
    def __init__(self):
        """初始化 Agent"""
        self.agent = create_agent(
            model=chat_model,
            system_prompt=load_system_prompts(),
            tools=[
                rag_summarize, get_weather, get_user_location,
                get_user_id, get_current_month,
                fetch_external_data, fill_context_for_report
            ],
            middleware=[
                monitor_tool, log_before_model, report_prompt_switch
            ],
        )
    
    def execute_stream(self, query: str):
        """
        流式执行 Agent
        
        参数:
        - query: 用户问题
        
        返回:
        - 生成器,逐块输出 Agent 响应
        """
        # 组装输入
        input_dict = {
            "messages": [
                {"role": "user", "content": query},
            ]
        }
        
        # 流式执行
        # context={"report": False} 初始化为非报告场景
        for chunk in self.agent.stream(
            input_dict, 
            stream_mode="values", 
            context={"report": False}
        ):
            latest_message = chunk["messages"][-1]
            if latest_message.content:
                yield latest_message.content.strip() + "\n"

3.2 流式处理要点

python 复制代码
# 1. 使用 stream_mode="values" 获取完整状态
for chunk in agent.stream(input_dict, stream_mode="values"):
    # 2. 获取最新消息
    latest_message = chunk["messages"][-1]
    
    # 3. 提取内容
    if latest_message.content:
        yield latest_message.content

# 4. 在 UI 层逐字显示
def capture(generator, cache_list):
    for chunk in generator:
        cache_list.append(chunk)  # 保存完整内容
        for char in chunk:        # 逐字输出
            time.sleep(0.01)      # 打字机延迟
            yield char

四、生产环境部署

4.1 部署方案对比

方案 适用场景 优点 缺点
本地运行 开发测试 简单快速 无法对外服务
Streamlit Cloud 公开 Demo 免费、易部署 资源有限、国内访问慢
Docker 容器 生产环境 隔离、可移植 需要容器化知识
云服务器 生产环境 可控、高性能 成本较高
内网部署 企业内网 安全、私有 需要内网环境

4.2 Docker 部署方案

Dockerfile

dockerfile 复制代码
FROM python:3.11-slim

WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制项目文件
COPY . .

# 暴露端口
EXPOSE 8501

# 启动命令
CMD ["streamlit", "run", "app.py", "--server.port=8501", "--server.address=0.0.0.0"]

构建和运行

bash 复制代码
# 构建镜像
docker build -t zhisaotong-agent .

# 运行容器
docker run -d -p 8501:8501 \
    -v $(pwd)/data:/app/data \
    -v $(pwd)/logs:/app/logs \
    --name agent-app \
    zhisaotong-agent

# 查看日志
docker logs -f agent-app

# 停止容器
docker stop agent-app

4.3 云服务器部署(以 Ubuntu 为例)

1. 环境准备

bash 复制代码
# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装 Python
sudo apt install -y python3.11 python3.11-venv python3-pip

# 安装 Git
sudo apt install -y git

# 创建用户
sudo useradd -m agent-user
sudo passwd agent-user

2. 项目部署

bash 复制代码
# 切换到用户
sudo su - agent-user

# 克隆项目
git clone https://github.com/your-repo/zhisaotong-agent.git
cd zhisaotong-agent

# 创建虚拟环境
python3.11 -m venv venv
source venv/bin/activate

# 安装依赖
pip install -r requirements.txt

# 配置环境变量
cp .env.example .env
# 编辑 .env 文件,填入 API 密钥等

3. 后台运行

bash 复制代码
# 使用 nohup
nohup streamlit run app.py --server.port=8501 --server.address=0.0.0.0 > app.log 2>&1 &

# 或使用 systemd 服务
sudo nano /etc/systemd/system/agent-app.service

systemd 服务配置

ini 复制代码
[Unit]
Description=Zhisaotong Agent App
After=network.target

[Service]
Type=simple
User=agent-user
WorkingDirectory=/home/agent-user/zhisaotong-agent
Environment="PATH=/home/agent-user/zhisaotong-agent/venv/bin"
ExecStart=/home/agent-user/zhisaotong-agent/venv/bin/streamlit run app.py --server.port=8501 --server.address=0.0.0.0
Restart=always

[Install]
WantedBy=multi-user.target
bash 复制代码
# 启动服务
sudo systemctl daemon-reload
sudo systemctl enable agent-app
sudo systemctl start agent-app

# 查看状态
sudo systemctl status agent-app

4. Nginx 反向代理

nginx 复制代码
server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:8501;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # WebSocket 支持(Streamlit 需要)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

五、性能优化建议

5.1 Agent 层面

1. 限制最大迭代次数

python 复制代码
agent = create_agent(
    model=chat_model,
    tools=tools,
    max_iterations=10,  # 防止无限循环
)

2. 设置超时

python 复制代码
for chunk in agent.stream(
    input_dict,
    stream_mode="values",
    config={"timeout": 30}  # 30 秒超时
):
    yield chunk

3. 缓存工具结果

python 复制代码
from functools import lru_cache

@lru_cache(maxsize=100)
def cached_tool_call(tool_name: str, args: str) -> str:
    # 缓存工具调用结果
    pass

5.2 向量检索层面

1. 限制检索数量

yaml 复制代码
# config/chroma.yml
k: 3  # 只检索最相关的 3 条

2. 使用元数据过滤

python 复制代码
retriever = vector_store.as_retriever(
    search_kwargs={
        "k": 3,
        "filter": {"category": "故障排除"}
    }
)

3. 定期清理向量库

python 复制代码
# 删除旧数据
vector_store.delete_collection()
# 重新加载
vector_store.load_document()

5.3 Streamlit 层面

1. 使用缓存装饰器

python 复制代码
@st.cache_resource
def get_agent():
    """Agent 实例缓存,避免重复创建"""
    return ReactAgent()

agent = get_agent()

2. 优化大文件加载

python 复制代码
@st.cache_data
def load_knowledge_base():
    """知识库加载缓存"""
    vs = VectorStoreService()
    vs.load_document()
    return vs

3. 减少不必要的重新渲染

python 复制代码
# 使用 session_state 避免重复计算
if "result" not in st.session_state:
    st.session_state["result"] = expensive_computation()

result = st.session_state["result"]

六、监控与日志

6.1 应用监控

python 复制代码
# middleware/monitoring.py
import time
from collections import defaultdict
from utils.logger_handler import logger

# 统计指标
metrics = defaultdict(lambda: {
    "count": 0,
    "total_time": 0,
    "errors": 0
})

@wrap_tool_call
def monitor_performance(request, handler):
    """性能监控中间件"""
    tool_name = request.tool_call['name']
    start = time.time()
    
    try:
        result = handler(request)
        return result
    except Exception as e:
        metrics[tool_name]["errors"] += 1
        raise
    finally:
        duration = time.time() - start
        metrics[tool_name]["count"] += 1
        metrics[tool_name]["total_time"] += duration
        
        avg_time = (
            metrics[tool_name]["total_time"] / 
            metrics[tool_name]["count"]
        )
        
        logger.info(
            f"工具{tool_name}: "
            f"调用{metrics[tool_name]['count']}次,"
            f"平均耗时{avg_time:.2f}s, "
            f"错误{metrics[tool_name]['errors']}次"
        )

6.2 日志轮转

python 复制代码
# utils/logger_handler.py
from logging.handlers import RotatingFileHandler

def get_logger_with_rotation(name: str = "agent"):
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    
    # 轮转文件 Handler
    # 每个文件最大 10MB,保留 5 个备份
    file_handler = RotatingFileHandler(
        f"logs/{name}.log",
        maxBytes=10*1024*1024,
        backupCount=5
    )
    file_handler.setFormatter(DEFAULT_LOG_FORMAT)
    logger.addHandler(file_handler)
    
    return logger

七、安全最佳实践

7.1 敏感信息管理

错误:硬编码密钥

python 复制代码
# 不要这样做!
API_KEY = "sk-abc123xyz"

正确:环境变量

python 复制代码
# .env 文件(加入 .gitignore)
DASHSCOPE_API_KEY=sk-abc123xyz
CHROMA_PERSIST_PATH=/secure/path

# 代码中读取
import os
from dotenv import load_dotenv

load_dotenv()
API_KEY = os.getenv("DASHSCOPE_API_KEY")

7.2 输入验证

python 复制代码
@tool(description="查询天气")
def get_weather(city: str) -> str:
    # 输入验证
    if not city or len(city) > 50:
        return "无效的城市名称"
    
    # 防止注入
    city = city.strip()
    city = ''.join(c for c in city if c.isalnum() or c in '中国省市自治区')
    
    return query_weather_api(city)

7.3 权限控制

python 复制代码
@wrap_tool_call
def check_permission(request, handler):
    """权限检查中间件"""
    sensitive_tools = ["delete_user", "export_data", "admin_command"]
    
    if request.tool_call['name'] in sensitive_tools:
        user_role = request.runtime.context.get("user_role", "guest")
        if user_role != "admin":
            logger.warning(f"非管理员尝试调用敏感工具")
            raise PermissionError("无权执行此操作")
    
    return handler(request)

八、系列总结

8.1 知识回顾

篇序 主题 核心收获
01 Agent 基础概念 理解 Agent 与 Chain 的区别
02 工具调用系统 掌握@tool 装饰器和工具设计
03 ReAct 框架详解 学会思考 - 行动 - 观察循环
04 流式输出与调试 理解 stream_mode 各种模式
05 中间件系统 掌握 Hooks 和动态提示词
06 RAG 与向量存储 实现知识库检索增强
07 项目架构设计 学习工程化实践
08 UI 集成与部署 完成从开发到部署

8.2 进阶方向

1. 多 Agent 协作

python 复制代码
# 多个 Agent 协同完成复杂任务
researcher_agent = create_agent(...)
writer_agent = create_agent(...)
reviewer_agent = create_agent(...)

# 工作流:研究 → 写作 → 审核

2. 记忆系统

python 复制代码
# 长期记忆存储
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

3. 评估与优化

python 复制代码
# 使用 LangSmith 等平台进行 Agent 评估
# 追踪每次执行的完整链路
# 分析工具调用准确率

4. 更多工具集成

  • 数据库查询工具
  • API 调用工具
  • 代码执行工具
  • 文件操作工具

九、结语

恭喜你完成了《Agent 智能体开发实战指南》全系列!

从最基础的 Agent 概念,到完整的项目部署,你已经掌握了:

  • Agent 的核心架构和工作原理
  • 工具调用系统的设计与实现
  • ReAct 框架的多步推理能力
  • 流式输出与状态管理
  • 中间件系统的高级应用
  • RAG 与向量存储的集成
  • 工程化的项目架构设计
  • 生产环境的部署与优化

但这只是开始。Agent 技术正在快速发展,新的框架、工具和最佳实践不断涌现。保持学习,持续实践,你一定能构建出更强大的智能应用。

最后的建议

  1. 动手实践:教程看十遍不如动手做一遍
  2. 从小开始:先做一个简单的 Agent,再逐步扩展
  3. 记录问题:遇到的每个问题都是学习机会

祝你在 Agent 开发的道路上越走越远!


  1. Agent 智能体开发实战指南(一):从 LLM 到 Agent 的认知升级
  2. Agent 智能体开发实战指南(二):工具调用系统深度解析
  3. Agent 智能体开发实战指南(三):ReAct 框架深度解析
  4. Agent 智能体开发实战指南(四):流式输出与状态管理
  5. Agent 智能体开发实战指南(五):中间件系统与动态提示词
  6. Agent 智能体开发实战指南(六):RAG 与向量存储实战
  7. Agent 智能体开发实战指南(七):项目架构设计与工程化实践
  8. Agent 智能体开发实战指南(八):UI 集成与生产部署(本文)
相关推荐
美酒没故事°18 小时前
Open WebUI安装指南。搭建自己的自托管 AI 平台
人工智能·windows·ai
云烟成雨TD18 小时前
Spring AI Alibaba 1.x 系列【6】ReactAgent 同步执行 & 流式执行
java·人工智能·spring
Csvn18 小时前
🌟 LangChain 30 天保姆级教程 · Day 13|OutputParser 进阶!让 AI 输出自动转为结构化对象,并支持自动重试!
python·langchain
AI攻城狮19 小时前
用 Obsidian CLI + LLM 构建本地 RAG:让你的笔记真正「活」起来
人工智能·云原生·aigc
鸿乃江边鸟19 小时前
Nanobot 从onboard启动命令来看个人助理Agent的实现
人工智能·ai
lpfasd12319 小时前
基于Cloudflare生态的应用部署与开发全解
人工智能·agent·cloudflare
俞凡19 小时前
DevOps 2.0:智能体如何接管故障修复和基础设施维护
人工智能
comedate19 小时前
[OpenClaw] GLM 5 关于电影 - 人工智能 - 的思考
人工智能·电影评价
财迅通Ai19 小时前
6000万吨产能承压 卫星化学迎来战略窗口期
大数据·人工智能·物联网·卫星化学
liliangcsdn19 小时前
Agent Memory智能体记忆系统的示例分析
数据库·人工智能·全文检索