Commit 702ba3aa74f87be1d98dd0b5b0cc3812ea7bbbaa

Authored by tangwang
1 parent 8dcb1dc0

readme

Showing 1 changed file with 126 additions and 89 deletions   Show diff stats
1 # ShopAgent 1 # ShopAgent
2 2
3 -An autonomous multi-modal fashion shopping agent powered by **LangGraph** and **ReAct pattern**. 3 +基于 **LangGraph** 与 **ReAct 模式** 的自主多模态时尚购物智能体,支持文本与图片输入、商品搜索、风格分析与多轮对话。
4 4
5 ## Demo 5 ## Demo
6 6
7 -📄 **[demo.pdf](./demo.pdf)**  
8 -  
9 -## Overview  
10 -  
11 -ShopAgent autonomously decides which tools to call, maintains conversation state, and determines when to respond. Built with **LangGraph**, it uses agentic patterns for intelligent product discovery.  
12 -  
13 -**Key Features:**  
14 -- Autonomous tool selection and execution  
15 -- Text search via Search API  
16 -- Conversational context awareness  
17 -- Real-time visual analysis (style extraction from images)  
18 -  
19 -## Tech Stack  
20 -  
21 -| Component | Technology |  
22 -|-----------|-----------|  
23 -| **Agent Framework** | LangGraph |  
24 -| **LLM** | any LLM supported by LangChain |  
25 -| **Search** | Search API (HTTP) |  
26 -| **Frontend** | Streamlit |  
27 -| **Dataset** | Kaggle Fashion Products |  
28 -  
29 -## Architecture  
30 -  
31 -**Agent Flow:**  
32 -  
33 -```mermaid  
34 -graph LR  
35 - START --> Agent  
36 - Agent -->|Has tool_calls| Tools  
37 - Agent -->|No tool_calls| END  
38 - Tools --> Agent  
39 -  
40 - subgraph "Agent Node"  
41 - A[Receive Messages] --> B[LLM Reasoning]  
42 - B --> C{Need Tools?}  
43 - C -->|Yes| D[Generate tool_calls]  
44 - C -->|No| E[Generate Response]  
45 - end  
46 -  
47 - subgraph "Tool Node"  
48 - F[Execute Tools] --> G[Return ToolMessage]  
49 - end  
50 -``` 7 +http://120.76.41.98:6008/
  8 +
  9 +
  10 +## 概述
  11 +
  12 +ShopAgent 根据用户意图自主决定是否调用工具、调用哪些工具,维护对话状态,并在适当时机给出回复。核心能力包括:
51 13
52 -**Available Tools:**  
53 -- `search_products(query)` - Text-based product search via Search API  
54 -- `analyze_image_style(image_path)` - VLM style analysis 14 +- **自主工具选择与执行**:按需调用 `search_products`、`analyze_image_style`、`web_search`
  15 +- **商品搜索**:通过外部 Search API 检索,结果经 LLM 质量评估后写入会话级结果库,回复中通过 `[SEARCH_RESULTS_REF:ref_id]` 引用,前端自动渲染为商品卡片
  16 +- **多轮对话与上下文**:LangGraph + MemorySaver 按 `thread_id` 持久化消息
  17 +- **图片理解**:上传图片时可调用 `analyze_image_style` 做风格/属性分析,再结合搜索
  18 +- **流式输出**:思考过程、工具调用与结果、正式回复以前端可感知的事件流实时展示,调试面板默认展开
55 19
  20 +## 技术栈
56 21
  22 +| 组件 | 技术 |
  23 +|------------|------|
  24 +| Agent 框架 | LangGraph(StateGraph + ReAct) |
  25 +| LLM | LangChain OpenAI 兼容(默认 gpt-4o-mini,可配 base_url 如 DashScope) |
  26 +| 推理/思考 | 可选:OpenAI Responses API reasoning / DashScope enable_thinking |
  27 +| 搜索 | 外部 Search API(HTTP),会话内结果登记到 SearchResultRegistry |
  28 +| 前端 | Streamlit |
57 29
58 -## Examples 30 +## 架构要点
  31 +
  32 +### Agent 流程(LangGraph)
59 33
60 -**Text Search:**  
61 ``` 34 ```
62 -User: "winter coats for women"  
63 -Agent: search_products("winter coats women") → Returns 5 products 35 +START → Agent → [有 tool_calls?] → Tools → Agent → … → END
64 ``` 36 ```
65 37
66 -**Style Analysis + Search:** 38 +- **Agent 节点**:注入 system prompt,调用 `llm_with_tools.invoke(messages)`,产出 AIMessage(含 content 和/或 tool_calls)。
  39 +- **条件边**:若最后一条消息含 `tool_calls` 则进入 **Tools** 节点,否则结束。
  40 +- **Tools 节点**:执行本轮工具调用,将 ToolMessage 追加到 state,再次回到 Agent。
  41 +- **状态**:`AgentState = { messages, current_image_path }`,`messages` 使用 `add_messages` 累加。
  42 +
  43 +### 搜索结果与引用
  44 +
  45 +- **SearchResultRegistry**:按会话存储每次 `search_products` 的结构化结果(query、质量统计、商品列表),并为每次搜索分配会话内唯一 `ref_id`(如 `sr_1`, `sr_2`)。
  46 +- **search_products 工具**:请求 Search API → 用 LLM 对每条结果打标(Relevant / Partially Relevant / Irrelevant)→ 将结果写入 registry,返回包含 `[SEARCH_RESULTS_REF:ref_id]` 的文本及质量摘要。
  47 +- **最终回复**:Agent 在正文中写入 `[SEARCH_RESULTS_REF:ref_id]`,前端用正则解析并在对应位置渲染商品卡片(见 `app.py` 中 `SEARCH_RESULTS_REF_PATTERN` 与 `render_message_with_refs`)。
  48 +
  49 +### 工具列表
  50 +
  51 +| 工具 | 说明 |
  52 +|------|------|
  53 +| `search_products(query)` | 文本商品搜索,会话绑定,结果写入 Registry 并返回 ref 引用 |
  54 +| `analyze_image_style(image_path)` | VLM 分析图片风格/属性,供后续搜索或回复使用 |
  55 +| `web_search(query)` | 联网检索(如时效、天气、事件等) |
  56 +
  57 +### 流式与调试
  58 +
  59 +- **chat_stream**:`ShoppingAgent.chat_stream(query, image_path)` 迭代产出事件:`debug_update`(思考步骤、工具调用/结果)、`response_delta` / `response_replace`(正式回复增量)、`done`(最终结果)。
  60 +- **前端**:发送消息后消费 `chat_stream`,在占位区实时更新工具链、调试步骤和回复;调试面板「思考 & 工具调用详细过程」默认展开,可展示 thinking 与工具结果。
  61 +- **chat**:仍保留 `chat()`,内部改为消费 `chat_stream` 直至 `done`,保证兼容。
  62 +
  63 +## 示例
  64 +
  65 +**文本搜索:**
67 ``` 66 ```
68 -User: [uploads vintage jacket] "what style is this? find matching pants"  
69 -Agent: analyze_image_style(path) → "Vintage denim bomber..."  
70 - search_products("vintage pants casual") → Returns matching items 67 +用户:「有没有适合通勤的女式大衣」
  68 +Agent:search_products("通勤 女式 大衣") → 返回 [SEARCH_RESULTS_REF:sr_1],页面展示商品卡片
71 ``` 69 ```
72 70
73 -**Multi-turn Context:** 71 +**图片 + 搜索:**
74 ``` 72 ```
75 -Turn 1: "show me red dresses"  
76 -Agent: search_products("red dresses") → Results  
77 -  
78 -Turn 2: "make them formal"  
79 -Agent: [remembers context] → search_products("red formal dresses") → Results 73 +用户:[上传一张外套图] 「这件是什么风格?找类似款」
  74 +Agent:analyze_image_style(path) → 得到风格描述 → search_products("…") → 引用 sr_1 等
80 ``` 75 ```
81 76
82 -**Complex Reasoning:** 77 +**多轮与引用:**
  78 +```
  79 +第1轮:「红色连衣裙」→ search_products → 展示结果
  80 +第2轮:「要正式一点的」→ 结合上下文 search_products("红色 正式 连衣裙")
83 ``` 81 ```
84 -User: [uploads office outfit] "I like the shirt but need something more casual"  
85 -Agent: analyze_image_style(path) → Extracts shirt details  
86 - search_products("casual shirt [color] [style]") → Returns casual alternatives  
87 82
88 -**Note:** For image uploads "find similar", use analyze_image_style first to extract attributes, then search_products with the description. 83 +**时效类(web_search):**
89 ``` 84 ```
  85 +用户:「最近有什么流行元素」
  86 +Agent:web_search("时尚 流行 2025") → 结合结果回复
  87 +```
  88 +
  89 +## 安装与运行
90 90
91 -## Installation 91 +### 环境要求
92 92
93 -**Prerequisites:**  
94 -- Python 3.12+ (LangChain 1.x 要求 Python 3.10+)  
95 -- OpenAI API Key 93 +- Python 3.10+(LangChain/LangGraph 推荐 3.12+)
  94 +- 配置 `.env`:至少 `OPENAI_API_KEY`;若用自建或第三方 LLM,可设 `OPENAI_API_BASE_URL`(如 DashScope 兼容地址)
  95 +
  96 +### 步骤
96 97
97 -### 1. Setup Environment  
98 ```bash 98 ```bash
99 -# Clone and install dependencies  
100 git clone <repository-url> 99 git clone <repository-url>
101 -cd ShopAgent 100 +cd shop_agent
102 python -m venv venv 101 python -m venv venv
103 -source venv/bin/activate # Windows: venv\Scripts\activate 102 +source venv/bin/activate # Windows: venv\Scripts\activate
104 pip install -r requirements.txt 103 pip install -r requirements.txt
105 104
106 -# Configure environment variables 105 +# 配置
107 cp .env.example .env 106 cp .env.example .env
108 -# Edit .env and add your OPENAI_API_KEY 107 +# 编辑 .env:OPENAI_API_KEY、可选 OPENAI_API_BASE_URL、SEARCH_API_BASE_URL、SEARCH_API_TENANT_ID 等
109 ``` 108 ```
110 109
111 -### 2. (Optional) Download Dataset  
112 -For image style analysis, you may download the [Fashion Product Images Dataset](https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset) from Kaggle: 110 +### 可选:本地图片数据
113 111
114 -```bash  
115 -python scripts/download_dataset.py  
116 -``` 112 +若需本地商品图(如侧边栏「Similar」用本地图),可准备 `data/images/` 下的图片资源;图像风格分析不依赖该目录。
  113 +
  114 +### 启动
117 115
118 -### 3. Launch Application  
119 ```bash 116 ```bash
120 -# 使用启动脚本(推荐) 117 +# 推荐
121 ./scripts/start.sh 118 ./scripts/start.sh
122 119
123 -# 或直接运行 120 +# 或
124 streamlit run app.py 121 streamlit run app.py
125 ``` 122 ```
126 123
127 -Product search uses the external Search API. Configure `SEARCH_API_BASE_URL` and `SEARCH_API_TENANT_ID` in `.env` if needed. 124 +默认访问 `http://localhost:8501`。商品搜索依赖外部 Search API,请在 `.env` 中配置 `SEARCH_API_BASE_URL` 与 `SEARCH_API_TENANT_ID`。
  125 +
  126 +### 部署
  127 +
  128 +CentOS 8 等部署说明见 **[docs/DEPLOY_CENTOS8.md](docs/DEPLOY_CENTOS8.md)**(若存在)。
  129 +
  130 +## 配置说明(.env 摘要)
  131 +
  132 +| 变量 | 说明 | 默认 |
  133 +|------|------|------|
  134 +| `OPENAI_API_KEY` | 必填,LLM/视觉调用 | - |
  135 +| `OPENAI_API_BASE_URL` | 可选,兼容接口 base URL(如 DashScope) | - |
  136 +| `OPENAI_MODEL` | 对话模型 | gpt-4o-mini |
  137 +| `OPENAI_USE_REASONING` | 是否开启思考(OpenAI/DashScope 等) | true |
  138 +| `OPENAI_REASONING_EFFORT` | reasoning 力度(如 medium) | medium |
  139 +| `SEARCH_API_BASE_URL` | 搜索服务地址 | 见 config.py |
  140 +| `SEARCH_API_TENANT_ID` | 租户 ID | 见 config.py |
  141 +| `SEARCH_PRODUCTS_LIMIT` | 单次搜索返回条数上限 | 20 |
  142 +
  143 +更多见 `app/config.py`。
  144 +
  145 +## 项目结构(概览)
  146 +
  147 +```
  148 +shop_agent/
  149 +├── app/
  150 +│ ├── agents/
  151 +│ │ └── shopping_agent.py # LangGraph 图、chat/chat_stream、thinking 支持
  152 +│ ├── config.py # 配置与环境变量
  153 +│ ├── search_registry.py # SearchResultRegistry、ProductItem、SearchResult
  154 +│ ├── tools/
  155 +│ │ ├── search_tools.py # search_products、analyze_image_style、web_search
  156 +│ │ └── __init__.py
  157 +│ └── ...
  158 +├── app.py # Streamlit UI、流式渲染、引用解析与商品卡片
  159 +├── docs/
  160 +│ └── 技术实现报告.md # 详细设计与实现说明
  161 +├── scripts/
  162 +│ └── start.sh
  163 +├── .env.example
  164 +├── requirements.txt
  165 +└── README.md
  166 +```
128 167
129 -Opens at `http://localhost:8501` 168 +---
130 169
131 -### CentOS 8 部署  
132 -详见 [docs/DEPLOY_CENTOS8.md](docs/DEPLOY_CENTOS8.md)