Mergetober:用 cognee 和 Zendesk 建立能記住支援工單、忘記已刪工單的智能體
Mergetober: an agent that remembers your support tickets, and forgets the deleted ones, with cognee and Zendesk
作者為 cognee 建立 Zendesk 連接器,讓智能體根據團隊工單及 Help Center 文章回答問題,並在來源資料刪除後同步清除相關內容。連接器透過增量匯出及完整文章清單追蹤變更;一般同步錯誤會保留舊資料,避免誤刪。項目目前有 101 項測試。
Support teams answer the same questions again and again: "have we seen this error before?", "how did we fix the double charge last month?" The answers are in old tickets and Help Center articles, but nobody has time to dig through them.
For Mergetober I built a Zendesk connector for cognee, so an agent can answer from the team's own tickets and articles.
- Pull request: topoteretes/cognee-community#356
- Issue: topoteretes/cognee#4754
Setting it up
import cognee
from cognee_community_connector_zendesk import zendesk_source
await cognee.remember(
zendesk_source(subdomain="acme", oauth_token=token),
dataset_name="zendesk",
primary_key="id",
write_disposition="merge",
max_rows_per_table=0,
)
answers = await cognee.recall(
"What problems did customers report, and how were they resolved?",
datasets=["zendesk"],
)
The connector takes an email plus API token, as the issue asked, or an OAuth access token. That second option turned out to matter: Zendesk is retiring API tokens. Accounts created after 28 July 2026 can't create them (my trial couldn't), creation stops on 27 October 2026, and existing tokens stop working on 30 April 2027.
What cognee answered, before and after a delete
On a Zendesk trial with a few tickets and sample Help Center articles, with OpenAI as the LLM, I asked:
What problems did customers report, and how were they resolved?
Before:
cognee's answer named a duplicate October charge (refunded within five days) and a 500 error after a password reset.
Then I deleted ticket 3, the duplicate-charge ticket, in Zendesk:
After the next sync, the same question:
The answer only named the 500 error after a password reset (plus the return policy, from a Help Center article). The duplicate charge was gone, and the dataset went from 4 items to 3.
How it keeps up
- Tickets come from Zendesk's cursor-based incremental ticket export. The cursor lives in dlt state and is saved only after a successful load. Each ticket becomes one document with its whole comment thread, so a reply makes sense next to the question it answers.
-
Deleted tickets come back in that export with
status="deleted", so they become_deletedtombstones and cognee's orphan cleanup removes them. -
Articles have no delete feed. Each run lists all articles with cursor pagination, and an article that is missing from a complete listing, or turned back into a draft, is forgotten. To make sure a short or shifting listing never forgets anything by mistake, the listing is checked against the
countZendesk reports. - Internal notes and email addresses are off by default. An agent should not quote an internal note as if it were something the customer was told.
The live runs, through a real dlt merge:
1. first sync 3 tickets, 1 tombstone (a ticket deleted earlier)
2. published three articles 3 articles
3. replied on ticket 3, edited an article ticket 3 and that article only
4. deleted ticket 4, archived an article 1 deleted, 1 removed
5. internal note added to ticket 2 re-synced, the note stayed out of the document
Errors never delete
This was the theme of the review. Only a ticket marked deleted in the export, a ticket whose comments answer 404/410, or an article missing from a complete listing removes data. Everything else keeps the previous state:
- one ticket whose comments can't be read is set aside and retried on the next runs, while the rest of the page syncs;
- tickets and articles fail separately, so a broken Help Center doesn't stop ticket sync;
- three 5xx in a row stop the run cleanly, and a
Retry-Afterover 30 seconds isn't slept through; - a large account's first backfill saves its progress every 1,000 tickets, so an expiring OAuth token never throws the whole run away.
Checking my own work
Two bugs I found myself after opening the pull request:
-
An assignee who hadn't replied showed up as
user <id>. A requester or assignee who never commented isn't in the ticket's comment data, so the connector now looks them up withusers/show_many, and every ticket names them. - A ticket deleted and then restored between two syncs stayed forgotten. The export returned both versions, and the delete won. Now the newest version wins, so a restored ticket stays.
Before the review, I also went through the review points raised on other connectors in this batch, and the Calendar connector's port into cognee core, and fixed what applied to mine, each with a test that fails without the fix. That's most of why the test count went from a few dozen to 101.
What I learned
The connector has 101 tests now, most of them written after the review asked "what happens if…". Each fix has a test that fails without it. The biggest lesson: for a sync connector, the happy path is the easy part. The real work is making sure that every failure leaves memory exactly as it was.
The setup steps are in the README in the pull request, and examples/example.py is the script I used for this post.
來源:DEV Community · dev.to


