# LangSmith 集成设计文档

**日期**: 2026-03-20
**状态**: 设计中
**范围**: 后端 LangGraph Agent 追踪

---

## 1. 背景与目标

Jarvis 后端基于 LangGraph 构建了多智能体系统（Master/Planner/Executor/Librarian/Analyst），目前没有可观测性能力。

本次集成目标：
1. **调用追踪** — 在 LangSmith Dashboard 查看完整的 Agent 执行轨迹
2. **对话历史管理** — 按 run_id 聚合对话，自动存储到 LangSmith
3. **评估支持** — 积累的对话数据可用于 LangSmith Evaluation

---

## 2. 集成方案（方案 A：最小集成）

### 2.1 核心思路

LangGraph 内置对 LangSmith 的支持，只需三步即可完成集成：

1. 在 `.env` 中配置 LangSmith 环境变量
2. 在 `pyproject.toml` 中添加 `langsmith` 为直接依赖
3. 在 `llm_service.py` 中为 LLM 调用注入 LangSmith Callback

LangGraph 的 `compile()` 会自动将 Callback 传递到所有节点，无需修改 `graph.py`。

### 2.2 环境变量

在 `backend/.env.example` 中新增：

```env
# LangSmith Tracing
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=your-langsmith-api-key
LANGSMITH_PROJECT=jarvis-agent
```

### 2.3 依赖

在 `backend/pyproject.toml` 的 `dependencies` 中添加：

```toml
"langsmith>=0.1.0",
```

### 2.4 配置类变更

在 `backend/app/config.py` 中新增配置字段：

```python
# LangSmith
LANGSMITH_TRACING: bool = False
LANGSMITH_API_KEY: str = ""
LANGSMITH_PROJECT: str = "jarvis-agent"
```

### 2.5 实现变更

#### 2.5.1 Config 层

在 `backend/app/config.py` 中新增配置字段：

```python
LANGSMITH_TRACING: bool = False
LANGSMITH_API_KEY: str = ""
LANGSMITH_PROJECT: str = "jarvis-agent"
```

创建 `backend/app/config_tracing.py` 作为独立的 callback 工厂模块：

```python
from langchain_core.callbacks import LangChainTracer
from app.config import settings

def get_langsmith_callbacks() -> list:
    if not settings.LANGSMITH_TRACING or not settings.LANGSMITH_API_KEY:
        return []
    return [LangChainTracer(project_name=settings.LANGSMITH_PROJECT)]
```

#### 2.5.2 Graph 层

在 `backend/app/agents/graph.py` 中：

1. `create_agent_graph()` 新增 `callbacks` 参数，透传给 `graph.compile(callbacks=...)`
2. `get_agent_graph()` 内部调用 `get_langsmith_callbacks()` 并与传入参数合并后传给 `create_agent_graph()`

LangGraph 的 `compile(callbacks=...)` 会自动将 callbacks 传播到所有节点的 LLM 调用，覆盖 Master/Planner/Executor/Librarian/Analyst 全部 5 个节点。

### 2.6 Streaming 兼容性

当前 streaming 通过 `graph.astream_events()` 实现。LangSmith Callback 会异步记录追踪数据，不影响流式输出的实时性。

如果需要在 streaming 过程中实时展示 trace URL，可以在 `on_chat_model_end` 事件中从 `run.id` 生成链接：

```python
async for event in graph.astream_events(...):
    if event["event"] == "on_chat_model_end":
        run_id = event["data"]["output"].id  # 从 response 中获取 run_id
        trace_url = f"https://smith.langchain.com/runs/{run_id}"
```

---

## 3. 文件变更清单

| 文件 | 变更类型 |
|---|---|
| `backend/.env.example` | 新增 3 行环境变量 |
| `backend/pyproject.toml` | 新增 langsmith 依赖 |
| `backend/app/config.py` | 新增 3 个配置字段 |
| `backend/app/config_tracing.py` | 新建，callback 工厂函数 |
| `backend/app/agents/graph.py` | `create_agent_graph`/`get_agent_graph` 支持 callbacks |
| `backend/app/services/agent_service.py` | `get_agent_graph()` 调用签名对齐 |

---

## 4. 风险与限制

- LangSmith 免费版有追踪数量限制（详见 LangSmith 定价）
- Streaming 模式下 trace 数据在调用结束后才完整展示
- 需要用户自行在 [langchain.com](https://smith.langchain.com) 注册并获取 API Key

---

## 5. 测试验证

集成完成后通过以下方式验证：

1. 设置 `LANGSMITH_TRACING=true` 并配置 API Key
2. 发起一次 Agent 对话
3. 在 LangSmith Dashboard 中查看对应的 trace，确认包含：
   - 5 个节点的执行记录
   - 每个节点的 LLM 输入/输出
   - 工具调用记录
   - Token 消耗统计
