用 openJiuwen 构建 AI Agent:从 Hello World 到毒舌编辑器

前言:为什么选择 openJiuwen Agent-Core?

最近在探索 AI Agent 开发框架时,发现了 openJiuwen agent-core 。市面上 Agent 框架不少,但大多数要么过于复杂,要么缺少灵活性。openJiuwen 给我的感觉是:架构清晰、组件化设计、用起来很舒服

这篇文章记录我从零开始构建两个 Agent 的过程:一个是入门级的"Hello World",另一个是可以实际使用的"毒舌文档排版助理"。

OpenJiuwen项目地址:https://atomgit.com/openJiuwen?utm_source=csdn


第一部分:5 分钟上手第一个 Agent

理解核心概念

openJiuwen 的设计很简单:一切皆组件,组件即工作流

核心概念只有三个:

  • Workflow(工作流):处理流程的容器
  • Component(组件):处理单元(Start、LLM、End 等)
  • Agent(代理):对外提供服务的封装

数据流就像管道:

plain 复制代码
Start → LLM → End

安装 openJiuwen agent-core

bash 复制代码
pip install -U openjiuwen

第一个代码示例

下面是我写的第一个 WorkflowAgent:

python 复制代码
import os
import asyncio
from openjiuwen.core.component.start_comp import Start
from openjiuwen.core.component.end_comp import End
from openjiuwen.core.component.llm_comp import LLMComponent, LLMCompConfig
from openjiuwen.core.component.common.configs.model_config import ModelConfig
from openjiuwen.core.runner.runner import Runner
from openjiuwen.core.workflow.workflow_config import WorkflowConfig, WorkflowMetadata, WorkflowInputsSchema
from openjiuwen.core.workflow.base import Workflow
from openjiuwen.core.utils.llm.base import BaseModelInfo
from openjiuwen.agent.workflow_agent.workflow_agent import WorkflowAgent
from openjiuwen.agent.config.workflow_config import WorkflowAgentConfig
from openjiuwen.agent.common.schema import WorkflowSchema

# 配置大模型
os.environ.setdefault("API_BASE", "https://api.siliconflow.cn/v1/")
os.environ.setdefault("API_KEY", "你的API_KEY")
os.environ.setdefault("MODEL_PROVIDER", "openai")
os.environ.setdefault("MODEL_NAME", "Qwen/Qwen3-VL-8B-Instruct")

model_config = ModelConfig(
    model_provider=os.getenv("MODEL_PROVIDER"),
    model_info=BaseModelInfo(
        api_key=os.getenv("API_KEY"),
        api_base=os.getenv("API_BASE"),
        model=os.getenv("MODEL_NAME"),
    )
)

# 创建工作流配置
workflow_config = WorkflowConfig(
    metadata=WorkflowMetadata(
        id="generate_text_workflow",
        name="generate_text",
        version="1.0",
        description="根据用户输入生成文本"
    ),
    workflow_inputs_schema=WorkflowInputsSchema(
        type="object",
        properties={"query": {"type": "string"}},
        required=['query']
    )
)

# 初始化工作流
flow = Workflow(workflow_config=workflow_config)

# 创建组件
start = Start({"inputs": [{"id": "query", "type": "String", "required": "true"}]})
end = End({"responseTemplate": "工作流输出: {{output}}"})
llm_config = LLMCompConfig(
    model=model_config,
    template_content=[
        {"role": "system", "content": "你是一个AI助手,直接输出结果即可"},
        {"role": "user", "content": "{{query}}"}
    ],
    response_format={"type": "text"},
    output_config={"output": {"type": "string", "required": True}},
)
llm = LLMComponent(llm_config)

# 注册组件并连接
flow.set_start_comp("start", start, inputs_schema={"query": "${query}"})
flow.add_workflow_comp("llm", llm, inputs_schema={"query": "${start.query}"})
flow.set_end_comp("end", end, inputs_schema={"output": "${llm.output}"})
flow.add_connection("start", "llm")
flow.add_connection("llm", "end")

# 创建 Agent
schema = WorkflowSchema(
    id=flow.config().metadata.id,
    name=flow.config().metadata.name,
    version=flow.config().metadata.version,
    description="第一个工作流",
    inputs={"query": {"type": "string"}},
)
agent_config = WorkflowAgentConfig(
    id="hello_agent",
    version="0.1.0",
    description="第一个Agent",
    workflows=[schema],
)
workflow_agent = WorkflowAgent(agent_config)
workflow_agent.bind_workflows([flow])

# 运行
async def main():
    invoke_result = await Runner.run_agent(
        workflow_agent,
        {"query": "生成一则笑话,不要超过20个字"}
    )
    output_result = invoke_result.get("output").result
    print(f"结果: {output_result.get('responseContent')}")

asyncio.run(main())

代码结构解析

配置层:定义元数据和输入 Schema

python 复制代码
workflow_config = WorkflowConfig(
    metadata=WorkflowMetadata(...),
    workflow_inputs_schema=WorkflowInputsSchema(...)
)

组件层:创建处理单元

python 复制代码
start = Start(...)   # 接收输入
llm = LLMComponent(...)  # 调用大模型
end = End(...)       # 格式化输出

连接层:定义数据流向

python 复制代码
flow.set_start_comp("start", start, ...)
flow.add_workflow_comp("llm", llm, ...)
flow.set_end_comp("end", end, ...)
flow.add_connection("start", "llm")    # 起点到 LLM
flow.add_connection("llm", "end")      # LLM 到终点

封装层:绑定到 Agent

python 复制代码
workflow_agent = WorkflowAgent(agent_config)
workflow_agent.bind_workflows([flow])

运行层:调用执行

python 复制代码
await Runner.run_agent(workflow_agent, {"query": "..."})

结果:


第二部分:进阶实践------毒舌文档排版助理

需求背景

日常工作中有太多冗余文字:会议记录、啰嗦邮件、长篇报告。能不能做一个 Agent,自动提取核心要点,并给出"废话指数"点评?

功能需求

  1. 接收凌乱文字
  2. 提取 3 个核心要点
  3. 点评废话程度(幽默尖锐风格)
  4. 支持连续对话

核心设计

工作流逻辑

plain 复制代码
Start → LLM(毒舌编辑) → End

关键在于 System Prompt 的设计

python 复制代码
SASSY_EDITOR_SYSTEM_PROMPT = """
你是一个极简主义毒舌编辑,职责是将冗长文字压缩成3个核心要点,
并尖锐点评其废话程度。

## 输出格式要求:

### 1. 核心要点(仅3个Markdown列表项)
- 要点1:[核心信息1]
- 要点2:[核心信息2]
- 要点3:[核心信息3]

### 2. 废话指数点评
**废话等级:[X/10]**
[用幽默但尖锐的语言点评这段话的废话程度]

## 处理原则:
1. 直接输出,不要解释
2. 要点必须是具体信息
3. 点评要戳心,但保持幽默感
4. 必须恰好3个要点

现在开始处理用户输入。
"""

完整实现

python 复制代码
import os
import sys
import logging
import asyncio
from openjiuwen.core.component.start_comp import Start
from openjiuwen.core.component.end_comp import End
from openjiuwen.core.component.llm_comp import LLMComponent, LLMCompConfig
from openjiuwen.core.component.common.configs.model_config import ModelConfig
from openjiuwen.core.runner.runner import Runner
from openjiuwen.core.workflow.workflow_config import WorkflowConfig, WorkflowMetadata, WorkflowInputsSchema
from openjiuwen.core.workflow.base import Workflow
from openjiuwen.core.utils.llm.base import BaseModelInfo
from openjiuwen.agent.workflow_agent.workflow_agent import WorkflowAgent
from openjiuwen.agent.config.workflow_config import WorkflowAgentConfig
from openjiuwen.agent.common.schema import WorkflowSchema

# 日志重定向(保持控制台清爽)
log_file = os.path.join(os.path.dirname(__file__), "sassy_editor.log")

class TeeWriter:
    """同时写入文件和控制台,过滤框架日志"""
    def __init__(self, original, log_file_path):
        self.original = original
        self.log_file = open(log_file_path, 'a', encoding='utf-8')
        self.filter_patterns = [' | INFO | ', ' | DEBUG | ']

    def write(self, message):
        message_str = str(message)
        is_log = any(p in message_str for p in self.filter_patterns)

        if not is_log:
            self.original.write(message)  # 控制台:过滤日志
        if message.strip():
            self.log_file.write(message)   # 文件:全记录

    def flush(self):
        self.original.flush()
        self.log_file.flush()

sys.stdout = TeeWriter(sys.stdout, log_file)
sys.stderr = TeeWriter(sys.stderr, log_file)

# 大模型配置
os.environ.setdefault("WORKFLOW_EXECUTE_TIMEOUT", "120")

model_config = ModelConfig(
    model_provider="openai",
    model_info=BaseModelInfo(
        api_key="你的API_KEY",
        api_base="https://api.siliconflow.cn/v1/",
        model="Qwen/Qwen3-VL-8B-Instruct",
        timeout=120,
    )
)

# 工作流配置
workflow_config = WorkflowConfig(
    metadata=WorkflowMetadata(
        id="sassy_editor_workflow",
        name="sassy_editor",
        version="1.0",
        description="私人毒舌文档排版助理"
    ),
    workflow_inputs_schema=WorkflowInputsSchema(
        type="object",
        properties={
            "text": {"type": "string", "description": "待处理的凌乱文字"}
        },
        required=['text']
    )
)

flow = Workflow(workflow_config=workflow_config)

# 组件定义
start = Start({
    "inputs": [{"id": "text", "type": "String", "required": "true"}]
})

llm_config = LLMCompConfig(
    model=model_config,
    template_content=[
        {"role": "system", "content": SASSY_EDITOR_SYSTEM_PROMPT},
        {"role": "user", "content": "{{text}}"}
    ],
    response_format={"type": "text"},
    output_config={"output": {"type": "string", "required": True}},
)
llm = LLMComponent(llm_config)

end = End({"responseTemplate": "{{output}}"})

# 组件连接
flow.set_start_comp("start", start, inputs_schema={"text": "${text}"})
flow.add_workflow_comp("llm", llm, inputs_schema={"text": "${start.text}"})
flow.set_end_comp("end", end, inputs_schema={"output": "${llm.output}"})
flow.add_connection("start", "llm")
flow.add_connection("llm", "end")

# Agent 绑定
schema = WorkflowSchema(
    id=flow.config().metadata.id,
    name=flow.config().metadata.name,
    version=flow.config().metadata.version,
    description="私人毒舌文档排版助理",
    inputs={"text": {"type": "string"}},
)

agent_config = WorkflowAgentConfig(
    id="sassy_editor_agent",
    version="1.0.0",
    description="会议记录秒变日报",
    workflows=[schema],
)

sassy_agent = WorkflowAgent(agent_config)
sassy_agent.bind_workflows([flow])

# 交互式运行
async def main():
    print("=" * 60)
    print("毒舌文档排版助理已上线")
    print("输入 'quit' 或 'exit' 退出")
    print("=" * 60)

    while True:
        try:
            user_input = input("\n请输入待处理的文字:\n> ").strip()

            if user_input.lower() in ['quit', 'exit', 'q']:
                print("\n毒舌助理下线,再见!")
                break

            if not user_input:
                print("输入为空,请重新输入")
                continue

            invoke_result = await Runner.run_agent(sassy_agent, {"text": user_input})
            output_result = invoke_result.get("output").result

            print("\n" + "=" * 60)
            print("毒舌编辑处理结果:")
            print("=" * 60)
            print(output_result.get('responseContent'))
            print("=" * 60)

        except KeyboardInterrupt:
            print("\n\n毒舌助理下线!")
            break
        except Exception as e:
            print(f"\n处理失败:{e}")
            continue

if __name__ == "__main__":
    asyncio.run(main())

实际效果演示

输入(一段典型的会议记录):

plain 复制代码
今天下午我们开了一个非常重要的会议,讨论了下季度的产品规划。
会上大家进行了深入的交流和热烈的讨论,各个部门都发表了自己的看法。
产品部认为应该优先优化用户体验,技术部建议重构核心模块,
市场部强调要加强推广力度。最终我们达成了一致意见:
决定先做用户调研,再根据反馈决定优先级。
整个会议持续了3个小时,气氛非常融洽。

输出

plain 复制代码
============================================================
✨ 毒舌编辑处理结果:
============================================================
- 产品部主张用户体验优先  
- 技术部建议重构核心模块  
- 两方未达成共识,陷入"谁该先动"的扯皮  

**废话等级:6/10**  
"两个部门各说各的,像在会议室里打太极------一个说'用户要爽',一个说'系统要稳',最后观众席上的人比他们还累。"

总结:用 openJiuwen 构建 Agent 是什么体验?

一句话总结框架不阻碍思考,让开发者专注于业务逻辑本身。

从 Hello World 到毒舌编辑器,整个过程没有因为框架问题卡住。大部分时间花在:

  • 设计工作流逻辑
  • 调优 Prompt
  • 处理边界情况(超时、日志、错误处理)

框架本身提供了:

  • 清晰的组件抽象
  • 灵活的数据流定义
  • 稳定的运行环境

如果你也在找 Agent 开发框架,openJiuwen 值得一试。


OpenJiuwen官网:https://www.openjiuwen.com?utm_source=csdn

相关推荐
A012341234527 分钟前
认知?感知?觉知!升命学说之唯悟主义:AI时代人类精神的觉知觉醒
人工智能·唯物主义·明星的艺名都是谁起的·明星为什么要取艺名·明星起名字是随便起的吗·起名大师排名谁第一·明星都是怎么改名字的
B站计算机毕业设计超人29 分钟前
计算机毕业设计Python+Django考研院校推荐系统 考研分数线预测系统 大数据毕业设计 (代码+LW文档+PPT+讲解视频)
大数据·人工智能·hive·python·django·毕业设计·课程设计
好奇龙猫34 分钟前
工智能学习-AI入试相关题目练习-第十次
人工智能·学习
来两个炸鸡腿34 分钟前
【Datawhale组队学习202601】Base-NLP task05 高级微调技术
人工智能·学习·自然语言处理
组合缺一38 分钟前
Claude Code Agent Skills vs. Solon AI Skills:从工具增强到框架规范的深度对齐
java·人工智能·python·开源·solon·skills
小龙报43 分钟前
【SOLIDWORKS 练习题】草图专题:1.带座轴承
人工智能·嵌入式硬件·物联网·硬件架构·3d建模·硬件工程·精益工程
人工智能AI技术44 分钟前
【C#程序员入门AI】AI应用的操作系统:Semantic Kernel 2026实战
人工智能·c#
海天一色y1 小时前
基于Inception-V3实现CIFAR-100数据集的分类任务
人工智能·分类·数据挖掘
啊豪的思想1 小时前
算力为擎,算法为枢,数据为薪:人工智能三大核心要素的协同演进逻辑
网络·人工智能
SJLoveIT1 小时前
架构师视角:深度解构 Redis 底层数据结构的设计哲学
数据结构·数据库·redis