Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions python/03-integrations/migration/langgraph/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# LangGraph 项目适配 AgentKit Runtime 示例

本示例将演示如何将 LangGraph 项目适配到 AgentKit Runtime 上。

示例项目模拟一个用户已有的 LangGraph 旅行规划项目。该项目的业务入口是 `agent.py:agent`,类型是已编译的 `StateGraph`。它接收用户的旅行问题后,会通过 LangGraph 的图编排能力,把一次旅行规划拆成多个节点执行:先解析需求,再检索旅行上下文和预算信息,最后汇总成每天的景点、美食和交通建议。

示例中的工具用于模拟真实 LangGraph 项目中的 tool use:

- `search_travel_web`:模拟依赖外部知识检索的工具,内部调用 `veadk.tools.builtin_tools.web_search`
- `estimate_trip_budget`:模拟本地业务计算工具,根据城市、天数和预算生成预算判断

`agent.py` 是一个基于 LangGraph 构建的 Agent,重点模拟用户使用 LangGraph 搭建 agent 的真实使用场景:

- `StateGraph(TravelState)`:定义旅行规划的共享状态,并编译为 `agent.py:agent`
- `parse_request` 节点:解析用户问题中的城市、天数、预算、同行人和偏好
- `search_travel_context` 节点:调用 `search_travel_web` 和 `estimate_trip_budget`,把外部知识和本地预算判断写回 graph state
- `build_final_answer` 节点:读取前面节点写入的 state,汇总搜索上下文、预算判断和行程安排
- `add_edge`:声明节点执行顺序,让请求沿着 `START -> parse_request -> search_travel_context -> build_final_answer -> END` 流转
- `InMemorySaver`:保留同一个 `thread_id` 下的会话状态,模拟真实 LangGraph workflow 的状态延续

适配到 AgentKit Runtime 时,不需要改写 `agent.py` 的业务逻辑。`agentkit migrate` 会生成 `agentkit_app.py` 和 `.agentkit/` 配置;生成的 Runtime 应用通过 `LangGraphAgentkitBridge(input_key="question")` 调用原始 `agent.py:agent`。

## 适配后的图编排调用链路

适配前,用户可以直接调用 `agent.py:agent`。适配后,AgentKit Runtime 会通过生成的 `agentkit_app.py` 调用同一个入口;进入 `agent.py:agent` 后,执行逻辑仍然由 LangGraph 的节点和边驱动:

```text
用户问题
AgentKit Runtime
agentkit_app.py
LangGraphAgentkitBridge(input_key="question")
agent.py:agent # compiled StateGraph
├── parse_request
├── search_travel_context
│ ├── search_travel_web
│ │ └── veadk.tools.builtin_tools.web_search
│ └── estimate_trip_budget
└── build_final_answer
```

## 目录结构

```bash
langgraph/
├── README.md
├── agent.py # 原生 LangGraph graph、节点和 tools
├── requirements.txt # Python 依赖
└── tests # 本地行为测试和迁移链路回归测试
```

## 本地运行

安装依赖:

```bash
pip install -r requirements.txt
```

直接运行原生 Graph:

```bash
python agent.py
```

运行测试:

```bash
python -m unittest discover -s tests -v
```

测试会直接覆盖 `search_travel_web` 的真实工具调用链路。

## 搜索配置

`search_travel_web` 直接使用 `veadk.tools.builtin_tools.web_search`。本地或云端运行时,请参考其它 samples 的通用方式,先在 [AgentKit 控制台授权页面](https://console.volcengine.com/agentkit/region:agentkit+cn-beijing/auth?projectName=default) 完成依赖服务授权,并配置火山引擎 AK/SK:

```bash
VOLCENGINE_ACCESS_KEY=<Your Access Key>
VOLCENGINE_SECRET_KEY=<Your Secret Key>
```

如果环境没有搜索权限,工具会返回搜索失败说明,Graph 仍会按示例逻辑生成可读结果。

## 执行迁移

在当前目录执行:

```bash
agentkit migrate . \
--framework langgraph \
--entry agent.py:agent \
--name migration-langgraph-travel \
--input-key question \
--verify
```

参数含义:

- `--framework langgraph`:按 LangGraph compiled graph 方式迁移
- `--entry agent.py:agent`:指定原生 Graph 入口
- `--input-key question`:把 Runtime 输入写入 `question` 字段
- `--verify`:生成后执行基础校验

迁移会生成:

```bash
langgraph/
├── agentkit_app.py
├── .agentkit/
│ ├── agentkit.yaml
│ ├── Dockerfile
│ └── migration-plan.json
└── requirements.txt
```

迁移命令不会改写 `agent.py`。生成的 Runtime 应用会通过 `LangGraphAgentkitBridge(input_key="question")` 调用原始 `agent.py:agent`,并将 AgentKit 会话映射到 LangGraph `thread_id`。

## 部署到 AgentKit Runtime

确认 `.agentkit/agentkit.yaml` 后执行:

```bash
agentkit deploy
```

部署后,Runtime 入口是 `agentkit_app.py`,业务逻辑仍由 `agent.py:agent` 中的 LangGraph 节点、checkpointer 和原有 tools 执行。

## 示例问题

```text
我想带父母去北京玩3天,总预算3000元,喜欢历史文化、胡同和老北京美食,行程轻松一点。请帮我规划每天的景点、美食和交通建议。
```
137 changes: 137 additions & 0 deletions python/03-integrations/migration/langgraph/README_EN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# LangGraph Project Adaptation to AgentKit Runtime Sample

This sample shows how to adapt a LangGraph project to AgentKit Runtime.

The sample project represents an existing LangGraph travel-planning project that a user already has. Its business entry point is `agent.py:agent`, implemented as a compiled `StateGraph`. After receiving a user's travel request, it uses LangGraph orchestration to split one travel-planning task into multiple nodes: first parsing the request, then retrieving travel context and budget information, and finally summarizing daily attraction, food, and transportation suggestions.

The tools in this sample simulate tool use in a real LangGraph project:

- `search_travel_web`: simulates a tool that depends on external knowledge retrieval, and internally calls `veadk.tools.builtin_tools.web_search`
- `estimate_trip_budget`: simulates a local business calculation tool that evaluates the budget based on city, number of days, and total budget

`agent.py` is an Agent built with LangGraph. It focuses on simulating a realistic scenario where users build an agent with LangGraph:

- `StateGraph(TravelState)`: defines the shared state for travel planning and compiles it as `agent.py:agent`
- `parse_request` node: parses the city, number of days, budget, travelers, and preferences from the user's question
- `search_travel_context` node: calls `search_travel_web` and `estimate_trip_budget`, then writes external knowledge and local budget evaluation back into the graph state
- `build_final_answer` node: reads the state written by previous nodes and summarizes search context, budget evaluation, and itinerary planning
- `add_edge`: declares node execution order so the request flows through `START -> parse_request -> search_travel_context -> build_final_answer -> END`
- `InMemorySaver`: preserves session state under the same `thread_id`, simulating state continuity in a real LangGraph workflow

When adapting the project to AgentKit Runtime, you do not need to rewrite the business logic in `agent.py`. `agentkit migrate` generates `agentkit_app.py` and `.agentkit/` configuration. The generated Runtime app calls the original `agent.py:agent` through `LangGraphAgentkitBridge(input_key="question")`.

## Adapted Graph Orchestration Flow

Before adaptation, users can call `agent.py:agent` directly. After adaptation, AgentKit Runtime calls the same entry point through the generated `agentkit_app.py`. Once execution enters `agent.py:agent`, the logic is still driven by LangGraph nodes and edges:

```text
User question
|
AgentKit Runtime
|
agentkit_app.py
|
LangGraphAgentkitBridge(input_key="question")
|
agent.py:agent # compiled StateGraph
|-- parse_request
|-- search_travel_context
| |-- search_travel_web
| | `-- veadk.tools.builtin_tools.web_search
| `-- estimate_trip_budget
`-- build_final_answer
```

## Directory Layout

```bash
langgraph/
├── README.md
├── README_EN.md
├── agent.py # Native LangGraph graph, nodes, and tools
├── requirements.txt # Python dependencies
└── tests # Local behavior tests and migration-chain regression tests
```

## Local Run

Install dependencies:

```bash
pip install -r requirements.txt
```

Run the native Graph directly:

```bash
python agent.py
```

Run tests:

```bash
python -m unittest discover -s tests -v
```

The tests directly cover the real tool-call path of `search_travel_web`.

## Search Configuration

`search_travel_web` directly uses `veadk.tools.builtin_tools.web_search`. For local or cloud execution, follow the common setup used by other samples: authorize dependent services in the [AgentKit Console authorization page](https://console.volcengine.com/agentkit/region:agentkit+cn-beijing/auth?projectName=default), then configure Volcengine AK/SK:

```bash
VOLCENGINE_ACCESS_KEY=<Your Access Key>
VOLCENGINE_SECRET_KEY=<Your Secret Key>
```

If the environment has no search permission, the tool returns a search failure message. The Graph still returns a readable sample response.

## Run Migration

Run this command in the current directory:

```bash
agentkit migrate . \
--framework langgraph \
--entry agent.py:agent \
--name migration-langgraph-travel \
--input-key question \
--verify
```

Arguments:

- `--framework langgraph`: migrate as a LangGraph compiled graph
- `--entry agent.py:agent`: specify the native Graph entry point
- `--input-key question`: write Runtime input into the `question` field
- `--verify`: run basic checks after generation

Migration generates:

```bash
langgraph/
├── agentkit_app.py
├── .agentkit/
│ ├── agentkit.yaml
│ ├── Dockerfile
│ └── migration-plan.json
└── requirements.txt
```

The migration command does not rewrite `agent.py`. The generated Runtime app calls the original `agent.py:agent` through `LangGraphAgentkitBridge(input_key="question")` and maps the AgentKit session to the LangGraph `thread_id`.

## Deploy To AgentKit Runtime

After reviewing `.agentkit/agentkit.yaml`, run:

```bash
agentkit deploy
```

After deployment, the Runtime entry point is `agentkit_app.py`. The business logic is still handled by the LangGraph nodes, checkpointer, and original tools in `agent.py:agent`.

## Example Prompt

```text
I want to take my parents to Beijing for 3 days with a total budget of 3000 RMB. We like history and culture, hutongs, and old Beijing food. Please keep the itinerary relaxed and plan attractions, food, and transportation for each day.
```
Loading