
Parlant Customer 实体详解客户注册、存储选型、标签分组与元数据个性化【免费下载链接】parlantBuild reliable customer-facing AI agents with Parlant: an interaction control harness optimized for controlled, consistent, and predictable LLM interactions.项目地址: https://gitcode.com/GitHub_Trending/pa/parlant本文围绕 Parlant 的 Customer客户实体展开讲清 Customer 在 Parlant 中的定义与边界与认证体系的关系、如何通过 SDK 以最小信息注册客户、customer_store参数在内存 / 本地 JSON 文件 / MongoDB / 自定义四种存储后端的实际行为以及如何用 tags标签分组和 metadata自定义元数据驱动差异化交互与工具调用并结合 CustomerStore 抽象 与 CustomerModule 应用层模块 的源码实现说明每个 API 参数落到存储层的具体链路。Customer 是什么一个与业务关系解耦的交互身份在 Parlant 中customer客户是一个代码层面的称谓指代任何与 agent 交互的一方——无论真实关系如何它可以是真人、机器人甚至是一个人类坐席human agent。也就是说Parlant 不关心客户在业务语义上是否真的付费或购买它只提供一套统一的交互身份机制让 agent 能够知道自己正在和谁对话。由此带来两个要点匿名交互是一等公民。agent 可以在完全不知道对方是谁的情况下运行anonymous operation。注册客户是可选增强。当你注册了客户Parlant 允许你基于其身份与偏好提供深度个性化体验——例如高价值客户收到高级别优惠、新用户获得聚焦的入门引导、不同用户分群采用不同话术。import parlant.sdk as p async with p.Server() as server: # Register a new customer customer await server.create_customer(nameAlice)从 SDK 的Server.create_customer实现看注册一个客户只需要name一个必填参数此外还支持三个可选参数metadata默认空 dict描述客户的任意键值对如邮箱、VIP 状态、偏好tags默认空列表要关联的标签 ID 列表用于客户分类与筛选id默认自动生成允许传入自定义客户 ID 字符串用于跨部署环境或对接内部系统时保持标识一致如与内部 CRM 的客户 ID 对齐。若显式传入的 ID 已存在存储层会直接抛出ValueError未显式指定时ID 由客户属性name extra tags的 xxh3 校验和驱动 ID 生成器产生。Guest内置的匿名客户源码中有一个值得注意的细节CustomerStore抽象类定义了一个常量GUEST_ID CustomerId(guest)。在 存储实现 中读取guestID 时返回的是一个虚拟构造的客户对象名为 Guest、无元数据、无标签并不落库列举客户时guest 客户始终被计入总数并出现在列表首位除非按标签过滤guest 客户不可删除会抛出Removing the guest customer is not allowed错误。SDK 层同样暴露了这些语义Customer.guest是一个 classproperty 形式的便捷访问入口而Customer.current则可以从当前 asyncio 任务上下文中获取当前对话的客户见 Customer 类定义。这意味着 Parlant 从底层设计上就兼容了先匿名、后识别的渐进式身份模型。认证Parlant 是后端服务鉴权留在应用层Parlant 的设计定位是作为后端服务运行因此刻意不内置认证逻辑客户的注册归 Parlant 管但认证authentication与授权authorization留给应用层完成——你可以用 OAuth、JWT 或任何适合业务的方式。推荐的协作方式是在你的应用代码中完成客户身份识别登录态、令牌校验等识别完成后把该客户的 ID 传给 agent在会话/消息的上下文中传入customer_idagent 即可基于这个已注册客户的身份与元数据来个性化交互。这与 core 层的实体读写入口 相吻合引擎在执行交互时按customer_id从CustomerStore读取客户实体并注入引擎上下文EntityContext工具与检索函数随后即可通过上下文访问当前客户。存储customer_store 参数的四种取值与底层实现p.Server的构造参数customer_store的签名是customer_store: Literal[transient, local] | str | CustomerStore transient即它可以是内置关键字字符串、数据库连接字符串或者直接传入一个实现了CustomerStore抽象接口的自定义实例。在 Server 的容器装配逻辑 中内部函数make_persistable_store负责把字符串规格解析为具体的存储实例取值行为适用场景transient默认纯内存存储服务重启后客户数据丢失测试与开发localJSON 文件持久化保存至$PARLANT_HOME/customers.json本地/单机的生产持久化零依赖mongodb://...或mongodbsrv://...连接 MongoDB使用内置的 Mongo 适配器库名为parlant_customers生产环境CustomerStore实例直接注入自定义存储实现需要对接自有数据库时默认不持久化默认情况下 Parlant不持久化客户——客户保存在内存中服务重启即丢失。这对开发和测试非常方便每次启动都从干净状态开始。本地持久化JSON 文件把customer_store设为local即可启用本地持久化客户数据会保存到$PARLANT_HOME/customers.json源码中对应PARLANT_HOME_DIR / customers.json由 JSON 文件适配器 提供底层读写。零配置、零外部依赖import asyncio import parlant.sdk as p async def main(): async with p.Server(customer_storelocal) as server: # ... asyncio.run(main())MongoDB 持久化生产环境可以直接指定 MongoDB 连接字符串启动服务器。从 Mongo 适配路径 看mongodb://与mongodbsrv://两种协议前缀都被识别底层使用AsyncMongoClient建立连接并通过 MongoDocumentDatabase 适配器 将客户数据写入名为parlant_customers的数据库import asyncio import parlant.sdk as p async def main(): async with p.Server(customer_storemongodb://path.to.your.host:27017) as server: # ... asyncio.run(main())存储层的数据模型无论选哪种后端CustomerDocumentStore 的数据模型是一致的它建立在DocumentDatabase抽象之上、使用两个集合customers客户主体文档字段为id、versionschema 版本当前0.1.0、creation_utc、name、extra即 SDK 中对外呈现的metadata键值对customer_tag_associations客户-标签关联文档customer_idtag_id并对customer_id、tag_id及二者组合建立索引保证按客户查标签与按标签查客户两个方向的查询效率。标签采用独立的关联集合而非客户文档内嵌数组使得给某个标签筛选全部客户这类操作天然高效同时文档带版本号并配有迁移辅助DocumentStoreMigrationHelper从源码结构看这为 schema 演进预留了迁移通道。客户分组用 tags 控制分群个性化要按客户群体做差异化处理例如给 VIP 客户提供专属话术或优惠Parlant 提供tags标签机制# Create a new tag to represent VIP customers vip_tag await server.create_tag(nameVIP) # Register a new customer customer await server.create_customer(nameAlice, tags[vip_tag.id])从 CustomerModule.create 的实现 可以确认其行为细节传入的每个标签 ID 都会先经过_ensure_tag校验——标签必须真实存在包括 agent 作用域的标签会先校验其所属 agent不存在的标签 ID 会导致创建失败而不是静默忽略传入的标签列表会先做set去重避免重复关联创建成功后标签关联以独立文档写入customer_tag_associations集合。反过来列举客户也支持按标签过滤CustomerStore.list_customers(tags...)会先在关联集合中按$or条件反查拥有任一指定标签的客户 ID再据此过滤主体集合特别地按标签过滤时不包含 guest 客户见 list_customers 实现。进阶针对特定客户或客户分群的更精细个性化如按客户/标签注入变量可继续阅读 variables 文档 中关于 Context Variables 的说明。自定义元数据Metadata为交互与工具提供上下文除了name还可以给客户附加任意自定义元数据用于进一步个性化交互或为工具调用提供上下文。SDK 侧的参数名叫metadata存储层对应extra字段Mapping[str, str]customer await server.create_customer(nameAlice, metadata{ external_id: 12345, location: USA, })元数据最常见的消费场景是工具内部读取当前客户。工具函数通过ToolContext拿到customer_id再用server.find_customer查回客户对象注意文档示例中的find_customer在 SDK 实现 中要求id或name至少提供一个否则抛出SDKErrorp.tool async def get_customer_location(context: p.ToolContext) - p.ToolResult: server p.ToolContextAccessor(context).server if customer : await server.find_customer(idcontext.customer_id): return p.ToolResult(customer.metadata.get(location, Unknown location)) return p.ToolResult(Customer not found)从 CustomerMetadata 的实现 看SDK 返回的metadata对象比只读字典更丰富它同时支持同步读metadata[location]、in、iter、len直接读取本地缓存副本异步读await metadata.get(key, default)会先从存储层重新读取客户文档再返回保证拿到最新值异步写await metadata.set(key, value)/await metadata.delete(key)分别对应存储层的upsert_extra/remove_extra并即时持久化guest 保护对 guest 客户的元数据写入会抛出RuntimeError(Cannot update the guest customer)与guest 不可变更的整体约束一致。应用层注册客户REST API 与客户端 SDKSDK 方式适合与 Parlant 同进程部署的场景但在多数生产架构中更实际的做法是在应用层完成客户注册——这样可以把客户管理与现有的用户认证、授权体系自然集成。此时可以通过 Parlant 的 REST API 或原生客户端 SDK 管理客户例如from parlant.client import ParlantClient # Change localhost to your servers address client ParlantClient(http://localhost:8800) client.customers.create( nameAlice, metadata{ external_id: 12345, location: USA, hobby: reading, }, tags[TAG_ID] # Optional: specify tag IDs to assign to the customer )对应的服务端路由定义在 api/customers.py提供POST创建、GET查询/列举、PATCH更新、DELETE删除等端点供客户端 SDK 调用。API 层的请求处理最终委托给 CustomerModule因此通过 HTTP 与通过 SDK 直连所走的应用层逻辑完全一致。更新客户数据name、metadata 与 tags 的原子化组合更新客户数据可以随时更新包括姓名、元数据和标签以便随应用演进保持客户信息最新client.customers.update( customer_idCUSTOMER_ID, nameAlice Smith, metadata{ set: { location: Canada, }, remove: [hobby], }, tags[NEW_TAG_ID] # Optional: specify new tag IDs to assign to the customer )从 CustomerModule.update 的实现可以看清一次更新请求在存储层的展开方式——三项更新各自独立执行、按需跳过name非空 → 调用update_customer(params{name: ...})更新主体文档metadata.set→ 调用upsert_extra将键值对合并进现有extrametadata.remove→ 调用remove_extra按 key 列表删除tags的增/删 → 逐个调用upsert_tag/remove_tag且新增前同样会_ensure_tag校验标签存在性全部完成后重新读取客户并返回最新对象。值得注意的是upsert_extra是合并语义保留未提及的旧键而remove_extra才是显式删除二者组合起来{set: ..., remove: ...}的更新协议就能精确表达部分修改。SDK 直连模式下Customer.update(name...)提供的是最简子集仅改名完整元数据修改则通过CustomerMetadata.set/delete完成。小结Parlant 的 Customer 实体是一套刻意保持轻量的身份机制最小注册仅 name→ 可选标签分组 → 可选任意元数据 → 可插拔存储后端transient / local JSON / MongoDB / 自定义 CustomerStore。认证与授权被明确留在应用层Parlant 只负责把已识别的客户身份变成 agent 可用的上下文——这一分工使得它可以干净地嵌入既有系统的用户体系同时通过 tags 与 metadata 支撑起从VIP 优惠到工具读取客户属性这类常见的个性化需求。若需要进一步掌握按客户/分群注入上下文的机制建议继续阅读 variables 一节相关行为测试可参考 tests/sdk/test_customers.py 与 tests/api/test_customers.py。【免费下载链接】parlantBuild reliable customer-facing AI agents with Parlant: an interaction control harness optimized for controlled, consistent, and predictable LLM interactions.项目地址: https://gitcode.com/GitHub_Trending/pa/parlant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考