#Python

0 关注者 · 53 帖子

Python 是一种用于通用编程的解释性高级编程语言。Python 由 Guido van Rossum 创建并于 1991 年首次发布,其设计理念强调代码的可读性,特别是使用大量的空白

官方网站

InterSystems Python 绑定

文章 Lilian Huang · 十一月 6, 2025 6m read

我很清楚对于那些完全不熟悉 VS Code、Git、Docker、FHIR 和其他工具的人来说,设置环境时会遇到一些困难。 所以我决定写这篇文章,详细介绍整个设置过程,以便大家能够轻松上手。

如果您能在本文最后留下评论,告诉我说明是否清楚,是否有遗漏,或者是否有其他您觉得有用的东西,我将不胜感激。

设置包括:

✅ VS Code – 代码编辑器
✅ Git – 版本控制系统
✅ Docker – 运行 IRIS for Health Community 的实例
✅ VS Code REST 客户端扩展程序 – 用于运行 FHIR API 查询
✅ Python – 用于编写基于 FHIR 的脚本
✅ Jupyter Notebook – 用于 AI 和 FHIR 任务

准备工作:确保您在系统上拥有管理员权限

除了阅读本指南,您还可以按照视频中的步骤操作:

如果您是 Windows 系统(请注意:原文是YouTube视频,请跳转至EN原帖查看)

0
0 13
文章 Lilian Huang · 十一月 6, 2025 7m read

Interoperability on Python (IoP) 是一个概念验证项目,旨在展示与 Python 优先方式相结合时 InterSystems IRIS Interoperability Framework 的强大功能。IoP 利用Embedded Python(嵌入式 Python,InterSystems IRIS 的一个功能)使开发者能够用 Python 编写互操作性组件,从而可以与强大的 IRIS 平台无缝集成。本指南专为初学者编写,全面介绍了 IoP、其设置以及创建第一个互操作性组件的操作步骤。 阅读完本文,您将能够清楚地了解如何使用 IoP 构建可扩缩、基于 Python 的互操作性解决方案。

0
0 13
文章 Lilian Huang · 十月 24, 2025 14m read

学习如何使用 LangGraph 设计结合了推理、矢量搜索和工具集成的可扩缩自主 AI 智能体。

cover

概括

  • AI 智能体是一种超越简单的聊天机器人的自主系统,它结合了记忆库、上下文,并具有自动完成任务的主动性。
  • LangGraph 是一种框架,它使我们能够利用具有内置状态管理的节点(任务)和边缘(连接),构建复杂的 AI 工作流。
  • 本指南将指导您构建 AI 赋能的客户支持智能体,该智能体可以划分优先级,识别相关主题,并确定是上报还是自动回复。

那么,AI 智能体究竟是什么?

让我们直面它吧 —“AI 智能体”听起来就像可以接管会议室的机器人。 实际上,它们是您得力的助手,可以简化复杂的工作流,消除重复性任务。 您可以把它们看作是聊天机器人的下一个进化阶段:它们不只是简单地等待提示;它们可以发起行动,协调多个步骤,并随时进行调整。

过去,打造一个“智能”系统意味着兼顾语言理解、代码生成、数据查找等各种不同的模型,然后将它们粘合在一起。 您的一半时间花在了集成上,另一半时间则花在了调试上。

智能体彻底颠覆了这一切。 它们将上下文、主动性和适应性融合在一个精心编排的流程中。 它们不仅实现了自动化,更是肩负使命的智者。 借助 LangGraph 之类的框架,我相信,组建一支自己的智能体团队实际上会很有趣。

image

LangGraph 究竟是什么?

LangGraph 是一种创新型框架,它彻底改变了我们构建涉及大语言模型 (LLM) 的复杂应用程序的方式。

想象一下,您正在指挥一支管弦乐队:每种乐器(或“节点”)都需要知道何时演奏,声音有多大,顺序如何。 这种情况下,LangGraph 就是您的指挥棒,为您提供以下内容:

  • 图结构:它采用具有节点和边缘的图结构,使开发者能够设计适应各种分支和循环的灵活非线性工作流。 它可以反映复杂的决策过程,类似于神经通路的运作方式。
  • 状态管理:LangGraph 提供了各种内置工具,可以实现状态保持和错误恢复,简化了应用程序中各个阶段的上下文数据的维护。 借助 Zep 等工具,它可以在短期记忆和长期记忆之间高效切换,提高了交互质量。
  • 工具集成:借助 LangGraph,LLM 智能体可以轻松与外部服务或数据库协作,获取真实的数据,从而改进应用程序的功能和响应性。
  • 人机协同:除了可以实现自动化外,LangGraph 还可以适应工作流中的人为干预,这对于需要分析监督或伦理考虑的决策过程至关重要。

无论您是在构建具有真实记忆的聊天机器人、交互式故事引擎,还是能够处理复杂问题的智能体团队,LangGraph 都可以将令人头疼的管道工程转变成简单明了、直观的状态机。

开始

要开始使用 LangGraph,您需要进行基本的设置,通常包括安装 langgraph 和 langchain-openai 等必要的库。 然后,您可以定义图中的节点(任务)和边缘(连接),有效地实现短期记忆的检查点,并利用 Zep 满足更持久的记忆需求。

操作 LangGraph 时,请记住以下几点:

  • 具有灵活性的设计:利用强大的图结构来解释并非严格线性的潜在工作流分支和交互。
  • 以深思熟虑的方式与工具交互:利用外部工具增强 LLM 功能,而不是取而代之。 为每个工具提供全面的描述,以实现精确使用。
  • 采用丰富的记忆解决方案:高效地使用记忆库,留意 LLM 的上下文窗口,并考虑集成外部解决方案,以实现自动事实管理。

现在,我们已经介绍 LangGraph 的基础知识,我们来看一个实例。 为此,我们将开发一个用于提供客户支持的 AI 智能体。

这个智能体将接收电子邮件请求,分析电子邮件正文中的问题描述,然后确定请求的优先级和适当的主题/类别/部门。

系好安全带,我们开始吧!

buckle up

首先,我们需要定义什么是“工具”。 可以把它看作是智能体的专属“助理”,使其能够与外部功能进行交互。

@tool 装饰器在这里必不可少。 LangChain 简化了自定义工具的创建,这意味着首先,定义一个 Python 函数,然后应用 @tool 装饰器。

tools

为了进行说明,我们来创建第一个工具。 这个工具将帮助智能体根据电子邮件内容划分 IT 支持工单的优先级:

    from langchain_core.tools import tool
    
    @tool
    def classify_priority(email_body: str) -> str:
        """Classify the priority of an IT support ticket based on email content."""
        prompt = ChatPromptTemplate.from_template(
            """Analyze this IT support email and classify its priority as High, Medium, or Low.
            
            High: System outages, security breaches, critical business functions down
            Medium: Non-critical issues affecting productivity, software problems
            Low: General questions, requests, minor issues
            
            Email: {email}
            
            Respond with only: High, Medium, or Low"""
        )
        chain = prompt | llm
        response = chain.invoke({"email": email_body})
        return response.content.strip()

太棒了! 现在,我们有一个提示,指示 AI 接收电子邮件正文,对其进行分析,并将其优先级分为“高”、“中”或“低”。

就是这样! 您刚刚编写了一个智能体可以调用的工具!

接下来,我们创建一个类似的工具来识别支持请求的主要主题(或类别):


    @tool
    def identify_topic(email_body: str) -> str:
        """Identify the main topic/category of the IT support request."""
        prompt = ChatPromptTemplate.from_template(
            """Analyze this IT support email and identify the main topic category.
            
            Categories: password_reset, vpn, software_request, hardware, email, network, printer, other
            
            Email: {email}
            
            Respond with only the category name (lowercase with underscores)."""
        )
        chain = prompt | llm
        response = chain.invoke({"email": email_body})
        return response.content.strip()

现在,我们需要创建一个状态,在 LangGraph 中,这一小部分非常重要。

把它想象成图的中枢神经系统。 这就是节点之间的通信方式,就像优等生在课堂上传递纸条一样。

文档中显示:

“状态是表示应用程序当前快照的共享数据结构。”

在实践中呢? 状态是在节点之间移动的结构化消息。 它将一个步骤的输出作为下一个步骤的输入。 基本上,它是将整个工作流粘合在一起的粘合剂。

因此,在构建图之前,我们必须先定义我们的状态结构。 本例中,我们的状态包括以下内容:

  • 用户请求(电子邮件正文)
  • 指定的优先级
  • 确定的主题(类别)

它简单明了,因此您可以像专业人士一样浏览图。

    from typing import TypedDict

    # Define the state structure
    class TicketState(TypedDict):
        email_body: str
        priority: str
        topic: str
        
    
    # Initialize state
    initial_state = TicketState(
        email_body=email_body,
        priority="",
        topic=""
    )

节点与 边缘:LangGraph 的关键组成部分

LangGraph 的基本要素包括节点边缘

  • 节点:它们是图中的操作单元,执行实际工作。 节点通常由可以执行任何逻辑(从计算到与语言模型 (LLM) 或外部集成交互)的 Python 代码组成。 从本质上讲,节点就像传统编程中的个别函数或智能体。
  • 边缘:边缘定义节点之间的执行流,决定接下来会发生什么。 它们充当连接器,允许状态根据预定义条件从一个节点转换到另一个节点。 在 LangGraph 中,边缘在协调节点之间的序列和决策流方面至关重要。

为了掌握边缘的功能,我们来看一个消息传递应用程序的简单类比:

  • 节点类似于积极参与对话的用户(或他们的设备)。
  • 边缘代表着用户之间能够促进沟通的聊天主题或连接。

当用户选择一个聊天主题来发送消息时,会有效地创建一个边缘,将他们与另一个用户连接在一起。 与 LangGraph 状态的结构化模式类似,每次交互(无论是发送文本、语音还是视频消息)都遵循预定义的顺序。 它确保了沿边缘传递的数据的一致性和可解释性。

不同于事件驱动型应用程序的动态特性,LangGraph 采用在整个执行过程中保持一致的静态模式。 它简化了节点之间的通信,使开发者可以依赖稳定的状态格式,从而确保无缝的边缘通信。

设计基本工作流

可以将 LangGraph 中的流工程理解为设计一个状态机。 在这个情境中,每个节点代表一个不同的状态或处理步骤,而边缘定义了这些状态之间的转换。 这种方式对想要在 AI 的确定性任务序列与动态决策能力之间取得平衡的开发者特别有用。 我们来使用前面定义的 TicketState 类初始化 StateGraph,开始构建流程。

    from langgraph.graph import StateGraph, START, END
    
    workflow = StateGraph(TicketState)

节点添加:节点是基本要素,用于执行划分工单优先级或识别其主题等特定任务。

每个节点函数均接收当前状态,执行其操作,并返回一个字典以更新状态:

   def classify_priority_node(state: TicketState) -> TicketState:
        """Node to classify ticket priority."""
        priority = classify_priority.invoke({"email_body": state["email_body"]})
        return {"priority": priority}

    def identify_topic_node(state: TicketState) -> TicketState:
        """Node to identify ticket topic."""
        topic = identify_topic.invoke({"email_body": state["email_body"]})
        return {"topic": topic}
        
        
    workflow.add_node("classify_priority", classify_priority_node)
    workflow.add_node("identify_topic", identify_topic_node)

classify_priority_node 和 identify_topic_node 方法将更改 TicketState 并发送参数输入。

边缘创建:定义连接节点的边缘:


    workflow.add_edge(START, "classify_priority")
    workflow.add_edge("classify_priority", "identify_topic")
    workflow.add_edge("identify_topic", END)

classify_priority 确定起点,而 identify_topic 确定到目前为止工作流的终点。

编译与执行:配置节点和边缘后,编译并执行该工作流。


    graph = workflow.compile()
    result = graph.invoke(initial_state)

太好了! 您还可以生成 LangGraph 流的可视化表示。

graph.get_graph().draw_mermaid_png(output_file_path="graph.png")

如果将代码运行到此点,您就会看到一个与下面类似的图:

first_graph.png

这幅图直观地显示了一次顺序执行:开始,然后划分优先级,接着确定主题,最后结束。

LangGraph 最强大的一个方面是它的灵活性,这让我们可以创建更复杂的流程和应用程序。 例如,我们可以修改工作流,使用以下行将 START 中的边缘添加到两个节点:

    workflow.add_edge(START, "classify_priority")
    workflow.add_edge(START, "identify_topic")

这一更改意味着智能体将同时执行 classify_priority 和 identify_topic。

LangGraph 中另一个非常有用的功能是能够使用条件边缘。 它们允许工作流根据对当前状态的评估进行分支,实现任务的动态路由。

我们来增强工作流。 我们将创建一个新工具,分析请求的内容、优先级和主题,以确定它是否为需要上报(例如,为人工团队提交工单)的高优先级问题。 如果不需要,将为用户生成一个自动响应。


    @tool
    def make_escalation_decision(email_body: str, priority: str, topic: str) -> str:
        """Decide whether to auto-respond or escalate to IT team."""
        prompt = ChatPromptTemplate.from_template(
            """Based on this IT support ticket, decide whether to:
            - "auto_respond": Send an automated response for simple/common or medium priority issues
            - "escalate": Escalate to the IT team for complex/urgent issues
            
            Email: {email}
            Priority: {priority}
            Topic: {topic}
            
            Consider: High priority items usually require escalation, while complex technical issues necessitate human review.
            
            Respond with only: auto_respond or escalate"""
        )
        chain = prompt | llm
        response = chain.invoke({
            "email": email_body,
            "priority": priority,
            "topic": topic
        })
        return response.content.strip()
        

此外,如果请求被确定为低优先级或中等优先级(导致“auto_respond”决策),我们将执行矢量搜索来检索历史回答。 然后,将使用此信息来生成适当的自动回答。 不过,这需要两个额外的工具:


    @tool
    def retrieve_examples(email_body: str) -> str:
        """Retrieve relevant examples from past responses based on email_body."""
        try:
            examples = iris.cls(__name__).Retrieve(email_body)
            return examples if examples else "No relevant examples found."
        except:
            return "No relevant examples found."

    @tool
    def generate_reply(email_body: str, topic: str, examples: str) -> str:
        """Generate a suggested reply based on the email, topic, and RAG examples."""
        prompt = ChatPromptTemplate.from_template(
            """Generate a professional IT support response based on:
            
            Original Email: {email}
            Topic Category: {topic}
            Example Response: {examples}
            
            Create a helpful, professional response that addresses the user's concern.
            Keep it concise and actionable."""
        )
        chain = prompt | llm
        response = chain.invoke({
            "email": email_body,
            "topic": topic,
            "examples": examples
        })
        return response.content.strip()

现在,我们为这些新工具定义相应的节点:

    
    def decision_node(state: TicketState) -> TicketState:
        """Node to decide on escalation or auto-response."""
        decision = make_escalation_decision.invoke({
            "email_body": state["email_body"],
            "priority": state["priority"],
            "topic": state["topic"]
        })
        return {"decision": decision}
        
    
    def rag_node(state: TicketState) -> TicketState:
        """Node to retrieve relevant examples using RAG."""
        examples = retrieve_examples.invoke({"email_body": state["email_body"]})
        return {"rag_examples": examples}

    def generate_reply_node(state: TicketState) -> TicketState:
        """Node to generate suggested reply."""
        reply = generate_reply.invoke({
            "email_body": state["email_body"],
            "topic": state["topic"],
            "examples": state["rag_examples"]
        })
        return {"suggested_reply": reply}
        
    
    def execute_action_node(state: TicketState) -> TicketState:
        """Node to execute final action based on decision."""
        if state["decision"] == "escalate":
            action = f"🚨 ESCALATED TO IT TEAM\nPriority: {state['priority']}\nTopic: {state['topic']}\nTicket created in system."
            print(f"[SYSTEM] Escalating ticket to IT team - Priority: {state['priority']}, Topic: {state['topic']}")
        else:
            action = f"✅ AUTO-RESPONSE SENT\nReply: {state['suggested_reply']}\nTicket logged for tracking."
            print(f"[SYSTEM] Auto-response sent to user - Topic: {state['topic']}")
        
        return {"final_action": action}
        
        
        
    workflow.add_node("make_decision", decision_node)
    workflow.add_node("rag", rag_node)
    workflow.add_node("generate_reply", generate_reply_node)
    workflow.add_node("execute_action", execute_action_node)

然后,条件边缘将使用 make_decision 节点的输出来定向流:

    workflow.add_conditional_edges(
        "make_decision",
        lambda x: x.get("decision"),
        {
            "auto_respond": "rag",
            "escalate": "execute_action"
        }
    )

如果 make_escalation_decision 工具(通过 decision_node)产生“auto_respond”,工作流将继续通过 RAG 节点(检索示例),然后是 generate_reply 节点(设计回答),最后是 execute_action 节点(记录 auto-response)。

相反,如果决策是“escalate”,流程将绕过 RAG 和生成步骤,直接转到 execute_action 来处理上报。 要添加剩余的标准边缘来完成图,请执行以下操作:

    workflow.add_edge("rag", "generate_reply")
    workflow.add_edge("generate_reply", "execute_action")
    workflow.add_edge("execute_action", END)

数据集注释:对于此项目,我们用于支持检索增强生成 (RAG) 的数据集来自 Hugging Face 上的 Customer Support Tickets 数据集。 对该数据集进行了筛选,以便只包含分类为技术支持并限制为英语的条目。 它确保 RAG 系统只为技术支持任务检索高度相关的特定领域的示例。

此时,我们的图应当与下图类似:

graph.png

当您使用一封电子邮件来执行此图,并导致高优先级分类和“escalate”决策时,您将看到以下响应:

image.png

同时,被分类为低优先级并导致“auto_respond”决策的请求将触发与下面类似的回复:

image.png

那么… 这一路都很顺利吗?

并不完全是。 有一些问题需要注意:

  • 数据隐私:小心敏感信息 — 这些智能体需要防护。
  • 计算成本:某些高级设置需要大量资源。
  • 幻觉:LLM 偶尔也会编造一些内容(不过仍然比大多数实习生聪明)。
  • 非确定性:相同的输入可能会返回不同的输出,这对创造力来说是好事,但对严格的流程来说却很棘手。

不过,大多数缺点都可以通过良好的规划、合适的工具和一点点思考加以控制。

LangGraph 将 AI 智能体从流行语变成实实在在的有效解决方案。 无论您是要自动执行客户支持,处理 IT 工单,还是构建自主应用程序,这个框架都让操作变得可行,甚至有趣。

您有任何问题或反馈吗? 请说出来。 AI 革命需要像您这样的建设者。

0
0 9
文章 Kelly Huang · 十月 23, 2025 15m read

img

在本节中,我们将探讨如何在 IRIS 中使用 Python 作为主要编程语言,在使用 Python 编写应用程序逻辑的同时仍能利用 IRIS 的强大功能。

使用方法 (irispython)

我们先来介绍官方操作方式,即使用 irispython 解释器。

您可以使用 irispython 解释器直接在 IRIS 中运行 Python 代码。 这样,您可以编写 Python 代码,并在 IRIS 应用程序的运行环境中执行相应代码。

什么是 irispython?

irispython 是位于 IRIS 安装目录 (<installation_directory>/bin/irispython) 下的 Python 解释器,用于在 IRIS 的运行环境中执行 Python 代码。

它的功能包括:

  • 设置 sys.path,以包含 IRIS Python 库和模块。
    • 此操作通过 <installation_directory>/lib/python/iris_site.py 中的 site.py 文件执行。
    • 如需了解详情,请参阅模块文章 Python 模块简介
  • 允许您导入 iris 模块,这是一个特殊模块,用于访问 IRIS 功能,例如实现任何 ObjectScript 类与 Python 的双向桥接。
  • 修复权限问题并动态加载 iris 内核库。

irispython 使用示例

您可以通过命令行运行 irispython 解释器:

<installation_directory>/bin/irispython

我们来运行一个简单的示例:

# src/python/article/irispython_example.py
import requests
import iris

def run():
    response = requests.get("https://2eb86668f7ab407989787c97ec6b24ba.api.mockbin.io/")

    my_dict = response.json()

    for key, value in my_dict.items():
        print(f"{key}: {value}")  # print message: Hello World

    return my_dict

if __name__ == "__main__":
    print(f"Iris version: {iris.cls('%SYSTEM.Version').GetVersion()}")
    run()

您可以使用 irispython解释器运行此脚本:

<installation_directory>/bin/irispython src/python/article/irispython_example.py

您将看到如下输出:

Iris version: IRIS for UNIX (Ubuntu Server LTS for x86-64 Containers) 2025.1 (Build 223U) Tue Mar 11 2025 18:23:31 EDT
message: Hello World

此例展示了如何使用 irispython 解释器在 IRIS 的运行环境中执行 Python 代码。

优点

  • Python 优先:您可以使用 Python 编写应用程序逻辑,这样,您可以利用 Python 的功能和库。
  • IRIS 集成:您可以轻松将 Python 代码与 IRIS 功能相集成。

缺点

  • 调试受限:在 irispython 中调试 Python 代码并不像在专用 Python 环境中那样简单直接。
    • 这并不是说无法进行调试,而是并不像在专用 Python 环境中那样简单。
    • 如需了解详情,请参阅补充部分
  • 虚拟环境:在 irispython 中为 Python 代码搭建虚拟环境比较困难。
    • 这并不是说无法搭建,只是操作起来比较困难。因为默认情况下,虚拟环境会查找名为 pythonpython3 的解释器,而 IRIS 中的情况并非如此。
    • 如需了解详情,请参阅补充部分

结论

总的来说,使用 irispython 解释器让您既可以利用 Python 编写应用程序逻辑,又能利用 IRIS 的强大功能。 不过,这种方式也存在调试和虚拟环境搭建方面的限制。

使用 WSGI

在本节中,我们将探讨如何使用 WSGI(Web 服务器网关接口)在 IRIS 中运行 Python Web 应用程序。

WSGI 是 Web 服务器与 Python Web 应用程序或框架之间的标准接口。 利用 WSGI,您可以在 Web 服务器环境中运行 Python Web 应用程序。

IRIS 支持 WSGI,这意味着您可以在 IRIS 中使用内置的 WSGI 服务器运行 Python Web 应用程序。

使用方法

要在 IRIS 中使用 WSGI,您需要创建 WSGI 应用程序,并向 IRIS Web 服务器注册此应用程序。

如需了解详情,请参阅官方文档

WSGI 使用示例

有关完整模板,请参见此处:iris-flask-example

优点

  • Python Web 框架:您可以使用流行的 Python Web 框架(如 Flask 或 Django)来构建 Web 应用程序。
  • IRIS 集成:您可以轻松将 Python Web 应用程序与 IRIS 功能相集成。

缺点

  • 复杂程度:构建 WSGI 应用程序会比直接在 Python Web 框架中使用 uvicorngunicorn 复杂一些。

结论

总的来说,在 IRIS 中使用 WSGI 让您既可以利用 Python 构建功能强大的 Web 应用程序,又能利用 IRIS 的功能。

DB-API

在本节中,我们将探讨如何使用 Python DB-API 与 IRIS 数据库进行交互。

Python DB-API 是 Python 中用于连接数据库的标准接口。 利用此接口,您可以执行 SQL 查询,并从数据库中检索结果。

使用方法

您可以使用 pip 进行安装:

pip install intersystems-irispython

随后,您可以使用 DB-API 连接 IRIS 数据库并执行 SQL 查询。

DB-API 使用示例

它的使用方法与其他所有 Python DB-API 相同,示例如下:

# src/python/article/dbapi_example.py
import iris

def run():
    # Connect to the IRIS database
# Open a connection to the server
    args = {
        'hostname':'127.0.0.1', 
        'port': 1972,
        'namespace':'USER', 
        'username':'SuperUser', 
        'password':'SYS'
    }
    conn = iris.connect(**args)

    # Create a cursor
    cursor = conn.cursor()

    # Execute a query
    cursor.execute("SELECT 1")

    # Fetch all results
    results = cursor.fetchall()

    for row in results:
        print(row)

    # Close the cursor and connection
    cursor.close()
    conn.close()
if __name__ == "__main__":
    run()

您可以使用任何 Python 解释器运行此脚本:

python3 /irisdev/app/src/python/article/dbapi_example.py

您将看到如下输出:

(1,)

优点

  • 标准接口:DB-API 提供用于连接数据库的标准接口,因此可以轻松切换不同的数据库。
  • SQL 查询:您可以使用 Python 执行 SQL 查询,并从数据库检索结果。
  • 远程访问:您可以使用 DB-API 连接到远程 IRIS 数据库。

缺点

  • 功能有限:DB-API 仅可通过 SQL 访问数据库,因此,您无法使用高级 IRIS 数据库功能,如执行 ObjectScript 或 Python 代码。

备选方案

还提供社区版 DB-API,参见此处:intersystems-irispython-community

该版本能更好地支持 SQLAlchemy、Django、langchain,以及其他使用 DB-API 的 Python 库。

如需了解详情,请参阅 补充部分

结论

总的来说,将 Python DB-API 与 IRIS 结合使用能够让您构建功能强大的应用程序,实现与数据库的无缝交互。

Notebook

现在,我们已了解如何在 IRIS 中使用 Python,接下来我们将探讨如何将 Jupyter Notebooks 与 IRIS 结合使用。

Jupyter Notebooks 是交互式编写和执行 Python 代码的绝佳方式,并且可与 IRIS 结合使用,以充分利用 IRIS 的功能。

使用方法

要在 IRIS 中使用 Jupyter Notebooks,您需要安装 notebookipykernel 这两个软件包:

pip install notebook ipykernel

然后,您可以创建新的 Jupyter Notebook 并选择 Python 3 内核。

Notebook 使用示例

您可以创建新的 Jupyter Notebook 并编写以下代码:

# src/python/article/my_notebook.ipynb
# Import the necessary modules
import iris
# Do the magic
iris.system.Version.GetVersion()

您可以使用 Jupyter Notebook 运行此 notebook:

jupyter notebook src/python/article/my_notebook.ipynb

优点

  • 交互式开发:利用 Jupyter Notebooks,您可以交互式编写和执行 Python 代码,非常适合数据分析和探索。
  • 丰富的输出:您可以直接在 Notebook 中显示丰富的输出,如图表和表格。
  • 文档:您可以在代码旁添加文档和说明。

缺点

  • 设置有难度:设置将 Jupyter Notebooks 与 IRIS 结合使用存在一定的难度,特别是对于内核配置而言。

结论

总的来说,将 Jupyter Notebooks 与 IRIS 结合使用可以交互式编写和执行 Python 代码,同时利用 IRIS 的功能。 不过,设置起来存在一定的难度,特别是对于内核配置而言。

补充部分

从本节开始,我们将探讨一些与在 IRIS 中使用 Python 相关的高级主题,例如远程调试 Python 代码、使用虚拟环境等。

以下大部分主题均未获得 InterSystems 的官方支持,但如果您要在 IRIS 中使用 Python,了解相关内容会提供很大的帮助。

使用原生解释器(无 irispython

在本节中,我们将探讨如何使用原生 Python 解释器代替 irispython 解释器。

这样一来,您可以直接使用虚拟环境,并使用您习惯的 Python 解释器。

使用方法

要使用原生 Python 解释器,您需要在机器本地安装 IRIS,并需要安装 iris-embedded-python-wrapper 软件包。

您可以使用 pip 进行安装:

pip install iris-embedded-python-wrapper

接下来,您需要设置一些环境变量指向 IRIS 安装目录:

export IRISINSTALLDIR=<installation_directory>
export IRISUSERNAME=<username>
export IRISPASSWORD=<password>
export IRISNAMESPACE=<namespace>

然后,您可以使用您的原生 Python 解释器运行 Python 代码:

python3 src/python/article/irispython_example.py
# src/python/article/irispython_example.py
import requests
import iris

def run():
    response = requests.get("https://2eb86668f7ab407989787c97ec6b24ba.api.mockbin.io/")

    my_dict = response.json()

    for key, value in my_dict.items():
        print(f"{key}: {value}")  # print message: Hello World

    return my_dict

if __name__ == "__main__":
    print(f"Iris version: {iris.cls('%SYSTEM.Version').GetVersion()}")
    run()

如需了解详情,请参阅 iris-embedded-python-wrapper 文档

优点

  • 虚拟环境:您可以将虚拟环境与原生 Python 解释器结合使用,从而可以更加轻松地管理依赖项。
  • 熟悉的工作流:您可以使用习惯的 Python 解释器,从而可以更轻松地与现有工作流相集成。
  • 调试:可以使用您喜欢的 Python 调试工具(如 pdbipdb)在 IRIS 中调试 Python 代码。

缺点

  • 设置的复杂程度:设置环境变量和 iris-embedded-python-wrapper 软件包可能会比较复杂,特别是对于初学者来说。
  • 未获官方支持:此方式未获 InterSystems 的官方支持,因此您可能遇到文档中未记录或不受支持的问题。

DB-API 社区版

在本节中,我们将探讨 GitHub 上提供的社区版 DB-API。

使用方法

您可以使用 pip 进行安装:

pip install sqlalchemy-iris

此代码将安装社区版 DB-API。

或使用特定版本:

pip install https://github.com/intersystems-community/intersystems-irispython/releases/download/3.9.3/intersystems_iris-3.9.3-py3-none-any.whl

然后,您可以使用 DB-API 连接 IRIS 数据库,并执行 SQL 查询或其他任何使用 DB-API 的 Python 代码,如 SQLAlchemy、Django、langchain、pandas 等。

DB-API 使用示例

它的使用方法与其他所有 Python DB-API 相同,示例如下:

# src/python/article/dbapi_community_example.py
import intersystems_iris.dbapi._DBAPI as dbapi

config = {
    "hostname": "localhost",
    "port": 1972,
    "namespace": "USER",
    "username": "_SYSTEM",
    "password": "SYS",
}

with dbapi.connect(**config) as conn:
    with conn.cursor() as cursor:
        cursor.execute("select ? as one, 2 as two", 1)   # second arg is parameter value
        for row in cursor:
            one, two = row
            print(f"one: {one}")
            print(f"two: {two}")

您可以使用任何 Python 解释器运行此脚本:

python3 /irisdev/app/src/python/article/dbapi_community_example.py

也可以使用 sqlalchemy:

from sqlalchemy import create_engine, text

COMMUNITY_DRIVER_URL = "iris://_SYSTEM:SYS@localhost:1972/USER"
OFFICIAL_DRIVER_URL = "iris+intersystems://_SYSTEM:SYS@localhost:1972/USER"
EMBEDDED_PYTHON_DRIVER_URL = "iris+emb:///USER"

def run(driver):
    # Create an engine using the official driver
    engine = create_engine(driver)

    with engine.connect() as connection:
        # Execute a query
        result = connection.execute(text("SELECT 1 AS one, 2 AS two"))

        for row in result:
            print(f"one: {row.one}, two: {row.two}")

if __name__ == "__main__":
    run(OFFICIAL_DRIVER_URL)
    run(COMMUNITY_DRIVER_URL)
    run(EMBEDDED_PYTHON_DRIVER_URL)

您可以使用任何 Python 解释器运行此脚本:

python3 /irisdev/app/src/python/article/dbapi_sqlalchemy_example.py

您将看到如下输出:

one: 1, two: 2
one: 1, two: 2
one: 1, two: 2

优点

  • 更好的支持:对 SQLAlchemy、Django、langchain 以及其他使用 DB-API 的 Python 库提供更好的支持。
  • 依托于社区:它由社区维护,这意味着随着时间的推移,可能会对其进行更新和改进。
  • 兼容性:它兼容官方 InterSystems DB-API,因此您可以在官方版与社区版之间轻松切换。

缺点

  • 速度:社区版的优化程度可能不如正式版高,某些场景下可能会导致速度变慢。

在 IRIS 中调试 Python 代码

在本节中,我们将探讨如何在 IRIS 中调试 Python 代码。

默认情况下,无法在 IRIS 中调试 Python 代码(在包含语言标签或 %SYS.Python 的 objectscript 中),但可以通过社区解决方案在 IRIS 中调试 Python 代码。

使用方法

先安装 IoP 基于 Python 的互操作性

pip install iris-pex-embedded-python
iop --init

此代码将安装 IoP 和新的 ObjectScript 类,以便您可以在 IRIS 中调试 Python 代码。

然后,您可以使用 IOP.Wrapper 类包装 Python 代码并实现调试。

Class Article.DebuggingExample Extends %RegisteredObject
{
ClassMethod Run() As %Status
{
    set myScript = ##class(IOP.Wrapper).Import("my_script", "/irisdev/app/src/python/article/", 55550) // Adjust the path to your module
    Do myScript.run()
    Quit $$$OK
}
}

然后,向 launch.json 文件添加以下配置,将 VsCode 配置为使用 IoP 调试器:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python in IRIS",
            "type": "python",
            "request": "attach",
            "port": 55550,
            "host": "localhost",
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/src/python/article",
                    "remoteRoot": "/irisdev/app/src/python/article"
                }
            ]
        }
    ]
}

现在,您可以运行用于导入 Python 模块的 ObjectScript 代码,然后将 VsCode 中的调试器关联到端口 55550

您可以使用以下命令运行此脚本:

iris session iris -U IRISAPP '##class(Article.DebuggingExample).Run()'

然后,您可以在 Python 代码中设置断点,调试器将在这些断点处停止执行,以便您检查变量并单步执行代码。

远程调试实际运作视频(针对 IoP,但原理是相同的):

Python 代码中还提供回溯信息,这对调试非常有用。

启用回溯时:

Traceback enabled

禁用回溯时:

Traceback disabled

优点

  • 远程调试:您可以远程调试在 IRIS 中运行的 Python 代码,在我看来,这是一项革命性的功能。
  • Python 调试功能:您可以使用所有 Python 调试功能,例如断点、变量检查和单步执行代码。
  • 回溯:您可以看到 Python 代码中错误的完整回溯信息,这对调试非常有用。

缺点

  • 设置的复杂程度:设置 IoP 和调试器可能会比较复杂,特别是对于初学者来说。
  • 社区解决方案:该解决方案属于社区解决方案,因此可能不像官方解决方案那样稳定,文档也可能不完善。

结论

总的来说,在 IRIS 中调试 Python 代码可以通过 IoP 社区解决方案来实现,借助该解决方案,您可以使用 Python 调试器调试在 IRIS 中运行的 Python 代码。 不过,此解决方案需要执行一些设置操作,并可能不像官方解决方案一样稳定。

IoP(基于 Python 的互操作性)

在本节中,我们将探讨 IoP(基于 Python 的互操作性)解决方案,利用该解决方案,您可以使用 Python 优先的方式在 IRIS 中运行 Python 代码。

我开发这个解决方案已经有一段时间了,可以说它是我的心血之作,该解决方案尝试解决或改善我们在本系列文章中提到的所有问题。

IoP 的要点:

  • Python 优先:您可以使用 Python 编写应用程序逻辑,这样,您可以利用 Python 的功能和库。
  • IRIS 集成:您可以轻松将 Python 代码与 IRIS 功能相集成。
  • 远程调试:您可以远程调试在 IRIS 中运行的 Python 代码。
  • 回溯:您可以看到 Python 代码中错误的完整回溯信息,这对调试非常有用。
  • 虚拟环境:支持虚拟环境功能,因此您可以更加轻松地管理依赖项。

要详细了解 IoP,您可以查阅官方文档

然后,您可以阅读以下文章详细了解 IoP:

🐍❤️如您所见,通过 IoP 这一功能强大的方法,我们可以将 Python 与 IRIS 相集成,从而可以更轻松地开发和调试应用程序。

您无需继续使用 irispython,也不必手动设置 sys.path,而是可以使用虚拟环境,并且可以调试在 IRIS 中运行的 Python 代码。

结论

希望大家喜欢这一系列关于在 IRIS 中使用 Python 的文章。

如果您对这一系列的文章有任何疑问或反馈,请随时联系我。

祝您在 IRIS 中使用 Python 时一切顺利!

0
0 18
文章 Lilian Huang · 九月 19, 2025 5m read

image

您知道当您拿到验血结果时一切看起来都像天书的那种感觉吗? 这就是 FHIRInsight 要解决的问题。 它最初的理念是,医疗数据不应该令人恐惧或困惑 – 它应该是我们所有人都能使用的东西。 验血是健康检查中十分常见的检查,但说实话,大多数人都很难理解它们,有时甚至对不擅长实验室工作的医务人员来说也是如此。 FHIRInsight 希望整个过程能够变得更简单,信息更富有实用价值。

FHIRInsight logo

🤖我们为什么要构建 FHIRInsight

这一切都始于一个简单而有力的问题:

“为什么验血结果仍然很难读懂 — 有时甚至对医生来说也是如此?”

如果您看过化验结果,您可能会看到一大堆数字、隐晦的缩写和“参考范围”,这些可能适用于您的年龄、性别或身体状况,也可能不适用。 毫无疑问,它是一种诊断工具,但如果没有背景信息,它就变成了一个猜谜游戏。 即使是经验丰富的医疗保健专业人员有时也需要交叉参考指导方针、研究论文或专家意见才能理解所有内容。

这正是 FHIRInsight 的用武之地。

我们不只是为患者而构建,也为一线医护人员而构建。 为轮流值班的医生,为捕捉生命体征细微变化的护士,为每一位试图在有限的时间和巨大的责任下做出正确决定的医护人员而构建。 我们的目标是让他们的工作简单一点,将密集的临床 FHIR 数据转化为清晰、有用、以真正的医学科学为基础的东西, 讲人类语言的东西。

FHIRInsight 不仅仅是解释化验结果。 它还:

  • 提供化验结果是轻度、中度还是重度的情境建议
  • 根据临床症状提出潜在病因和鉴别诊断
  • 提出下一步行动建议 — 是后续检查、转诊还是紧急护理
  • 利用 RAG(检索增强生成)拉取相关科学文章,为分析提供支持

想象一下,一位年轻的医生正在查看患者的贫血检查结果。 他们不需要在 Google 上搜索每一个异常值或翻阅医学期刊,而是收到一份报告,上面不仅总结了问题,还引用了最近的研究或世界卫生组织的指导方针来支持这一推理。 这就是将 AI针对精选研究的矢量搜索相结合的力量。

那患者呢?

他们再也不用盯着满屏的数字,猜想“胆红素 2.3 mg/dL”是什么意思,或者他们是否应该担心了。 他们会得到简单、周全的解释。 感觉更像是一场对话,而不是一份临床报告。 一些他们能真正理解的东西 — 并与他们的医生进行讨论,让人感觉更有准备,不那么焦虑。

因为这就是 FHIRInsight 的真正意义**:将复杂的医疗数据转化为清晰的见解**,帮助医疗保健专业人员和患者共同制定更好、更自信的决策

🔍 表象之下

当然,所有这些表面上的简单,背后可能由一些默默运行的强大技术提供支持。

以下是 FHIRInsight 的构建基础:

  • FHIR (Fast Healthcare Interoperability Resources) — 这是健康数据的全球标准。 它是我们接收化验结果、患者病史、受众特征和诊疗等结构化信息的方式。 FHIR 是医疗系统使用的语言,我们将这种语言翻译成人们可以真正使用的东西。
  • RAG(检索增强生成)的矢量搜索:FHIRInsight 通过在使用 InterSystems IRIS 原生矢量搜索的矢量数据库中建立科学 PDF 论文和可信 URL 索引,增强其诊断推理能力。 当化验结果看起来模棱两可或差别细微时,系统会检索相关内容来支持其建议,它不是从记忆库中进行检索,而是从真实的、最新的研究中进行检索。
  • 医学推理提示工程:我们对提示进行了微调,以指导 LLM 识别各种血液相关疾病。 无论是缺铁性贫血、凝血功能障碍、激素失衡还是自身免疫触发因素,提示都会引导 LLM 了解症状、检验室模式和可能病因的变化。
  • LiteLLM 集成:自定义适配器通过统一的接口将请求路由到多个 LLM 提供程序(OpenAI、Anthropic、Ollama 等),从而轻松实现回退、流式传输和模型切换。

无论您是查看 30 个患者图表的医生,还是想要理解数字含义的患者,都可以在几秒钟内将原始的化验数据转化为可解释、富有实用价值的医学见解

🧩 创建 LiteLLM 适配器:使用一个接口管理所有模型

在后台,FHIRInsight 的 AI 赋能报告由 LiteLLM 驱动,后者是一个出色的抽象层,可以使我们通过一个 OpenAI 风格的界面调用 100 多个 LLM(OpenAI、Claude、Gemini、Ollama 等)。

但是要想将 LiteLLM 集成到 InterSystems IRIS 中,需要比隐藏在业务操作中的 Python 脚本更持久、更能重复使用的东西。 所以,我们创建了自己的 LiteLLM 适配器

认识 LiteLLMAdapter

此适配器类可以处理您希望从一个强大的 LLM 集成中获得的所有东西:

  • 接受 promptmodeltemperature 等参数
  • 动态加载环境变量(例如,API 密钥)

为了将其嵌入我们的互操作性生产中,我们将其包装在一个专门的业务操作中:

  • 通过标准的 LLMModel 设置处理生产配置
  • 与 FHIRAnalyzer 组件集成,以实时生成报告
  • 作为未来任何需要访问 LLM 的组件的中心“AI 桥”

以下是简化的核心流程:

set response = ##class(dc.LLM.LiteLLMAdapter).CallLLM("Tell me about hemoglobin.", "openai/gpt-4o", 0.7)
write response

🧭 结语

当我们开始构建 FHIRInsight 时,我们的使命很简单**:让验血结果对每个人来说都更容易理解**。 不仅仅是患者,还有医生、护士、护理人员… 任何曾经盯着化验结果苦思冥想的人,“好吧,这到底是什么意思?”

我们都有过这样的经历。

通过融合 FHIR 的结构、InterSystems IRIS 的速度、LLM 的智能,以及通过矢量搜索实现真实医学研究的深度,我们创造了一个可以将令人困惑的数字转化成有意义的叙述的工具。 帮助人们对自己的健康做出更明智的决定,甚至可能及早发现一些被忽视的疾病。

但 FHIRInsight 不仅仅与数据相关。 它还与我们查看数据时的感受相关。 我们希望它给人一种清晰、支持和赋能的感觉。 我们希望这种体验… 有点像**“氛围编程”医疗保健** — 在智能的代码、优秀的设计和人类同理心方面达到最佳平衡点。

我们希望您能尝试它,打破它,质疑它,并帮助我们改进它。

告诉我们您接下来想看到什么。 更多条件? 更具可解释性? 更加个性化?

这只是一个开端 — 我们希望您能帮助塑造它的未来。

0
0 30
文章 Lilian Huang · 四月 16, 2025 7m read

Hi 大家好
在本文中,我讲介绍我的应用 iris-AgenticAI .

代理式人工智能的兴起标志着人工智能与世界互动方式的变革性飞跃--从静态响应转变为动态、目标驱动的问题解决方式。参看 OpenAI’s Agentic SDK ,  OpenAI Agents SDK使您能够在一个轻量级、易用且抽象程度极低的软件包中构建代理人工智能应用程序。它是我们之前的代理实验 Swarm 的生产就绪升级版。

该应用展示了下一代自主人工智能系统,这些系统能够进行推理、协作,并以类似人类的适应能力执行复杂任务。

应用功能

  • Agent Loop 🔄 一个内置循环,可自主管理工具的执行,将结果发回 LLM,并迭代直至任务完成。
  • Python-First 🐍 利用本地 Python 语法(装饰器、生成器等)来协调和连锁代理,而无需外部 DSL。
  • Handoffs 🤝 通过在专业代理之间委派任务,无缝协调多代理工作流程。
  • Function Tools ⚒️ 用 @tool 修饰任何 Python 函数,可立即将其集成到代理的工具包中。
  • Vector Search (RAG) 🧠 原生集成向量存储(IRIS),用于 RAG 检索。
  • Tracing 🔍 内置跟踪功能,可实时可视化、调试和监控代理工作流(想想 LangSmith 的替代方案)。
  • MCP Servers 🌐 通过 stdio 和 HTTP 支持模型上下文协议(MCP),实现跨进程代理通信。
  • Chainlit UI 🖥️ 集成 Chainlit 框架,可使用最少的代码构建交互式聊天界面。
  • Stateful Memory 🧠 跨会话保存聊天历史、上下文和代理状态,以实现连续性和长期任务。
0
0 118