> ## Documentation Index
> Fetch the complete documentation index at: https://powercontext.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain

> 每次模型请求前召回，并按需捕获一次成功完成的轮次，不修改 agent 状态。

> [!WARNING]
>
> 仅支持源码安装：`powercontext-langchain==0.0.1` 尚未发布到 PyPI。官方安装 URL 跟随可变的 `master`，专项软件包测试也没有覆盖这条 VCS 安装路径。可复现性为 **Not validated**；请固定经过审阅的提交及其依赖。

`PowerContextMiddleware` 接入 LangChain `create_agent`。它支持同步与异步，只修改当前模型请求，并可把完成的轮次捕获为 Source 证据。它没有 adapter-owned PowerContext 工具。

## 成熟度与安装

| 项目 | 状态 |
| - | - |
| 软件包 | 仅源码安装；不在 PyPI |
| 版本 | `0.0.1` |
| 运行时 | Python `>=3.11,<4.0`；LangChain `>=1.3,<2` |
| 调用方式 | Sync 与异步 |
| 可变分支的可复现性 | **Not validated** |
| 文档证据中的真实模型提供方往返验证 | **Not validated** |

从已审阅的源码提交安装 Server 与中间件：

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
uv tool install --force "powercontext[cli,server] @ git+https://github.com/oceanbase/powercontext.git@3e629eb163ba0ddf2935ce3b3fbaced0f9371977"
uv pip install "powercontext-langchain @ git+https://github.com/oceanbase/powercontext.git@3e629eb163ba0ddf2935ce3b3fbaced0f9371977#subdirectory=integrations/langchain"
powercontext server run
```

如果使用同一提交的本地检出：

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
git -C /path/to/powercontext checkout 3e629eb163ba0ddf2935ce3b3fbaced0f9371977
uv pip install /path/to/powercontext/integrations/langchain
```

> [!NOTE]
>
> 中间件 与 `powercontext-langgraph` 相互独立。LangChain 内部可能安装 LangGraph，但两个 PowerContext 适配器使用不同的设置、Scope types 和生命周期行为。

## 最小用法

下面的示例假设应用已经有初始化完成的聊天模型和正常的 Agent 或模型调用循环。PowerContext 只提供中间件，不替你选择或创建模型。先用中间件专项测试或无模型假实现验证 Scope 与召回，再把中间件放到真实调用外围。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from langchain.agents import create_agent
from powercontext_langchain import PowerContextMiddleware, PowerContextScope

agent = create_agent(
    model,
    tools=application_tools,
    middleware=[PowerContextMiddleware()],
    context_schema=PowerContextScope,
)

result = await agent.ainvoke(
    {
        "messages": [
            {
                "role": "user",
                "content": "What should happen after changing the OpenAPI contract?",
            }
        ]
    },
    context=PowerContextScope(scope_id="project:powercontext-101"),
)
```

同一中间件在同步应用中支持 `invoke` 与 `stream`，在异步应用中支持 `ainvoke` 与 `astream`。

> [!WARNING]
>
> 不要在已经运行的事件循环中调用同步 agent method。宿主仍会运行，但 PowerContext 召回与采集会被跳过，中间件记录一次警告。此时应使用异步 agent API。

## 执行流程

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
before every model request
→ read latest human message
→ resolve per-invocation Scope and connection settings
→ prepare_context(query <= 8192 chars, max_bytes)
→ append an untrusted block to this ModelRequest.system_message
→ call model without changing agent state
→ after successful agent completion, optionally capture latest user + final response
```

每个模型请求前都会召回。它不像 Pydantic AI 能力那样每个运行一次，也不像 LangGraph 那样按用户轮次准备一次并跨模型 steps 使用缓存。因此，同一运行中应用-owned 工具先写入 Memory，后续模型步骤可能看到新内容。

中间件 只覆盖值当前 `ModelRequest.system_message`，从不把召回的内容块写入框架状态或检查点存储器。原有系统消息保持在前，不可信上下文内容块只追加到这一次请求。

## 采集默认关闭

只有在确认可以持久保存用户与最终模型内容后才开启采集：

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
middleware = PowerContextMiddleware(auto_capture=True)
```

`auto_capture` 默认为 `False`。`after_agent` 或 `aafter_agent` 只在成功完成后捕获，内容是最新的非空用户消息，加上可序列化的 `structured_response` 或最后一条非空助手响应。

| 包含 | 排除 |
| - | - |
| Latest 用户 文本 | 工具输出 |
| Final 助手 文本 | Intermediate 工具-calling 消息 |
| 可序列化的 `structured_response` | 召回的 PowerContext 内容块 |
| Truncation 元数据 | Aborted 运行或没有最终响应的运行 |

合并后的 Source 载荷另有 200,000 Python-character 上限。适配器会在用户与助手 文本 之间分配预算，并记录 截断 flags。

> [!NOTE]
>
> 采集创建 Source，不创建或批准 Memory，中间件也不刷新。Server 抽取可以稍后由调度器或显式客户端操作触发，也可能得到无变更。

## Scope 与配置

一个 agent 服务多个租户时，应在每次调用传入 `PowerContextScope`。每次调用的 Scope、基础 URL、令牌和超时会覆盖环境变量。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
scope = PowerContextScope(
    scope_id="tenant:acme:project:api",
    base_url="https://context.example.com",
    token="opaque-server-token",
    timeout=8.0,
)

result = await agent.ainvoke(state, context=scope)
```

| 设置 | 默认值 |
| - | -: |
| `POWERCONTEXT_LANGCHAIN_BASE_URL` | `http://127.0.0.1:8000` |
| `POWERCONTEXT_LANGCHAIN_TOKEN` | 未设置 |
| `POWERCONTEXT_LANGCHAIN_SCOPE_ID` | 派生或报错 |
| `POWERCONTEXT_LANGCHAIN_TIMEOUT` | `10` 秒 |
| `POWERCONTEXT_LANGCHAIN_MAX_BYTES` | `8000`；允许范围 `512`–`32768` 字节 |

Scope 优先顺序：

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
PowerContextScope(scope_id=...)
→ POWERCONTEXT_LANGCHAIN_SCOPE_ID
→ normalized network Git origin
→ MissingScopeError
```

没有 local-path 后备路径。HTTP(S)、SSH、Git 和 SCP-like 网络远程会在移除凭证后做规范化。过长的显式 Scope 会被替换为有界的 SHA-256 标识。

令牌采用不含 `Bearer ` 的不带前缀的令牌约定。适配器不严格校验该语法。除非调用方提供并显式标记可信传输层，共享的 `PowerContextClient` 会拒绝向非本机回环地址宿主使用明文 HTTP。

## 失败、隐私与 Scope 边界

自动召回与采集是相互独立的 fail-open 路径。Scope 缺失、配置错误、请求校验、认证失败、超时、Server 失败，或无法序列化的 结构化 响应，都不会替换模型结果，也不会中止宿主运行。HTTP 401/403 会记录为配置问题，不会冒充空结果 Memory。

中间件 不添加显式 PowerContext 工具。如果应用自行把 Python Client 修改操作包装成工具，其失败契约和权限归应用负责；自动 fail-open 不会让这些修改操作假装成功。

> [!WARNING]
>
> 召回可能包含旧用户或模型 文本。它是不可信证据，不是指令、标识 proof 或权限 grant。Scope 只选择数据分区；需要隔离时，应从 已认证 租户/项目映射派生 Scope。

采集可能存储普通提示词、代码、业务数据和最终模型输出。此适配器不承诺完整敏感信息脱敏。在应用明确内容 过滤、consent、保留策略与 deletion 规则 前，保持 `auto_capture=False`。排除工具输出并不能替代隐私策略。

## 与 LangGraph 对比

两者的区别在于召回挂接到哪个生命周期。选择应用已经使用的生命周期，不要额外包装一个框架去模仿另一个。

| 能力 | LangChain | LangGraph |
| - | - | - |
| 召回 frequency | 每个模型请求 | 每个用户轮次一次，跨模型 steps 使用缓存 |
| 适配器负责的 工具 | 无 | 三个 Memory 工具 |
| 自动采集 | 可选已完成轮次 Source；默认关闭 | 无 |
| 调用方式 | Sync 与异步 | 仅异步 |
| 注入频道 | 当前 `ModelRequest.system_message` | 临时 `llm_input_messages` |
| Framework 状态修改操作 | 无 | 召回不修改持久化的 `messages` |
| 刷新 | 无 | 无 |

## 当前不支持或尚未验证

| 项目 | 状态 |
| - | - |
| 适配器负责的 PowerContext 工具 | **Unsupported** |
| 自动或最终刷新 | **Unsupported** |
| Handoff 与 Candidate Review | **Unsupported** |
| Experience 与 Skill 操作 | **Unsupported** |
| Failed 或 aborted-run 采集 | **Unsupported** |
| 完整敏感信息脱敏 | **Unsupported** |
| 从可变 `master` 进行可复现安装 | **Not validated** |
| 文档证据中的真实外部模型提供方往返验证 | **Not validated** |

## 完成检查清单

* Server 单独运行，源码安装的中间件固定到经过审阅的提交。
* 同步代码在事件循环外运行；异步代码使用 `ainvoke` 或 `astream`。
* 捕获到的模型请求含不可信召回内容块，返回的 与写入检查点的状态不含该内容块。
* 测试按每个模型请求发生召回编写，而不是按运行一次或轮次一次。
* 每次调用收到预期 Scope；跨 Scope 负向 测试证明租户 isolation。
* `MAX_BYTES` 在 512 到 32,768 之间，超过 8,192 字符的查询会被截断，远程传输层使用 HTTPS。
* Server 不可用时模型流程继续，401/403 仍能与空结果 Memory 区分。
* 除非已完成轮次 storage 已有明确的隐私与保留策略，否则 `auto_capture` 保持关闭。
* 采集开启时检查 Source，不假定 Memory 已生成或刷新已发生。
* 部署记录没有混淆 Unsupported 与 Not validated。

> [!TIP]
>
> 先 种子 一条显式 Memory，检查模型请求，再检查框架状态。另开一次运行启用采集，然后确认 Source 日志有记录且没有自动刷新。

下一页进入[框架进阶技巧](https://powercontext.mintlify.site/zh/frameworks/tricks.md)，继续检查跨框架的 Scope、传输层、预算与失败行为。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.